* Update the order in which actions are committed and thus
  appear in the datapath such that MPLS actions appear after
  l3 and l4 (nw and port) actions.

  In the case where an mpls_push action is present it should ensure
  that l3 and l4 actions occur first, which seems logical as
  once a mpls_push has occur the frame will be MPLS rather
  than IPv4 or IPv6.

  In the case where there is an mpls_pop action is present this should
  not make any difference as the frame will have been MPLS to start with
  and thus not satisfy the pre-requisites for  l3 or l4 actions.

* Update commit_set_nw_action() to use the base ethertype when considering
  eligibility to commit l3 (nw) actions. This allows l3 actions to be
  applied so long as the frame was originally IPv4 or IPv6, even if
  an mpls_push action will be applied and thus flow indicates the
  frame will be MPLS.

* Make actions that may modify port or network information conditional on
  the flow's ethernet type being an IP ethernet type. This is to ensure
  that actions that modify network and port information do not occur
  on non IP packets, for example if an mpls_push action has changed a
  packet from IP to MPLS.

  Note that modification of network data is already prevented by
  virtue of commit_set_nw_action() only having cases for when the
  ethernet type of the flow is  IPV4 or IPV6. The conditionality
  of network actions on the ethernet type has been added to
  do_xlate_actions() to make it explicit.

Signed-off-by: Simon Horman <ho...@verge.net.au>

---

v2.22
* Make actions that may modify port or network information conditional
  on the flow's ethernet type being an IP ethernet type.

v2.21
* First post
---
 lib/odp-util.c         |   10 +++++++---
 ofproto/ofproto-dpif.c |   16 ++++++++++++----
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/odp-util.c b/lib/odp-util.c
index 54e5b12..1a3e386 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -2323,9 +2323,9 @@ commit_set_nw_action(const struct flow *flow, struct flow 
*base,
         return;
     }
 
-    if (flow->dl_type == htons(ETH_TYPE_IP)) {
+    if (base->dl_type == htons(ETH_TYPE_IP)) {
         commit_set_ipv4_action(flow, base, odp_actions);
-    } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+    } else if (base->dl_type == htons(ETH_TYPE_IPV6)) {
         commit_set_ipv6_action(flow, base, odp_actions);
     }
 }
@@ -2398,9 +2398,13 @@ commit_odp_actions(const struct flow *flow, struct flow 
*base,
 {
     commit_set_ether_addr_action(flow, base, odp_actions);
     commit_vlan_action(flow, base, odp_actions);
-    commit_mpls_action(flow, base, odp_actions);
     commit_set_nw_action(flow, base, odp_actions);
     commit_set_port_action(flow, base, odp_actions);
+    /* Commiting MPLS actions should occur after committing nw and port
+     * actions. This is because committing MPLS actions may alter a packet so
+     * that it is no longer IP and thus nw and port actions are no longer 
valid.
+     */
+    commit_mpls_action(flow, base, odp_actions);
     commit_set_priority_action(flow, base, odp_actions);
     commit_set_skb_mark_action(flow, base, odp_actions);
 }
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index d1b9f34..6e9023a 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -6450,11 +6450,15 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
ofpacts_len,
             break;
 
         case OFPACT_SET_IPV4_SRC:
-            ctx->flow.nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4;
+            if (ctx->flow.dl_type == htons(ETH_TYPE_IP)) {
+                ctx->flow.nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4;
+            }
             break;
 
         case OFPACT_SET_IPV4_DST:
-            ctx->flow.nw_dst = ofpact_get_SET_IPV4_DST(a)->ipv4;
+            if (ctx->flow.dl_type == htons(ETH_TYPE_IP)) {
+                ctx->flow.nw_dst = ofpact_get_SET_IPV4_DST(a)->ipv4;
+            }
             break;
 
         case OFPACT_SET_IPV4_DSCP:
@@ -6466,11 +6470,15 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
ofpacts_len,
             break;
 
         case OFPACT_SET_L4_SRC_PORT:
-            ctx->flow.tp_src = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
+            if (is_ip_any(&ctx->flow)) {
+                ctx->flow.tp_src = htons(ofpact_get_SET_L4_SRC_PORT(a)->port);
+            }
             break;
 
         case OFPACT_SET_L4_DST_PORT:
-            ctx->flow.tp_dst = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
+            if (is_ip_any(&ctx->flow)) {
+                ctx->flow.tp_dst = htons(ofpact_get_SET_L4_DST_PORT(a)->port);
+            }
             break;
 
         case OFPACT_RESUBMIT:
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to