flow: Ensure that padding is always zeroed.
[sliver-openvswitch.git] / lib / classifier.c
index 79ba657..d5e383f 100644 (file)
@@ -149,14 +149,14 @@ cls_rule_set_tun_id_masked(struct cls_rule *rule,
 void
 cls_rule_set_in_port(struct cls_rule *rule, uint16_t ofp_port)
 {
-    rule->wc.wildcards &= ~FWW_IN_PORT;
+    rule->wc.in_port_mask = UINT16_MAX;
     rule->flow.in_port = ofp_port;
 }
 
 void
 cls_rule_set_dl_type(struct cls_rule *rule, ovs_be16 dl_type)
 {
-    rule->wc.wildcards &= ~FWW_DL_TYPE;
+    rule->wc.dl_type_mask = htons(UINT16_MAX);
     rule->flow.dl_type = dl_type;
 }
 
@@ -351,8 +351,8 @@ cls_rule_set_tp_dst_masked(struct cls_rule *rule, ovs_be16 port, ovs_be16 mask)
 void
 cls_rule_set_nw_proto(struct cls_rule *rule, uint8_t nw_proto)
 {
-    rule->wc.wildcards &= ~FWW_NW_PROTO;
     rule->flow.nw_proto = nw_proto;
+    rule->wc.nw_proto_mask = UINT8_MAX;
 }
 
 void
@@ -403,7 +403,7 @@ cls_rule_set_nw_ecn(struct cls_rule *rule, uint8_t nw_ecn)
 void
 cls_rule_set_nw_ttl(struct cls_rule *rule, uint8_t nw_ttl)
 {
-    rule->wc.wildcards &= ~FWW_NW_TTL;
+    rule->wc.nw_ttl_mask = UINT8_MAX;
     rule->flow.nw_ttl = nw_ttl;
 }
 
@@ -600,23 +600,22 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
 {
     const struct flow_wildcards *wc = &rule->wc;
     size_t start_len = s->length;
-    flow_wildcards_t w = wc->wildcards;
     const struct flow *f = &rule->flow;
     bool skip_type = false;
     bool skip_proto = false;
 
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 14);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
 
     if (rule->priority != OFP_DEFAULT_PRIORITY) {
         ds_put_format(s, "priority=%d,", rule->priority);
     }
 
-    if (!(w & FWW_DL_TYPE)) {
+    if (wc->dl_type_mask) {
         skip_type = true;
         if (f->dl_type == htons(ETH_TYPE_IP)) {
-            if (!(w & FWW_NW_PROTO)) {
+            if (wc->nw_proto_mask) {
                 skip_proto = true;
                 if (f->nw_proto == IPPROTO_ICMP) {
                     ds_put_cstr(s, "icmp,");
@@ -632,7 +631,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
                 ds_put_cstr(s, "ip,");
             }
         } else if (f->dl_type == htons(ETH_TYPE_IPV6)) {
-            if (!(w & FWW_NW_PROTO)) {
+            if (wc->nw_proto_mask) {
                 skip_proto = true;
                 if (f->nw_proto == IPPROTO_ICMPV6) {
                     ds_put_cstr(s, "icmp6,");
@@ -688,7 +687,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
                       ntohll(f->metadata), ntohll(wc->metadata_mask));
         break;
     }
-    if (!(w & FWW_IN_PORT)) {
+    if (wc->in_port_mask) {
         ds_put_format(s, "in_port=%"PRIu16",", f->in_port);
     }
     if (wc->vlan_tci_mask) {
@@ -717,7 +716,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
     }
     format_eth_masked(s, "dl_src", f->dl_src, wc->dl_src_mask);
     format_eth_masked(s, "dl_dst", f->dl_dst, wc->dl_dst_mask);
-    if (!skip_type && !(w & FWW_DL_TYPE)) {
+    if (!skip_type && wc->dl_type_mask) {
         ds_put_format(s, "dl_type=0x%04"PRIx16",", ntohs(f->dl_type));
     }
     if (f->dl_type == htons(ETH_TYPE_IPV6)) {
@@ -737,7 +736,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
         format_ip_netmask(s, "nw_src", f->nw_src, wc->nw_src_mask);
         format_ip_netmask(s, "nw_dst", f->nw_dst, wc->nw_dst_mask);
     }
-    if (!skip_proto && !(w & FWW_NW_PROTO)) {
+    if (!skip_proto && wc->nw_proto_mask) {
         if (f->dl_type == htons(ETH_TYPE_ARP)) {
             ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
         } else {
@@ -754,7 +753,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
     if (wc->nw_tos_mask & IP_ECN_MASK) {
         ds_put_format(s, "nw_ecn=%"PRIu8",", f->nw_tos & IP_ECN_MASK);
     }
-    if (!(w & FWW_NW_TTL)) {
+    if (wc->nw_ttl_mask) {
         ds_put_format(s, "nw_ttl=%"PRIu8",", f->nw_ttl);
     }
     switch (wc->nw_frag_mask) {
@@ -1288,10 +1287,9 @@ static bool
 flow_equal_except(const struct flow *a, const struct flow *b,
                   const struct flow_wildcards *wildcards)
 {
-    const flow_wildcards_t wc = wildcards->wildcards;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 14);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
 
     for (i = 0; i < FLOW_N_REGS; i++) {
         if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
@@ -1303,17 +1301,17 @@ flow_equal_except(const struct flow *a, const struct flow *b,
             && !((a->metadata ^ b->metadata) & wildcards->metadata_mask)
             && !((a->nw_src ^ b->nw_src) & wildcards->nw_src_mask)
             && !((a->nw_dst ^ b->nw_dst) & wildcards->nw_dst_mask)
-            && (wc & FWW_IN_PORT || a->in_port == b->in_port)
+            && !((a->in_port ^ b->in_port) & wildcards->in_port_mask)
             && !((a->vlan_tci ^ b->vlan_tci) & wildcards->vlan_tci_mask)
-            && (wc & FWW_DL_TYPE || a->dl_type == b->dl_type)
+            && !((a->dl_type ^ b->dl_type) & wildcards->dl_type_mask)
             && !((a->tp_src ^ b->tp_src) & wildcards->tp_src_mask)
             && !((a->tp_dst ^ b->tp_dst) & wildcards->tp_dst_mask)
             && eth_addr_equal_except(a->dl_src, b->dl_src,
                                      wildcards->dl_src_mask)
             && eth_addr_equal_except(a->dl_dst, b->dl_dst,
                                      wildcards->dl_dst_mask)
-            && (wc & FWW_NW_PROTO || a->nw_proto == b->nw_proto)
-            && (wc & FWW_NW_TTL || a->nw_ttl == b->nw_ttl)
+            && !((a->nw_proto ^ b->nw_proto) & wildcards->nw_proto_mask)
+            && !((a->nw_ttl ^ b->nw_ttl) & wildcards->nw_ttl_mask)
             && !((a->nw_tos ^ b->nw_tos) & wildcards->nw_tos_mask)
             && !((a->nw_frag ^ b->nw_frag) & wildcards->nw_frag_mask)
             && eth_addr_equal_except(a->arp_sha, b->arp_sha,