From: Ben Pfaff Date: Thu, 4 Oct 2012 22:11:39 +0000 (-0700) Subject: ofproto-dpif: Avoid zeroing tunnel info in handle_miss_upcalls(). X-Git-Tag: sliver-openvswitch-1.9.90-1~3^2~72 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=1d446463ea3707ee609ea45f0cd2714aa7f5bfc6 ofproto-dpif: Avoid zeroing tunnel info in handle_miss_upcalls(). 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 Reported-by: Michael Hu Signed-off-by: Ben Pfaff --- diff --git a/lib/flow.c b/lib/flow.c index 93bd9b25b..76d234057 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -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; diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index ff6df41ff..6e50885f4 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -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);