flow: Only un-wildcard relevant IP headers.
authorJustin Pettit <jpettit@nicira.com>
Wed, 26 Jun 2013 23:37:16 +0000 (16:37 -0700)
committerJustin Pettit <jpettit@nicira.com>
Fri, 28 Jun 2013 02:51:46 +0000 (19:51 -0700)
When determining the fields to un-wildcard, we need to be careful
about only un-wildcarding fields that are relevant.  Also, we
didn't properly handle IPv6 addresses.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
lib/bond.c
lib/bundle.c
lib/flow.c
lib/flow.h
lib/multipath.c

index 68ac068..21922a0 100644 (file)
@@ -1375,12 +1375,12 @@ choose_output_slave(const struct bond *bond, const struct flow *flow,
             return NULL;
         }
         if (wc) {
-            flow_mask_hash_fields(wc, NX_HASH_FIELDS_SYMMETRIC_L4);
+            flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_SYMMETRIC_L4);
         }
         /* Fall Through. */
     case BM_SLB:
         if (wc) {
-            flow_mask_hash_fields(wc, NX_HASH_FIELDS_ETH_SRC);
+            flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_ETH_SRC);
         }
         e = lookup_bond_entry(bond, flow, vlan);
         if (!e->slave || !e->slave->enabled) {
index b3821e8..037f43e 100644 (file)
@@ -60,7 +60,7 @@ execute_hrw(const struct ofpact_bundle *bundle,
     int best, i;
 
     if (bundle->n_slaves > 1) {
-        flow_mask_hash_fields(wc, bundle->fields);
+        flow_mask_hash_fields(flow, wc, bundle->fields);
     }
 
     flow_hash = flow_hash_fields(flow, bundle->fields, bundle->basis);
index f8f8e5d..d6b9f69 100644 (file)
@@ -777,7 +777,8 @@ flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
 
 /* Masks the fields in 'wc' that are used by the flow hash 'fields'. */
 void
-flow_mask_hash_fields(struct flow_wildcards *wc, enum nx_hash_fields fields)
+flow_mask_hash_fields(const struct flow *flow, struct flow_wildcards *wc,
+                      enum nx_hash_fields fields)
 {
     switch (fields) {
     case NX_HASH_FIELDS_ETH_SRC:
@@ -787,11 +788,18 @@ flow_mask_hash_fields(struct flow_wildcards *wc, enum nx_hash_fields fields)
     case NX_HASH_FIELDS_SYMMETRIC_L4:
         memset(&wc->masks.dl_src, 0xff, sizeof wc->masks.dl_src);
         memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
-        memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
-        memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
-        memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
-        memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
-        memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
+        if (flow->dl_type == htons(ETH_TYPE_IP)) {
+            memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
+            memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
+        } else {
+            memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
+            memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
+        }
+        if (is_ip_any(flow)) {
+            memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
+            memset(&wc->masks.tp_src, 0xff, sizeof wc->masks.tp_src);
+            memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
+        }
         wc->masks.vlan_tci |= htons(VLAN_VID_MASK | VLAN_CFI);
         break;
 
index f4e930a..05c70bb 100644 (file)
@@ -205,7 +205,8 @@ bool flow_wildcards_equal(const struct flow_wildcards *,
                           const struct flow_wildcards *);
 uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis);
 
-void flow_mask_hash_fields(struct flow_wildcards *, enum nx_hash_fields);
+void flow_mask_hash_fields(const struct flow *, struct flow_wildcards *,
+                           enum nx_hash_fields);
 uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields,
                           uint16_t basis);
 const char *flow_hash_fields_to_str(enum nx_hash_fields);
index dbd5704..1be6964 100644 (file)
@@ -113,7 +113,7 @@ multipath_execute(const struct ofpact_multipath *mp, struct flow *flow,
     uint16_t link = multipath_algorithm(hash, mp->algorithm,
                                         mp->max_link + 1, mp->arg);
 
-    flow_mask_hash_fields(wc, mp->fields);
+    flow_mask_hash_fields(flow, wc, mp->fields);
     nxm_reg_load(&mp->dst, link, flow);
 }