[ovs-dev] [PATCH 14/26] ofproto-dpif-xlate: Factor wildcard processing out of xlate_actions().

Ben Pfaff blp at nicira.com
Thu Jul 30 06:42:34 UTC 2015


I think that this makes xlate_actions() easier to read.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 ofproto/ofproto-dpif-xlate.c | 102 ++++++++++++++++++++++++-------------------
 1 file changed, 58 insertions(+), 44 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 8acb908..03bca1b 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4717,6 +4717,58 @@ too_many_output_actions(const struct ofpbuf *odp_actions OVS_UNUSED)
 #endif
 }
 
+static void
+xlate_wc_init(struct xlate_ctx *ctx)
+{
+    flow_wildcards_init_catchall(ctx->wc);
+
+    /* Some fields we consider to always be examined. */
+    memset(&ctx->wc->masks.in_port, 0xff, sizeof ctx->wc->masks.in_port);
+    memset(&ctx->wc->masks.dl_type, 0xff, sizeof ctx->wc->masks.dl_type);
+    if (is_ip_any(&ctx->xin->flow)) {
+        ctx->wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+    }
+
+    if (ctx->xbridge->support.odp.recirc) {
+        /* Always exactly match recirc_id when datapath supports
+         * recirculation.  */
+        ctx->wc->masks.recirc_id = UINT32_MAX;
+    }
+
+    if (ctx->xbridge->netflow) {
+        netflow_mask_wc(&ctx->xin->flow, ctx->wc);
+    }
+
+    tnl_wc_init(&ctx->xin->flow, ctx->wc);
+}
+
+static void
+xlate_wc_finish(struct xlate_ctx *ctx)
+{
+    /* Clear the metadata and register wildcard masks, because we won't
+     * use non-header fields as part of the cache. */
+    flow_wildcards_clear_non_packet_fields(ctx->wc);
+
+    /* ICMPv4 and ICMPv6 have 8-bit "type" and "code" fields.  struct flow
+     * uses the low 8 bits of the 16-bit tp_src and tp_dst members to
+     * represent these fields.  The datapath interface, on the other hand,
+     * represents them with just 8 bits each.  This means that if the high
+     * 8 bits of the masks for these fields somehow become set, then they
+     * will get chopped off by a round trip through the datapath, and
+     * revalidation will spot that as an inconsistency and delete the flow.
+     * Avoid the problem here by making sure that only the low 8 bits of
+     * either field can be unwildcarded for ICMP.
+     */
+    if (is_icmpv4(&ctx->xin->flow) || is_icmpv6(&ctx->xin->flow)) {
+        ctx->wc->masks.tp_src &= htons(UINT8_MAX);
+        ctx->wc->masks.tp_dst &= htons(UINT8_MAX);
+    }
+    /* VLAN_TCI CFI bit must be matched if any of the TCI is matched. */
+    if (ctx->wc->masks.vlan_tci) {
+        ctx->wc->masks.vlan_tci |= htons(VLAN_CFI);
+    }
+}
+
 /* Translates the flow, actions, or rule in 'xin' into datapath actions in
  * 'xout'.
  * The caller must take responsibility for eventually freeing 'xout', with
@@ -4782,9 +4834,11 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
     };
     memset(&ctx.base_flow.tunnel, 0, sizeof ctx.base_flow.tunnel);
     ofpbuf_reserve(ctx.odp_actions, NL_A_U32_SIZE);
+    if (xin->wc) {
+        xlate_wc_init(&ctx);
+    }
 
     struct xport *in_port;
-    bool tnl_may_send;
 
     COVERAGE_INC(xlate_actions);
 
@@ -4809,26 +4863,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
      *   kernel does.  If we wish to maintain the original values an action
      *   needs to be generated. */
 
-    if (xin->wc) {
-        flow_wildcards_init_catchall(ctx.wc);
-        memset(&ctx.wc->masks.in_port, 0xff, sizeof ctx.wc->masks.in_port);
-        memset(&ctx.wc->masks.dl_type, 0xff, sizeof ctx.wc->masks.dl_type);
-        if (is_ip_any(flow)) {
-            ctx.wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
-        }
-        if (xbridge->support.odp.recirc) {
-            /* Always exactly match recirc_id when datapath supports
-             * recirculation.  */
-            ctx.wc->masks.recirc_id = UINT32_MAX;
-        }
-        if (xbridge->netflow) {
-            netflow_mask_wc(flow, ctx.wc);
-        }
-        tnl_wc_init(flow, xin->wc);
-    }
-
-    tnl_may_send = tnl_process_ecn(flow);
-
     /* The in_port of the original packet before recirculation. */
     in_port = get_ofp_port(xbridge, flow->in_port.ofp_port);
 
@@ -4968,7 +5002,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         }
         size_t sample_actions_len = ctx.odp_actions->size;
 
-        if (tnl_may_send && (!in_port || may_receive(in_port, &ctx))) {
+        if (tnl_process_ecn(flow)
+            && (!in_port || may_receive(in_port, &ctx))) {
             const struct ofpact *ofpacts;
             size_t ofpacts_len;
 
@@ -5079,28 +5114,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
     }
 
     if (xin->wc) {
-        /* Clear the metadata and register wildcard masks, because we won't
-         * use non-header fields as part of the cache. */
-        flow_wildcards_clear_non_packet_fields(ctx.wc);
-
-        /* ICMPv4 and ICMPv6 have 8-bit "type" and "code" fields.  struct flow
-         * uses the low 8 bits of the 16-bit tp_src and tp_dst members to
-         * represent these fields.  The datapath interface, on the other hand,
-         * represents them with just 8 bits each.  This means that if the high
-         * 8 bits of the masks for these fields somehow become set, then they
-         * will get chopped off by a round trip through the datapath, and
-         * revalidation will spot that as an inconsistency and delete the flow.
-         * Avoid the problem here by making sure that only the low 8 bits of
-         * either field can be unwildcarded for ICMP.
-         */
-        if (is_icmpv4(flow) || is_icmpv6(flow)) {
-            ctx.wc->masks.tp_src &= htons(UINT8_MAX);
-            ctx.wc->masks.tp_dst &= htons(UINT8_MAX);
-        }
-        /* VLAN_TCI CFI bit must be matched if any of the TCI is matched. */
-        if (ctx.wc->masks.vlan_tci) {
-            ctx.wc->masks.vlan_tci |= htons(VLAN_CFI);
-        }
+        xlate_wc_finish(&ctx);
     }
 
 exit:
-- 
2.1.3




More information about the dev mailing list