[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