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 93bd9b25bd13cfda63acf847922ea482e2cb040e..76d234057957ec6346143a7f92f269b5bdf5d83a 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 ff6df41ff0088dad3995fe3acef37622632b788a..6e50885f4c44df278d12d0229ba1f2261664264c 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);