[ovs-dev] [PATCH v2] Use updated dl_type when checking actions that use fields
Simon Horman
horms at verge.net.au
Fri May 10 02:00:06 UTC 2013
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 <jesse at nicira.com>
Signed-off-by: Simon Horman <horms at verge.net.au>
---
v2
* As suggested by Jesse gross.
- Move check from the top of ofpact_check__() into ofpacts_check() to
reduce copying of flow
---
lib/ofp-actions.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 068699f..026a376 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;
}
--
1.8.2.1
More information about the dev
mailing list