[ovs-dev] [PATCH 3/8] nx-match: Do not check pre-requisites for load actions

Simon Horman horms at verge.net.au
Tue Oct 30 06:49:20 UTC 2012


On Tue, Oct 30, 2012 at 09:59:24AM +0900, Simon Horman wrote:
> On Mon, Oct 29, 2012 at 09:58:58AM -0700, Ben Pfaff wrote:
> > On Sat, Oct 27, 2012 at 03:05:57PM +0900, Simon Horman wrote:
> > > There are (or at least will be) cases where this check can produce false
> > > positives.  For example, a flow which matches a non-MPLS packet and then
> > > applies an MPLS push action followed by an action to load the MPLS label.
> > 
> > So, I remember the discussion, but I don't remember coming to exactly
> > this conclusion.
> > 
> > The problem seems to be, at this point, MPLS specific, because for
> > most prerequisites, whether it is satisfied cannot be affected by
> > actions.  For example, no action can transform a TCP packet into a
> > non-TCP packet, and vice versa.
> > 
> > My thought is, then, for now we should define a new function to test
> > whether a prerequisite could ever be satisfied given a particular
> > flow.  For all prerequisites other than MPLS, this would return the
> > same thing as mf_are_prereqs_ok(); for MPLS, it could just return
> > true.
> 
> I think that I am comfortable with that approach, I will implement it
> and see how things go.

Hi Ben,

I had an idea about how to fix this particular problem a different way.
The idea seems to work, I would appreciate your feedback.

----------------------------------------------------------------
[RFC] Handle pre-requisites of MPLS set-field/load actions

mpls_push and mpls_pop actions may modify the dl_type of a flow.
This needs to be taken into account when checking the pre-requisites
of set-field/load actions.

This patch implements this by tracking the dl_type changes of
mpls_push and mpls_pop actions and passing an updated flow to
nxm_reg_load_check().

If acceptable, this change should be merged partially into
"User-Space MPLS actions and matches" and partially into
"Add support for copy_ttl_out action".

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/ofp-actions.c     |   20 ++++++++++++++++----
 tests/ofproto-dpif.at |    4 ++--
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 7e59484..df07357 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1112,7 +1112,8 @@ exit:
 }
 
 static enum ofperr
-ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports)
+ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports,
+               ovs_be16 *dl_type)
 {
     const struct ofpact_enqueue *enqueue;
 
@@ -1153,8 +1154,11 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports)
     case OFPACT_REG_MOVE:
         return nxm_reg_move_check(ofpact_get_REG_MOVE(a), flow);
 
-    case OFPACT_REG_LOAD:
-        return nxm_reg_load_check(ofpact_get_REG_LOAD(a), flow);
+    case OFPACT_REG_LOAD: {
+        struct flow updated_flow = *flow;
+        updated_flow.dl_type = *dl_type;
+        return nxm_reg_load_check(ofpact_get_REG_LOAD(a), &updated_flow);
+    }
 
     case OFPACT_DEC_TTL:
     case OFPACT_COPY_TTL_IN:
@@ -1179,8 +1183,14 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports)
 
     case OFPACT_NOTE:
     case OFPACT_EXIT:
+        return 0;
+
     case OFPACT_PUSH_MPLS:
+        *dl_type = ofpact_get_PUSH_MPLS(a)->ethertype;
+        return 0;
+
     case OFPACT_POP_MPLS:
+        *dl_type = ofpact_get_POP_MPLS(a)->ethertype;
         return 0;
 
     case OFPACT_CLEAR_ACTIONS:
@@ -1201,9 +1211,11 @@ ofpacts_check(const struct ofpact ofpacts[], size_t ofpacts_len,
               const struct flow *flow, int max_ports)
 {
     const struct ofpact *a;
+    ovs_be16 dl_type = flow->dl_type;
 
     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
-        enum ofperr error = ofpact_check__(a, flow, max_ports);
+        enum ofperr error = ofpact_check__(a, flow, max_ports,
+                                           &dl_type);
         if (error) {
             return error;
         }
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 24f04d4..642b261 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -256,8 +256,8 @@ cookie=0xa dl_src=40:44:44:44:44:46 actions=push_mpls:0x8847,load:10->OXM_OF_MPL
 cookie=0xa dl_src=40:44:44:44:44:47 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),controller
 cookie=0xa dl_src=40:44:44:44:44:48 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,controller
 cookie=0xa dl_src=40:44:44:44:44:49 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,copy_ttl_out,controller
-cookie=0xb dl_src=50:55:55:55:55:55 actions=load:1000->OXM_OF_MPLS_LABEL[[]],controller
-cookie=0xb dl_src=50:55:55:55:55:56 actions=load:1000->OXM_OF_MPLS_LABEL[[]],copy_ttl_out,controller
+cookie=0xb dl_src=50:55:55:55:55:55 dl_type=0x8847 actions=load:1000->OXM_OF_MPLS_LABEL[[]],controller
+cookie=0xb dl_src=50:55:55:55:55:56 dl_type=0x8847 actions=load:1000->OXM_OF_MPLS_LABEL[[]],copy_ttl_out,controller
 cookie=0xd dl_src=60:66:66:66:66:66 actions=pop_mpls:0x0800,controller
 cookie=0xd dl_src=60:66:66:66:66:67 actions=copy_ttl_in,dec_ttl,pop_mpls:0x0800,dec_ttl,controller
 cookie=0xc dl_src=70:77:77:77:77:77 actions=push_mpls:0x8848,load:1000->OXM_OF_MPLS_LABEL[[]],load:7->OXM_OF_MPLS_TC[[]],controller
-- 
1.7.10.4





More information about the dev mailing list