The initialization of 'base_flow' was previously split into a few pieces,
and I think it's easier to understand if it's all in one place.

This also moves and rewrites the comment describing 'base_flow'.  I think
that the perspective of the new comment is a little more useful.

Signed-off-by: Ben Pfaff <b...@nicira.com>
---
 ofproto/ofproto-dpif-xlate.c | 50 +++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 28 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 7726a40..8a208a4 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4770,7 +4770,29 @@ xlate_actions(struct xlate_in *xin, struct xlate_out 
*xout)
         .action_set_has_group = false,
         .action_set = OFPBUF_STUB_INITIALIZER(action_set_stub),
     };
+
+    /* 'base_flow' reflects the packet as it came in, but we need it to reflect
+     * the packet as the datapath will treat it for output actions:
+     *
+     *     - Our datapath doesn't retain tunneling information without us
+     *       re-setting it, so clear the tunnel data.
+     *
+     *     - For VLAN splinters, a higher layer may pretend that the packet
+     *       came in on 'flow->in_port.ofp_port' with 'flow->vlan_tci'
+     *       attached, because that's how we want to treat it from an OpenFlow
+     *       perspective.  But from the datapath's perspective it actually came
+     *       in on a VLAN device without any VLAN attached.  So here we put the
+     *       datapath's view of the VLAN information in 'base_flow' to ensure
+     *       correct treatment.
+     */
     memset(&ctx.base_flow.tunnel, 0, sizeof ctx.base_flow.tunnel);
+    if (flow->in_port.ofp_port
+        != vsp_realdev_to_vlandev(xbridge->ofproto,
+                                  flow->in_port.ofp_port,
+                                  flow->vlan_tci)) {
+        ctx.base_flow.vlan_tci = 0;
+    }
+
     ofpbuf_reserve(ctx.odp_actions, NL_A_U32_SIZE);
     if (xin->wc) {
         xlate_wc_init(&ctx);
@@ -4780,27 +4802,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out 
*xout)
 
     COVERAGE_INC(xlate_actions);
 
-    /* Flow initialization rules:
-     * - 'base_flow' must match the kernel's view of the packet at the
-     *   time that action processing starts.  'flow' represents any
-     *   transformations we wish to make through actions.
-     * - By default 'base_flow' and 'flow' are the same since the input
-     *   packet matches the output before any actions are applied.
-     * - When using VLAN splinters, 'base_flow''s VLAN is set to the value
-     *   of the received packet as seen by the kernel.  If we later output
-     *   to another device without any modifications this will cause us to
-     *   insert a new tag since the original one was stripped off by the
-     *   VLAN device.
-     * - Tunnel metadata as received is retained in 'flow'. This allows
-     *   tunnel metadata matching also in later tables.
-     *   Since a kernel action for setting the tunnel metadata will only be
-     *   generated with actual tunnel output, changing the tunnel metadata
-     *   values in 'flow' (such as tun_id) will only have effect with a later
-     *   tunnel output action.
-     * - Tunnel 'base_flow' is completely cleared since that is what the
-     *   kernel does.  If we wish to maintain the original values an action
-     *   needs to be generated. */
-
     /* The in_port of the original packet before recirculation. */
     in_port = get_ofp_port(xbridge, flow->in_port.ofp_port);
 
@@ -4926,13 +4927,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out 
*xout)
     /* Do not perform special processing on recirculated packets,
      * as recirculated packets are not really received by the bridge. */
     if (xin->recirc || !process_special(&ctx, in_port)) {
-        if (flow->in_port.ofp_port
-            != vsp_realdev_to_vlandev(xbridge->ofproto,
-                                      flow->in_port.ofp_port,
-                                      flow->vlan_tci)) {
-            ctx.base_flow.vlan_tci = 0;
-        }
-
         /* Sampling is done only for packets really received by the bridge. */
         unsigned int user_cookie_offset = 0;
         if (!xin->recirc) {
-- 
2.1.3

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

Reply via email to