Skip to content

Commit

Permalink
ofproto-dpif: Ignore non-packet field masks during flow revalidation
Browse files Browse the repository at this point in the history
Commit bcd2633(ofproto-dpif: Store relevant fields for wildcarding
in facet) implements flow revalidation by comparing the newly looked
up flow mask with that of the existing facet.

The non-packet fields, such as register masks, are always cleared
by xlate_actions in the masks stored within facets, but they are not
cleared in the newly looked up flow masks, causing otherwise valid
flows to be declared as invalid flows and be removed from the datapath.

This patch provides a fix. I was able to verify the fix on a system set
up by Ying Chen where the bug can be reproduced.

Bug #21680
Reported by: Ying Chen <[email protected]>

Acked-by: Justin Pettit <[email protected]>
Signed-off-by: Andy Zhou <[email protected]>
  • Loading branch information
azhou-nicira committed Dec 11, 2013
1 parent 97e9555 commit eaae2be
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 2 deletions.
9 changes: 9 additions & 0 deletions lib/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,15 @@ flow_wildcards_init_exact(struct flow_wildcards *wc)
memset(wc->masks.zeros, 0, sizeof wc->masks.zeros);
}

/* Clear the metadata and register wildcard masks. They are not packet
* header fields. */
void
flow_wildcards_clear_non_packet_fields(struct flow_wildcards *wc)
{
memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
}

/* Returns true if 'wc' matches every packet, false if 'wc' fixes any bits or
* fields. */
bool
Expand Down
2 changes: 2 additions & 0 deletions lib/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ struct flow_wildcards {
void flow_wildcards_init_catchall(struct flow_wildcards *);
void flow_wildcards_init_exact(struct flow_wildcards *);

void flow_wildcards_clear_non_packet_fields(struct flow_wildcards *);

bool flow_wildcards_is_catchall(const struct flow_wildcards *);

void flow_wildcards_set_reg_mask(struct flow_wildcards *,
Expand Down
3 changes: 1 addition & 2 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -2692,8 +2692,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)

/* Clear the metadata and register wildcard masks, because we won't
* use non-header fields as part of the cache. */
memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
flow_wildcards_clear_non_packet_fields(wc);

out:
ovs_rwlock_unlock(&xlate_rwlock);
Expand Down
4 changes: 4 additions & 0 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -4287,6 +4287,10 @@ facet_revalidate(struct facet *facet)
xlate_in_init(&xin, ofproto, &facet->flow, new_rule, 0, NULL);
xlate_actions(&xin, &xout);
flow_wildcards_or(&xout.wc, &xout.wc, &wc);
/* Make sure non -packet fields are not masked. If not cleared,
* the memcmp() below may fail, causing an otherwise valid facet
* to be removed. */
flow_wildcards_clear_non_packet_fields(&xout.wc);

/* A facet's slow path reason should only change under dramatic
* circumstances. Rather than try to update everything, it's simpler to
Expand Down

0 comments on commit eaae2be

Please sign in to comment.