X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fflow.c;h=6b78ae36f2d753b0b7283ed44b3dfc67185ac842;hb=f137ed099e3feaa4a9d8c5dc5f5234945451795e;hp=916d41c54b44b21b51939bd6380221c4c994f828;hpb=8b3b8dd1a5a1a8ba3b7e62798ff70cb8f9fc7659;p=openvswitch diff --git a/lib/flow.c b/lib/flow.c index 916d41c5..6b78ae36 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -445,6 +445,66 @@ flow_extract_stats(const struct flow *flow, struct ofpbuf *packet, stats->n_packets = 1; } +/* For every bit of a field that is wildcarded in 'wildcards', sets the + * corresponding bit in 'flow' to zero. */ +void +flow_zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards) +{ + const flow_wildcards_t wc = wildcards->wildcards; + int i; + + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1); + + for (i = 0; i < FLOW_N_REGS; i++) { + flow->regs[i] &= wildcards->reg_masks[i]; + } + flow->tun_id &= wildcards->tun_id_mask; + flow->nw_src &= wildcards->nw_src_mask; + flow->nw_dst &= wildcards->nw_dst_mask; + if (wc & FWW_IN_PORT) { + flow->in_port = 0; + } + flow->vlan_tci &= wildcards->vlan_tci_mask; + if (wc & FWW_DL_TYPE) { + flow->dl_type = 0; + } + if (wc & FWW_TP_SRC) { + flow->tp_src = 0; + } + if (wc & FWW_TP_DST) { + flow->tp_dst = 0; + } + if (wc & FWW_DL_SRC) { + memset(flow->dl_src, 0, sizeof flow->dl_src); + } + if (wc & FWW_DL_DST) { + flow->dl_dst[0] &= 0x01; + memset(&flow->dl_dst[1], 0, 5); + } + if (wc & FWW_ETH_MCAST) { + flow->dl_dst[0] &= 0xfe; + } + if (wc & FWW_NW_PROTO) { + flow->nw_proto = 0; + } + if (wc & FWW_NW_TOS) { + flow->nw_tos = 0; + } + if (wc & FWW_ARP_SHA) { + memset(flow->arp_sha, 0, sizeof flow->arp_sha); + } + if (wc & FWW_ARP_THA) { + memset(flow->arp_tha, 0, sizeof flow->arp_tha); + } + flow->ipv6_src = ipv6_addr_bitand(&flow->ipv6_src, + &wildcards->ipv6_src_mask); + flow->ipv6_dst = ipv6_addr_bitand(&flow->ipv6_dst, + &wildcards->ipv6_dst_mask); + if (wc & FWW_ND_TARGET) { + memset(&flow->nd_target, 0, sizeof flow->nd_target); + } +} + char * flow_to_string(const struct flow *flow) { @@ -546,6 +606,8 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc) { int i; + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1); + if (wc->wildcards || wc->tun_id_mask != htonll(UINT64_MAX) || wc->nw_src_mask != htonl(UINT32_MAX) @@ -565,6 +627,34 @@ flow_wildcards_is_exact(const struct flow_wildcards *wc) return true; } +/* Returns true if 'wc' matches every packet, false if 'wc' fixes any bits or + * fields. */ +bool +flow_wildcards_is_catchall(const struct flow_wildcards *wc) +{ + int i; + + BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1); + + if (wc->wildcards != FWW_ALL + || wc->tun_id_mask != htonll(0) + || wc->nw_src_mask != htonl(0) + || wc->nw_dst_mask != htonl(0) + || wc->vlan_tci_mask != htons(0) + || !ipv6_mask_is_any(&wc->ipv6_src_mask) + || !ipv6_mask_is_any(&wc->ipv6_dst_mask)) { + return false; + } + + for (i = 0; i < FLOW_N_REGS; i++) { + if (wc->reg_masks[i] != 0) { + return false; + } + } + + return true; +} + /* Initializes 'dst' as the combination of wildcards in 'src1' and 'src2'. * That is, a bit or a field is wildcarded in 'dst' if it is wildcarded in * 'src1' or 'src2' or both. */