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>
memset(flow, 0, sizeof *flow);
if (tnl) {
memset(flow, 0, sizeof *flow);
if (tnl) {
+ assert(tnl != &flow->tunnel);
flow->tunnel = *tnl;
}
flow->in_port = ofp_in_port;
flow->tunnel = *tnl;
}
flow->in_port = ofp_in_port;
for (upcall = upcalls; upcall < &upcalls[n_upcalls]; upcall++) {
struct flow_miss *miss = &misses[n_misses];
struct flow_miss *existing_miss;
for (upcall = upcalls; upcall < &upcalls[n_upcalls]; upcall++) {
struct flow_miss *miss = &misses[n_misses];
struct flow_miss *existing_miss;
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,
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;
}
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);
/* Add other packets to a to-do list. */
hash = flow_hash(&miss->flow, 0);