[ovs-dev] [PATCH 2/4] tunnel: Consolidate action code for tunnel port receive.

Jesse Gross jesse at nicira.com
Tue Aug 6 19:57:14 UTC 2013


There are a couple of operations that are related to receiving a
packet on a tunnel port but that affect the actions and therefore
need to be performed on the output path. This adds a new hook to
do this and consolidates the existing code there.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 ofproto/ofproto-dpif-xlate.c | 30 +++---------------------------
 ofproto/tunnel.c             | 38 ++++++++++++++++++++++++++++++++++++++
 ofproto/tunnel.h             |  2 ++
 3 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 1e71aa1..0c0d9ef 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -195,8 +195,6 @@ static void output_normal(struct xlate_ctx *, const struct xbundle *,
                           uint16_t vlan);
 static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port);
 
-static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-
 static struct xbridge *xbridge_lookup(const struct ofproto_dpif *);
 static struct xbundle *xbundle_lookup(const struct ofbundle *);
 static struct xport *xport_lookup(const struct ofport_dpif *);
@@ -2082,24 +2080,6 @@ may_receive(const struct xport *xport, struct xlate_ctx *ctx)
     return true;
 }
 
-static bool
-tunnel_ecn_ok(struct xlate_ctx *ctx)
-{
-    if (is_ip_any(&ctx->base_flow)
-        && (ctx->xin->flow.tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) {
-        if ((ctx->base_flow.nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) {
-            VLOG_WARN_RL(&rl, "dropping tunnel packet marked ECN CE"
-                         " but is not ECN capable");
-            return false;
-        } else {
-            /* Set the ECN CE value in the tunneled packet. */
-            ctx->xin->flow.nw_tos |= IP_ECN_CE;
-        }
-    }
-
-    return true;
-}
-
 static void
 do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
                  struct xlate_ctx *ctx)
@@ -2475,6 +2455,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
     struct flow orig_flow;
     struct xlate_ctx ctx;
     size_t ofpacts_len;
+    bool tnl_may_send;
 
     COVERAGE_INC(xlate_actions);
 
@@ -2528,12 +2509,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
     memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
     wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
 
-    if (tnl_port_should_receive(&ctx.xin->flow)) {
-        memset(&wc->masks.tunnel, 0xff, sizeof wc->masks.tunnel);
-        /* pkt_mark is currently used only by tunnels but that will likely
-         * change in the future. */
-        memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
-    }
+    tnl_may_send = tnl_xlate_init(&ctx.base_flow, flow, wc);
     if (ctx.xbridge->has_netflow) {
         netflow_mask_wc(flow, wc);
     }
@@ -2602,7 +2578,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         add_ipfix_action(&ctx);
         sample_actions_len = ctx.xout->odp_actions.size;
 
-        if (tunnel_ecn_ok(&ctx) && (!in_port || may_receive(in_port, &ctx))) {
+        if (tnl_may_send && (!in_port || may_receive(in_port, &ctx))) {
             do_xlate_actions(ofpacts, ofpacts_len, &ctx);
 
             /* We've let OFPP_NORMAL and the learning action look at the
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 0c59632..f662a66 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -249,6 +249,44 @@ out:
     return ofport;
 }
 
+static bool
+tnl_ecn_ok(const struct flow *base_flow, struct flow *flow)
+{
+    if (is_ip_any(base_flow)
+        && (flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) {
+        if ((base_flow->nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) {
+            VLOG_WARN_RL(&rl, "dropping tunnel packet marked ECN CE"
+                         " but is not ECN capable");
+            return false;
+        } else {
+            /* Set the ECN CE value in the tunneled packet. */
+            flow->nw_tos |= IP_ECN_CE;
+        }
+    }
+
+    return true;
+}
+
+/* Should be called at the beginning of action translation to initialize
+ * wildcards and perform any actions based on receiving on tunnel port.
+ *
+ * Returns false if the packet must be dropped. */
+bool
+tnl_xlate_init(const struct flow *base_flow, struct flow *flow,
+               struct flow_wildcards *wc)
+{
+    if (tnl_port_should_receive(flow)) {
+        memset(&wc->masks.tunnel, 0xff, sizeof wc->masks.tunnel);
+        memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
+
+        if (!tnl_ecn_ok(base_flow, flow)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 /* Given that 'flow' should be output to the ofport corresponding to
  * 'tnl_port', updates 'flow''s tunnel headers and returns the actual datapath
  * port that the output should happen on.  May return ODPP_NONE if the output
diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h
index f175f1a..afe78ab 100644
--- a/ofproto/tunnel.h
+++ b/ofproto/tunnel.h
@@ -39,6 +39,8 @@ void tnl_port_add(const struct ofport_dpif *, const struct netdev *,
 void tnl_port_del(const struct ofport_dpif *);
 
 const struct ofport_dpif *tnl_port_receive(const struct flow *);
+bool tnl_xlate_init(const struct flow *base_flow, struct flow *flow,
+                    struct flow_wildcards *);
 odp_port_t tnl_port_send(const struct ofport_dpif *, struct flow *,
                          struct flow_wildcards *wc);
 
-- 
1.8.1.2




More information about the dev mailing list