[ovs-dev] [PATCH v5 06/10] tc: Move tunnel_key unset action before output ports

Paul Blakey paulb at mellanox.com
Mon Dec 16 15:53:17 UTC 2019


Since OvS datapath gets packets already decapsulated from tunnel devices,
it doesn't explicitly decapsulate them. So in a recirculation setup,
the tunnel matching continues in the recirculation as the tunnel
metadata still exists on the SKB.

Tunnel key unset action unsets this metadata. Some drivers might rely
on this explicit tunnel key unset to know when to decapsulate the packet
instead of the device type. So instead of removing it completly,
we move it near the output actions.

This way, we also keep SKB metadata through recirculation, and for
non-recirculation rules, the resulting tc rules should remain the same.

Signed-off-by: Paul Blakey <paulb at mellanox.com>
Reviewed-by: Roi Dayan <roid at mellanox.com>

---

Changelog:
V3->V4:
    Fix: Set flower tunnel attribute to true, if any of the tunnel
         attributes exists (we used to rely on unset action).
V2->V3:
    Actually removed old tunnel set if tunnel exists (instead of just
    adding a new one before a port)
    Moved patch earlier to help git bisect
---
 lib/tc.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/lib/tc.c b/lib/tc.c
index b2d8ca7..7a4acce 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -665,6 +665,12 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower)
         flower->mask.tunnel.ttl =
             nl_attr_get_u8(attrs[TCA_FLOWER_KEY_ENC_IP_TTL_MASK]);
     }
+
+    if (!is_all_zeros(&flower->mask.tunnel, sizeof flower->mask.tunnel) ||
+        !is_all_zeros(&flower->key.tunnel, sizeof flower->key.tunnel)) {
+        flower->tunnel = true;
+    }
+
     if (attrs[TCA_FLOWER_KEY_ENC_OPTS] &&
         attrs[TCA_FLOWER_KEY_ENC_OPTS_MASK]) {
          err = nl_parse_flower_tunnel_opts(attrs[TCA_FLOWER_KEY_ENC_OPTS],
@@ -2091,24 +2097,17 @@ nl_msg_put_flower_rewrite_pedits(struct ofpbuf *request,
 static int
 nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
 {
+    bool ingress, released = false;
     size_t offset;
     size_t act_offset;
     uint16_t act_index = 1;
     struct tc_action *action;
     int i, ifindex = 0;
-    bool ingress;
 
     offset = nl_msg_start_nested(request, TCA_FLOWER_ACT);
     {
         int error;
 
-        if (flower->tunnel) {
-            act_offset = nl_msg_start_nested(request, act_index++);
-            nl_msg_put_act_tunnel_key_release(request);
-            nl_msg_put_act_flags(request);
-            nl_msg_end_nested(request, act_offset);
-        }
-
         action = flower->actions;
         for (i = 0; i < flower->action_count; i++, action++) {
             switch (action->type) {
@@ -2185,6 +2184,13 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
             }
             break;
             case TC_ACT_OUTPUT: {
+                if (!released && flower->tunnel) {
+                    act_offset = nl_msg_start_nested(request, act_index++);
+                    nl_msg_put_act_tunnel_key_release(request);
+                    nl_msg_end_nested(request, act_offset);
+                    released = true;
+                }
+
                 ingress = action->out.ingress;
                 ifindex = action->out.ifindex_out;
                 if (ifindex < 1) {
-- 
1.8.3.1



More information about the dev mailing list