2 * Copyright (c) 2009, 2010, 2011, 2012 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 "byte-order.h"
22 #include "dynamic-string.h"
26 VLOG_DEFINE_THIS_MODULE(match);
29 /* Converts the flow in 'flow' into a match in 'match', with the given
32 match_init(struct match *match,
33 const struct flow *flow, const struct flow_wildcards *wc)
37 match_zero_wildcarded_fields(match);
40 /* Converts a flow into a match. It sets the wildcard masks based on
41 * the packet contents. It will not set the mask for fields that do not
42 * make sense for the packet type. */
44 match_wc_init(struct match *match, const struct flow *flow)
46 struct flow_wildcards *wc;
51 memset(&wc->masks, 0x0, sizeof wc->masks);
53 memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
56 memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
59 for (i = 0; i < FLOW_N_REGS; i++) {
61 memset(&wc->masks.regs[i], 0xff, sizeof wc->masks.regs[i]);
65 if (flow->tunnel.ip_dst || flow->tunnel.tun_id) {
66 memset(&wc->masks.tunnel.tun_id, 0xff, sizeof wc->masks.tunnel.tun_id);
67 memset(&wc->masks.tunnel.ip_src, 0xff, sizeof wc->masks.tunnel.ip_src);
68 memset(&wc->masks.tunnel.ip_dst, 0xff, sizeof wc->masks.tunnel.ip_dst);
69 memset(&wc->masks.tunnel.flags, 0xff, sizeof wc->masks.tunnel.flags);
70 memset(&wc->masks.tunnel.ip_tos, 0xff, sizeof wc->masks.tunnel.ip_tos);
71 memset(&wc->masks.tunnel.ip_ttl, 0xff, sizeof wc->masks.tunnel.ip_ttl);
73 memset(&wc->masks.metadata, 0xff, sizeof wc->masks.metadata);
74 memset(&wc->masks.in_port, 0xff, sizeof wc->masks.in_port);
75 memset(&wc->masks.vlan_tci, 0xff, sizeof wc->masks.vlan_tci);
76 memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
77 memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
79 if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
80 memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
81 memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
82 memset(&wc->masks.ipv6_label, 0xff, sizeof wc->masks.ipv6_label);
83 } else if (flow->dl_type == htons(ETH_TYPE_IP) ||
84 (flow->dl_type == htons(ETH_TYPE_ARP))) {
85 memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
86 memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
89 if (flow->dl_type == htons(ETH_TYPE_ARP)) {
90 memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha);
91 memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha);
94 if (flow->dl_type == htons(ETH_TYPE_IPV6) ||
95 flow->dl_type == htons(ETH_TYPE_IP)) {
96 memset(&wc->masks.nw_tos, 0xff, sizeof wc->masks.nw_tos);
97 memset(&wc->masks.nw_ttl, 0xff, sizeof wc->masks.nw_ttl);
101 memset(&wc->masks.nw_frag, 0xff, sizeof wc->masks.nw_frag);
104 if (flow->nw_proto == IPPROTO_ICMP || flow->nw_proto == IPPROTO_ICMPV6 ||
105 (flow->tp_src || flow->tp_dst)) {
106 memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
107 memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
110 if (flow->nw_proto == IPPROTO_ICMPV6) {
111 memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha);
112 memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha);
118 /* Converts the flow in 'flow' into an exact-match match in 'match'. */
120 match_init_exact(struct match *match, const struct flow *flow)
122 ovs_be64 tun_id = flow->tunnel.tun_id;
125 match->flow.skb_priority = 0;
126 memset(&match->flow.tunnel, 0, sizeof match->flow.tunnel);
127 match->flow.tunnel.tun_id = tun_id;
128 flow_wildcards_init_exact(&match->wc);
131 /* Initializes 'match' as a "catch-all" match that matches every packet. */
133 match_init_catchall(struct match *match)
135 memset(&match->flow, 0, sizeof match->flow);
136 flow_wildcards_init_catchall(&match->wc);
139 /* For each bit or field wildcarded in 'match', sets the corresponding bit or
140 * field in 'flow' to all-0-bits. It is important to maintain this invariant
141 * in a match that might be inserted into a classifier.
143 * It is never necessary to call this function directly for a match that is
144 * initialized or modified only by match_*() functions. It is useful to
145 * restore the invariant in a match whose 'wc' member is modified by hand.
148 match_zero_wildcarded_fields(struct match *match)
150 flow_zero_wildcards(&match->flow, &match->wc);
154 match_set_reg(struct match *match, unsigned int reg_idx, uint32_t value)
156 match_set_reg_masked(match, reg_idx, value, UINT32_MAX);
160 match_set_reg_masked(struct match *match, unsigned int reg_idx,
161 uint32_t value, uint32_t mask)
163 assert(reg_idx < FLOW_N_REGS);
164 flow_wildcards_set_reg_mask(&match->wc, reg_idx, mask);
165 match->flow.regs[reg_idx] = value & mask;
169 match_set_metadata(struct match *match, ovs_be64 metadata)
171 match_set_metadata_masked(match, metadata, htonll(UINT64_MAX));
175 match_set_metadata_masked(struct match *match,
176 ovs_be64 metadata, ovs_be64 mask)
178 match->wc.masks.metadata = mask;
179 match->flow.metadata = metadata & mask;
183 match_set_tun_id(struct match *match, ovs_be64 tun_id)
185 match_set_tun_id_masked(match, tun_id, htonll(UINT64_MAX));
189 match_set_tun_id_masked(struct match *match, ovs_be64 tun_id, ovs_be64 mask)
191 match->wc.masks.tunnel.tun_id = mask;
192 match->flow.tunnel.tun_id = tun_id & mask;
196 match_set_in_port(struct match *match, uint16_t ofp_port)
198 match->wc.masks.in_port = UINT16_MAX;
199 match->flow.in_port = ofp_port;
203 match_set_dl_type(struct match *match, ovs_be16 dl_type)
205 match->wc.masks.dl_type = htons(UINT16_MAX);
206 match->flow.dl_type = dl_type;
209 /* Modifies 'value_src' so that the Ethernet address must match 'value_dst'
210 * exactly. 'mask_dst' is set to all 1s. */
212 set_eth(const uint8_t value_src[ETH_ADDR_LEN],
213 uint8_t value_dst[ETH_ADDR_LEN],
214 uint8_t mask_dst[ETH_ADDR_LEN])
216 memcpy(value_dst, value_src, ETH_ADDR_LEN);
217 memset(mask_dst, 0xff, ETH_ADDR_LEN);
220 /* Modifies 'value_src' so that the Ethernet address must match 'value_src'
221 * after each byte is ANDed with the appropriate byte in 'mask_src'.
222 * 'mask_dst' is set to 'mask_src' */
224 set_eth_masked(const uint8_t value_src[ETH_ADDR_LEN],
225 const uint8_t mask_src[ETH_ADDR_LEN],
226 uint8_t value_dst[ETH_ADDR_LEN],
227 uint8_t mask_dst[ETH_ADDR_LEN])
231 for (i = 0; i < ETH_ADDR_LEN; i++) {
232 value_dst[i] = value_src[i] & mask_src[i];
233 mask_dst[i] = mask_src[i];
237 /* Modifies 'rule' so that the source Ethernet address must match 'dl_src'
240 match_set_dl_src(struct match *match, const uint8_t dl_src[ETH_ADDR_LEN])
242 set_eth(dl_src, match->flow.dl_src, match->wc.masks.dl_src);
245 /* Modifies 'rule' so that the source Ethernet address must match 'dl_src'
246 * after each byte is ANDed with the appropriate byte in 'mask'. */
248 match_set_dl_src_masked(struct match *match,
249 const uint8_t dl_src[ETH_ADDR_LEN],
250 const uint8_t mask[ETH_ADDR_LEN])
252 set_eth_masked(dl_src, mask, match->flow.dl_src, match->wc.masks.dl_src);
255 /* Modifies 'match' so that the Ethernet address must match 'dl_dst'
258 match_set_dl_dst(struct match *match, const uint8_t dl_dst[ETH_ADDR_LEN])
260 set_eth(dl_dst, match->flow.dl_dst, match->wc.masks.dl_dst);
263 /* Modifies 'match' so that the Ethernet address must match 'dl_dst' after each
264 * byte is ANDed with the appropriate byte in 'mask'.
266 * This function will assert-fail if 'mask' is invalid. Only 'mask' values
267 * accepted by flow_wildcards_is_dl_dst_mask_valid() are allowed. */
269 match_set_dl_dst_masked(struct match *match,
270 const uint8_t dl_dst[ETH_ADDR_LEN],
271 const uint8_t mask[ETH_ADDR_LEN])
273 set_eth_masked(dl_dst, mask, match->flow.dl_dst, match->wc.masks.dl_dst);
277 match_set_dl_tci(struct match *match, ovs_be16 tci)
279 match_set_dl_tci_masked(match, tci, htons(0xffff));
283 match_set_dl_tci_masked(struct match *match, ovs_be16 tci, ovs_be16 mask)
285 match->flow.vlan_tci = tci & mask;
286 match->wc.masks.vlan_tci = mask;
289 /* Modifies 'match' so that the VLAN VID is wildcarded. If the PCP is already
290 * wildcarded, then 'match' will match a packet regardless of whether it has an
291 * 802.1Q header or not. */
293 match_set_any_vid(struct match *match)
295 if (match->wc.masks.vlan_tci & htons(VLAN_PCP_MASK)) {
296 match->wc.masks.vlan_tci &= ~htons(VLAN_VID_MASK);
297 match->flow.vlan_tci &= ~htons(VLAN_VID_MASK);
299 match_set_dl_tci_masked(match, htons(0), htons(0));
303 /* Modifies 'match' depending on 'dl_vlan':
305 * - If 'dl_vlan' is htons(OFP_VLAN_NONE), makes 'match' match only packets
306 * without an 802.1Q header.
308 * - Otherwise, makes 'match' match only packets with an 802.1Q header whose
309 * VID equals the low 12 bits of 'dl_vlan'.
312 match_set_dl_vlan(struct match *match, ovs_be16 dl_vlan)
314 flow_set_dl_vlan(&match->flow, dl_vlan);
315 if (dl_vlan == htons(OFP10_VLAN_NONE)) {
316 match->wc.masks.vlan_tci = htons(UINT16_MAX);
318 match->wc.masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
322 /* Sets the VLAN VID that 'match' matches to 'vid', which is interpreted as an
323 * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
326 match_set_vlan_vid(struct match *match, ovs_be16 vid)
328 match_set_vlan_vid_masked(match, vid, htons(VLAN_VID_MASK | VLAN_CFI));
332 /* Sets the VLAN VID that 'flow' matches to 'vid', which is interpreted as an
333 * OpenFlow 1.2 "vlan_vid" value, that is, the low 13 bits of 'vlan_tci' (VID
334 * plus CFI), with the corresponding 'mask'. */
336 match_set_vlan_vid_masked(struct match *match, ovs_be16 vid, ovs_be16 mask)
338 ovs_be16 pcp_mask = htons(VLAN_PCP_MASK);
339 ovs_be16 vid_mask = htons(VLAN_VID_MASK | VLAN_CFI);
342 flow_set_vlan_vid(&match->flow, vid & mask);
343 match->wc.masks.vlan_tci = mask | (match->wc.masks.vlan_tci & pcp_mask);
346 /* Modifies 'match' so that the VLAN PCP is wildcarded. If the VID is already
347 * wildcarded, then 'match' will match a packet regardless of whether it has an
348 * 802.1Q header or not. */
350 match_set_any_pcp(struct match *match)
352 if (match->wc.masks.vlan_tci & htons(VLAN_VID_MASK)) {
353 match->wc.masks.vlan_tci &= ~htons(VLAN_PCP_MASK);
354 match->flow.vlan_tci &= ~htons(VLAN_PCP_MASK);
356 match_set_dl_tci_masked(match, htons(0), htons(0));
360 /* Modifies 'match' so that it matches only packets with an 802.1Q header whose
361 * PCP equals the low 3 bits of 'dl_vlan_pcp'. */
363 match_set_dl_vlan_pcp(struct match *match, uint8_t dl_vlan_pcp)
365 flow_set_vlan_pcp(&match->flow, dl_vlan_pcp);
366 match->wc.masks.vlan_tci |= htons(VLAN_CFI | VLAN_PCP_MASK);
370 match_set_tp_src(struct match *match, ovs_be16 tp_src)
372 match_set_tp_src_masked(match, tp_src, htons(UINT16_MAX));
376 match_set_tp_src_masked(struct match *match, ovs_be16 port, ovs_be16 mask)
378 match->flow.tp_src = port & mask;
379 match->wc.masks.tp_src = mask;
383 match_set_tp_dst(struct match *match, ovs_be16 tp_dst)
385 match_set_tp_dst_masked(match, tp_dst, htons(UINT16_MAX));
389 match_set_tp_dst_masked(struct match *match, ovs_be16 port, ovs_be16 mask)
391 match->flow.tp_dst = port & mask;
392 match->wc.masks.tp_dst = mask;
396 match_set_nw_proto(struct match *match, uint8_t nw_proto)
398 match->flow.nw_proto = nw_proto;
399 match->wc.masks.nw_proto = UINT8_MAX;
403 match_set_nw_src(struct match *match, ovs_be32 nw_src)
405 match->flow.nw_src = nw_src;
406 match->wc.masks.nw_src = htonl(UINT32_MAX);
410 match_set_nw_src_masked(struct match *match,
411 ovs_be32 nw_src, ovs_be32 mask)
413 match->flow.nw_src = nw_src & mask;
414 match->wc.masks.nw_src = mask;
418 match_set_nw_dst(struct match *match, ovs_be32 nw_dst)
420 match->flow.nw_dst = nw_dst;
421 match->wc.masks.nw_dst = htonl(UINT32_MAX);
425 match_set_nw_dst_masked(struct match *match, ovs_be32 ip, ovs_be32 mask)
427 match->flow.nw_dst = ip & mask;
428 match->wc.masks.nw_dst = mask;
432 match_set_nw_dscp(struct match *match, uint8_t nw_dscp)
434 match->wc.masks.nw_tos |= IP_DSCP_MASK;
435 match->flow.nw_tos &= ~IP_DSCP_MASK;
436 match->flow.nw_tos |= nw_dscp & IP_DSCP_MASK;
440 match_set_nw_ecn(struct match *match, uint8_t nw_ecn)
442 match->wc.masks.nw_tos |= IP_ECN_MASK;
443 match->flow.nw_tos &= ~IP_ECN_MASK;
444 match->flow.nw_tos |= nw_ecn & IP_ECN_MASK;
448 match_set_nw_ttl(struct match *match, uint8_t nw_ttl)
450 match->wc.masks.nw_ttl = UINT8_MAX;
451 match->flow.nw_ttl = nw_ttl;
455 match_set_nw_frag(struct match *match, uint8_t nw_frag)
457 match->wc.masks.nw_frag |= FLOW_NW_FRAG_MASK;
458 match->flow.nw_frag = nw_frag;
462 match_set_nw_frag_masked(struct match *match,
463 uint8_t nw_frag, uint8_t mask)
465 match->flow.nw_frag = nw_frag & mask;
466 match->wc.masks.nw_frag = mask;
470 match_set_icmp_type(struct match *match, uint8_t icmp_type)
472 match_set_tp_src(match, htons(icmp_type));
476 match_set_icmp_code(struct match *match, uint8_t icmp_code)
478 match_set_tp_dst(match, htons(icmp_code));
482 match_set_arp_sha(struct match *match, const uint8_t sha[ETH_ADDR_LEN])
484 memcpy(match->flow.arp_sha, sha, ETH_ADDR_LEN);
485 memset(match->wc.masks.arp_sha, UINT8_MAX, ETH_ADDR_LEN);
489 match_set_arp_sha_masked(struct match *match,
490 const uint8_t arp_sha[ETH_ADDR_LEN],
491 const uint8_t mask[ETH_ADDR_LEN])
493 set_eth_masked(arp_sha, mask,
494 match->flow.arp_sha, match->wc.masks.arp_sha);
498 match_set_arp_tha(struct match *match, const uint8_t tha[ETH_ADDR_LEN])
500 memcpy(match->flow.arp_tha, tha, ETH_ADDR_LEN);
501 memset(match->wc.masks.arp_tha, UINT8_MAX, ETH_ADDR_LEN);
505 match_set_arp_tha_masked(struct match *match,
506 const uint8_t arp_tha[ETH_ADDR_LEN],
507 const uint8_t mask[ETH_ADDR_LEN])
509 set_eth_masked(arp_tha, mask,
510 match->flow.arp_tha, match->wc.masks.arp_tha);
514 match_set_ipv6_src(struct match *match, const struct in6_addr *src)
516 match->flow.ipv6_src = *src;
517 match->wc.masks.ipv6_src = in6addr_exact;
521 match_set_ipv6_src_masked(struct match *match, const struct in6_addr *src,
522 const struct in6_addr *mask)
524 match->flow.ipv6_src = ipv6_addr_bitand(src, mask);
525 match->wc.masks.ipv6_src = *mask;
529 match_set_ipv6_dst(struct match *match, const struct in6_addr *dst)
531 match->flow.ipv6_dst = *dst;
532 match->wc.masks.ipv6_dst = in6addr_exact;
536 match_set_ipv6_dst_masked(struct match *match, const struct in6_addr *dst,
537 const struct in6_addr *mask)
539 match->flow.ipv6_dst = ipv6_addr_bitand(dst, mask);
540 match->wc.masks.ipv6_dst = *mask;
544 match_set_ipv6_label(struct match *match, ovs_be32 ipv6_label)
546 match->wc.masks.ipv6_label = htonl(UINT32_MAX);
547 match->flow.ipv6_label = ipv6_label;
552 match_set_ipv6_label_masked(struct match *match, ovs_be32 ipv6_label,
555 match->flow.ipv6_label = ipv6_label & mask;
556 match->wc.masks.ipv6_label = mask;
560 match_set_nd_target(struct match *match, const struct in6_addr *target)
562 match->flow.nd_target = *target;
563 match->wc.masks.nd_target = in6addr_exact;
567 match_set_nd_target_masked(struct match *match,
568 const struct in6_addr *target,
569 const struct in6_addr *mask)
571 match->flow.nd_target = ipv6_addr_bitand(target, mask);
572 match->wc.masks.nd_target = *mask;
575 /* Returns true if 'a' and 'b' wildcard the same fields and have the same
576 * values for fixed fields, otherwise false. */
578 match_equal(const struct match *a, const struct match *b)
580 return (flow_wildcards_equal(&a->wc, &b->wc)
581 && flow_equal(&a->flow, &b->flow));
584 /* Returns a hash value for the flow and wildcards in 'match', starting from
587 match_hash(const struct match *match, uint32_t basis)
589 return flow_wildcards_hash(&match->wc, flow_hash(&match->flow, basis));
593 format_eth_masked(struct ds *s, const char *name, const uint8_t eth[6],
594 const uint8_t mask[6])
596 if (!eth_addr_is_zero(mask)) {
597 ds_put_format(s, "%s=", name);
598 eth_format_masked(eth, mask, s);
604 format_ip_netmask(struct ds *s, const char *name, ovs_be32 ip,
608 ds_put_format(s, "%s=", name);
609 ip_format_masked(ip, netmask, s);
615 format_ipv6_netmask(struct ds *s, const char *name,
616 const struct in6_addr *addr,
617 const struct in6_addr *netmask)
619 if (!ipv6_mask_is_any(netmask)) {
620 ds_put_format(s, "%s=", name);
621 print_ipv6_masked(s, addr, netmask);
628 format_be16_masked(struct ds *s, const char *name,
629 ovs_be16 value, ovs_be16 mask)
631 if (mask != htons(0)) {
632 ds_put_format(s, "%s=", name);
633 if (mask == htons(UINT16_MAX)) {
634 ds_put_format(s, "%"PRIu16, ntohs(value));
636 ds_put_format(s, "0x%"PRIx16"/0x%"PRIx16,
637 ntohs(value), ntohs(mask));
643 /* Appends a string representation of 'match' to 's'. If 'priority' is
644 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
646 match_format(const struct match *match, struct ds *s, unsigned int priority)
648 const struct flow_wildcards *wc = &match->wc;
649 size_t start_len = s->length;
650 const struct flow *f = &match->flow;
651 bool skip_type = false;
652 bool skip_proto = false;
656 BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
658 if (priority != OFP_DEFAULT_PRIORITY) {
659 ds_put_format(s, "priority=%u,", priority);
662 if (wc->masks.dl_type) {
664 if (f->dl_type == htons(ETH_TYPE_IP)) {
665 if (wc->masks.nw_proto) {
667 if (f->nw_proto == IPPROTO_ICMP) {
668 ds_put_cstr(s, "icmp,");
669 } else if (f->nw_proto == IPPROTO_TCP) {
670 ds_put_cstr(s, "tcp,");
671 } else if (f->nw_proto == IPPROTO_UDP) {
672 ds_put_cstr(s, "udp,");
674 ds_put_cstr(s, "ip,");
678 ds_put_cstr(s, "ip,");
680 } else if (f->dl_type == htons(ETH_TYPE_IPV6)) {
681 if (wc->masks.nw_proto) {
683 if (f->nw_proto == IPPROTO_ICMPV6) {
684 ds_put_cstr(s, "icmp6,");
685 } else if (f->nw_proto == IPPROTO_TCP) {
686 ds_put_cstr(s, "tcp6,");
687 } else if (f->nw_proto == IPPROTO_UDP) {
688 ds_put_cstr(s, "udp6,");
690 ds_put_cstr(s, "ipv6,");
694 ds_put_cstr(s, "ipv6,");
696 } else if (f->dl_type == htons(ETH_TYPE_ARP)) {
697 ds_put_cstr(s, "arp,");
702 for (i = 0; i < FLOW_N_REGS; i++) {
703 switch (wc->masks.regs[i]) {
707 ds_put_format(s, "reg%d=0x%"PRIx32",", i, f->regs[i]);
710 ds_put_format(s, "reg%d=0x%"PRIx32"/0x%"PRIx32",",
711 i, f->regs[i], wc->masks.regs[i]);
715 switch (wc->masks.tunnel.tun_id) {
718 case CONSTANT_HTONLL(UINT64_MAX):
719 ds_put_format(s, "tun_id=%#"PRIx64",", ntohll(f->tunnel.tun_id));
722 ds_put_format(s, "tun_id=%#"PRIx64"/%#"PRIx64",",
723 ntohll(f->tunnel.tun_id),
724 ntohll(wc->masks.tunnel.tun_id));
727 switch (wc->masks.metadata) {
730 case CONSTANT_HTONLL(UINT64_MAX):
731 ds_put_format(s, "metadata=%#"PRIx64",", ntohll(f->metadata));
734 ds_put_format(s, "metadata=%#"PRIx64"/%#"PRIx64",",
735 ntohll(f->metadata), ntohll(wc->masks.metadata));
738 if (wc->masks.in_port) {
739 ds_put_format(s, "in_port=%"PRIu16",", f->in_port);
741 if (wc->masks.vlan_tci) {
742 ovs_be16 vid_mask = wc->masks.vlan_tci & htons(VLAN_VID_MASK);
743 ovs_be16 pcp_mask = wc->masks.vlan_tci & htons(VLAN_PCP_MASK);
744 ovs_be16 cfi = wc->masks.vlan_tci & htons(VLAN_CFI);
746 if (cfi && f->vlan_tci & htons(VLAN_CFI)
747 && (!vid_mask || vid_mask == htons(VLAN_VID_MASK))
748 && (!pcp_mask || pcp_mask == htons(VLAN_PCP_MASK))
749 && (vid_mask || pcp_mask)) {
751 ds_put_format(s, "dl_vlan=%"PRIu16",",
752 vlan_tci_to_vid(f->vlan_tci));
755 ds_put_format(s, "dl_vlan_pcp=%d,",
756 vlan_tci_to_pcp(f->vlan_tci));
758 } else if (wc->masks.vlan_tci == htons(0xffff)) {
759 ds_put_format(s, "vlan_tci=0x%04"PRIx16",", ntohs(f->vlan_tci));
761 ds_put_format(s, "vlan_tci=0x%04"PRIx16"/0x%04"PRIx16",",
762 ntohs(f->vlan_tci), ntohs(wc->masks.vlan_tci));
765 format_eth_masked(s, "dl_src", f->dl_src, wc->masks.dl_src);
766 format_eth_masked(s, "dl_dst", f->dl_dst, wc->masks.dl_dst);
767 if (!skip_type && wc->masks.dl_type) {
768 ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type));
770 if (f->dl_type == htons(ETH_TYPE_IPV6)) {
771 format_ipv6_netmask(s, "ipv6_src", &f->ipv6_src, &wc->masks.ipv6_src);
772 format_ipv6_netmask(s, "ipv6_dst", &f->ipv6_dst, &wc->masks.ipv6_dst);
773 if (wc->masks.ipv6_label) {
774 if (wc->masks.ipv6_label == htonl(UINT32_MAX)) {
775 ds_put_format(s, "ipv6_label=0x%05"PRIx32",",
776 ntohl(f->ipv6_label));
778 ds_put_format(s, "ipv6_label=0x%05"PRIx32"/0x%05"PRIx32",",
779 ntohl(f->ipv6_label),
780 ntohl(wc->masks.ipv6_label));
784 format_ip_netmask(s, "nw_src", f->nw_src, wc->masks.nw_src);
785 format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst);
787 if (!skip_proto && wc->masks.nw_proto) {
788 if (f->dl_type == htons(ETH_TYPE_ARP)) {
789 ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
791 ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
794 if (f->dl_type == htons(ETH_TYPE_ARP)) {
795 format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha);
796 format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha);
798 if (wc->masks.nw_tos & IP_DSCP_MASK) {
799 ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos & IP_DSCP_MASK);
801 if (wc->masks.nw_tos & IP_ECN_MASK) {
802 ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK);
804 if (wc->masks.nw_ttl) {
805 ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl);
807 switch (wc->masks.nw_frag) {
808 case FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER:
809 ds_put_format(s, "nw_frag=%s,",
810 f->nw_frag & FLOW_NW_FRAG_ANY
811 ? (f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "first")
812 : (f->nw_frag & FLOW_NW_FRAG_LATER ? "<error>" : "no"));
815 case FLOW_NW_FRAG_ANY:
816 ds_put_format(s, "nw_frag=%s,",
817 f->nw_frag & FLOW_NW_FRAG_ANY ? "yes" : "no");
820 case FLOW_NW_FRAG_LATER:
821 ds_put_format(s, "nw_frag=%s,",
822 f->nw_frag & FLOW_NW_FRAG_LATER ? "later" : "not_later");
825 if (f->nw_proto == IPPROTO_ICMP) {
826 format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
827 format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
828 } else if (f->nw_proto == IPPROTO_ICMPV6) {
829 format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
830 format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
831 format_ipv6_netmask(s, "nd_target", &f->nd_target,
832 &wc->masks.nd_target);
833 format_eth_masked(s, "nd_sll", f->arp_sha, wc->masks.arp_sha);
834 format_eth_masked(s, "nd_tll", f->arp_tha, wc->masks.arp_tha);
836 format_be16_masked(s, "tp_src", f->tp_src, wc->masks.tp_src);
837 format_be16_masked(s, "tp_dst", f->tp_dst, wc->masks.tp_dst);
840 if (s->length > start_len && ds_last(s) == ',') {
845 /* Converts 'match' to a string and returns the string. If 'priority' is
846 * different from OFP_DEFAULT_PRIORITY, includes it in the string. The caller
847 * must free the string (with free()). */
849 match_to_string(const struct match *match, unsigned int priority)
851 struct ds s = DS_EMPTY_INITIALIZER;
852 match_format(match, &s, priority);
853 return ds_steal_cstr(&s);
857 match_print(const struct match *match)
859 char *s = match_to_string(match, OFP_DEFAULT_PRIORITY);
864 /* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst'
865 * with minimatch_destroy(). */
867 minimatch_init(struct minimatch *dst, const struct match *src)
869 miniflow_init(&dst->flow, &src->flow);
870 minimask_init(&dst->mask, &src->wc);
873 /* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst'
874 * with minimatch_destroy(). */
876 minimatch_clone(struct minimatch *dst, const struct minimatch *src)
878 miniflow_clone(&dst->flow, &src->flow);
879 minimask_clone(&dst->mask, &src->mask);
882 /* Frees any memory owned by 'match'. Does not free the storage in which
883 * 'match' itself resides; the caller is responsible for that. */
885 minimatch_destroy(struct minimatch *match)
887 miniflow_destroy(&match->flow);
888 minimask_destroy(&match->mask);
891 /* Initializes 'dst' as a copy of 'src'. */
893 minimatch_expand(const struct minimatch *src, struct match *dst)
895 miniflow_expand(&src->flow, &dst->flow);
896 minimask_expand(&src->mask, &dst->wc);
899 /* Returns true if 'a' and 'b' match the same packets, false otherwise. */
901 minimatch_equal(const struct minimatch *a, const struct minimatch *b)
903 return (miniflow_equal(&a->flow, &b->flow)
904 && minimask_equal(&a->mask, &b->mask));
907 /* Returns a hash value for 'match', given 'basis'. */
909 minimatch_hash(const struct minimatch *match, uint32_t basis)
911 return miniflow_hash(&match->flow, minimask_hash(&match->mask, basis));
914 /* Appends a string representation of 'match' to 's'. If 'priority' is
915 * different from OFP_DEFAULT_PRIORITY, includes it in 's'. */
917 minimatch_format(const struct minimatch *match, struct ds *s,
918 unsigned int priority)
920 struct match megamatch;
922 minimatch_expand(match, &megamatch);
923 match_format(&megamatch, s, priority);
926 /* Converts 'match' to a string and returns the string. If 'priority' is
927 * different from OFP_DEFAULT_PRIORITY, includes it in the string. The caller
928 * must free the string (with free()). */
930 minimatch_to_string(const struct minimatch *match, unsigned int priority)
932 struct match megamatch;
934 minimatch_expand(match, &megamatch);
935 return match_to_string(&megamatch, priority);