ofproto-dpif: Avoid zeroing tunnel info in handle_miss_upcalls().
authorBen Pfaff <blp@nicira.com>
Thu, 4 Oct 2012 22:11:39 +0000 (15:11 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 4 Oct 2012 23:57:54 +0000 (16:57 -0700)
Commit 296e07ace0f (flow: Extend struct flow to contain tunnel outer
header.) changed the tunnel ID parameter of flow_extract() from an integer
passed by value to a structure passed by pointer.  Before flow_extract()
reads the tunnel ID, it zeros the entire flow parameter.  This means that,
if a caller passes the address of the tunnel member of the flow as the
tunnel ID, then flow_extract() zeros the tunnel data before it reads and
copies the tunnel data (that it just zeroed).  The result is that the
tunnel data is ignored.

This commit fixes the problem by making the caller that did this use a
separate flow structure instead of trying to be clever.

Bug #13461.
CC: Pankaj Thakkar <thakkar@nicira.com>
Reported-by: Michael Hu <mhu@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/flow.c
ofproto/ofproto-dpif.c

index 93bd9b2..76d2340 100644 (file)
@@ -346,6 +346,7 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
     memset(flow, 0, sizeof *flow);
 
     if (tnl) {
+        assert(tnl != &flow->tunnel);
         flow->tunnel = *tnl;
     }
     flow->in_port = ofp_in_port;
index ff6df41..6e50885 100644 (file)
@@ -3106,18 +3106,19 @@ handle_miss_upcalls(struct ofproto_dpif *ofproto, struct dpif_upcall *upcalls,
     for (upcall = upcalls; upcall < &upcalls[n_upcalls]; upcall++) {
         struct flow_miss *miss = &misses[n_misses];
         struct flow_miss *existing_miss;
+        struct flow flow;
         uint32_t hash;
 
         /* Obtain metadata and check userspace/kernel agreement on flow match,
          * then set 'flow''s header pointers. */
         miss->key_fitness = ofproto_dpif_extract_flow_key(
             ofproto, upcall->key, upcall->key_len,
-            &miss->flow, &miss->initial_tci, upcall->packet);
+            &flow, &miss->initial_tci, upcall->packet);
         if (miss->key_fitness == ODP_FIT_ERROR) {
             continue;
         }
-        flow_extract(upcall->packet, miss->flow.skb_priority,
-                     &miss->flow.tunnel, miss->flow.in_port, &miss->flow);
+        flow_extract(upcall->packet, flow.skb_priority,
+                     &flow.tunnel, flow.in_port, &miss->flow);
 
         /* Add other packets to a to-do list. */
         hash = flow_hash(&miss->flow, 0);