From: Simon Horman Date: Fri, 10 May 2013 02:00:06 +0000 (+0900) Subject: Use updated dl_type when checking actions that use fields X-Git-Tag: sliver-openvswitch-1.10.90-3~16^2~2 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=500d243dad40ff667710aca1d099d97c38e6a62d;p=sliver-openvswitch.git Use updated dl_type when checking actions that use fields Update handling of the following actions to use the dl_type set by MPLS push and pop actions if it differs from the original dl_type. This is consistent with the existing checking of load actions and allows their existing checks to enforce dl_type pre-requisites correctly. output_reg bundle reg_move stack_push stack_pop learn multipath In order to avoid the verbosity of updating the flow for each applicable action the update is treated as a common case and performed in ofpact_check(). This was suggested by Jesse Gross. Cc: Jesse Gross Signed-off-by: Simon Horman Signed-off-by: Jesse Gross --- diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 068699f66..026a376d9 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -1181,13 +1181,7 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports, return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow); case OFPACT_REG_LOAD: - if (*dl_type != flow->dl_type) { - struct flow updated_flow = *flow; - updated_flow.dl_type = *dl_type; - return nxm_reg_load_check(ofpact_get_REG_LOAD(a), &updated_flow); - } else { - return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow); - } + return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow); case OFPACT_STACK_PUSH: return nxm_stack_push_check(ofpact_get_STACK_PUSH(a), flow); @@ -1245,9 +1239,23 @@ ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len, { const struct ofpact *a; ovs_be16 dl_type = flow->dl_type; + struct flow updated_flow; OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) { - enum ofperr error = ofpact_check__(a, flow, max_ports, &dl_type); + enum ofperr error; + + /* If the dl_type was changed by an action then its new value + * should be present in the flow passed to ofpact_check__(). */ + if (flow->dl_type != dl_type) { + /* Only copy flow at most once */ + if (flow != &updated_flow) { + updated_flow = *flow; + flow = &updated_flow; + } + updated_flow.dl_type = dl_type; + } + + error = ofpact_check__(a, flow, max_ports, &dl_type); if (error) { return error; }