From 97a4b006b64955a81874e874e8c7848ff73d61e4 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Wed, 9 Apr 2014 11:13:57 -0700 Subject: [PATCH 1/1] ofproto/xlate: Fix set field unwildcarding. If the field does not exist, nothing is set. However, we must unwildcard the bits we used to make the decision, and we need not unwildcard the field and it's prerequisities, if nothing is set. Signed-off-by: Jarno Rajahalme Acked-by: Ben Pfaff --- ofproto/ofproto-dpif-xlate.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index ad60b07e2..55c21e006 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2752,15 +2752,22 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_SET_FIELD: set_field = ofpact_get_SET_FIELD(a); mf = set_field->field; - mf_mask_field_and_prereqs(mf, &wc->masks); /* Set field action only ever overwrites packet's outermost * applicable header fields. Do nothing if no header exists. */ - if ((mf->id != MFF_VLAN_VID || flow->vlan_tci & htons(VLAN_CFI)) - && ((mf->id != MFF_MPLS_LABEL && mf->id != MFF_MPLS_TC) - || eth_type_mpls(flow->dl_type))) { - mf_set_flow_value(mf, &set_field->value, flow); + if (mf->id == MFF_VLAN_VID) { + wc->masks.vlan_tci |= htons(VLAN_CFI); + if (!(flow->vlan_tci & htons(VLAN_CFI))) { + break; + } + } else if ((mf->id == MFF_MPLS_LABEL || mf->id == MFF_MPLS_TC) + /* 'dl_type' is already unwildcarded. */ + && !eth_type_mpls(flow->dl_type)) { + break; } + + mf_mask_field_and_prereqs(mf, &wc->masks); + mf_set_flow_value(mf, &set_field->value, flow); break; case OFPACT_STACK_PUSH: -- 2.20.1