[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