[ovs-dev,V2,3/4] lib/tc: Support setting tos and ttl for TC IP tunnels

Message ID 1533033639-13009-4-git-send-email-ogerlitz@mellanox.com
State Accepted
Headers show
Series
  • Enable set/match of tos/ttl for IP tunnels on TC data-path
Related show

Commit Message

Or Gerlitz July 31, 2018, 10:40 a.m.
Allow to set the tos and ttl for TC tunnels.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
---
 acinclude.m4                         |  6 +++---
 include/linux/tc_act/tc_tunnel_key.h | 10 ++++++++--
 lib/netdev-tc-offloads.c             | 16 ++++++++++++++++
 lib/tc.c                             | 19 +++++++++++++++++--
 lib/tc.h                             |  2 ++
 5 files changed, 46 insertions(+), 7 deletions(-)

Patch

diff --git a/acinclude.m4 b/acinclude.m4
index d6e0d33..a5ff325 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -192,10 +192,10 @@  AC_DEFUN([OVS_CHECK_LINUX_TC], [
 
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([#include <linux/tc_act/tc_tunnel_key.h>], [
-        int x = TCA_TUNNEL_KEY_ENC_DST_PORT;
+        int x = TCA_TUNNEL_KEY_ENC_TTL;
     ])],
-    [AC_DEFINE([HAVE_TCA_TUNNEL_KEY_ENC_DST_PORT], [1],
-               [Define to 1 if TCA_TUNNEL_KEY_ENC_DST_PORT is avaiable.])])
+    [AC_DEFINE([HAVE_TCA_TUNNEL_KEY_ENC_TTL], [1],
+               [Define to 1 if TCA_TUNNEL_KEY_ENC_TTL is available.])])
 
   AC_COMPILE_IFELSE([
     AC_LANG_PROGRAM([#include <linux/tc_act/tc_pedit.h>], [
diff --git a/include/linux/tc_act/tc_tunnel_key.h b/include/linux/tc_act/tc_tunnel_key.h
index 0e49834..26cbd2f 100644
--- a/include/linux/tc_act/tc_tunnel_key.h
+++ b/include/linux/tc_act/tc_tunnel_key.h
@@ -1,7 +1,7 @@ 
 #ifndef __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H
 #define __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H 1
 
-#if defined(__KERNEL__) || defined(HAVE_TCA_TUNNEL_KEY_ENC_DST_PORT)
+#if defined(__KERNEL__) || defined(HAVE_TCA_TUNNEL_KEY_ENC_TTL)
 #include_next <linux/tc_act/tc_tunnel_key.h>
 #else
 
@@ -36,11 +36,17 @@  enum {
 	TCA_TUNNEL_KEY_ENC_KEY_ID,	/* be64 */
 	TCA_TUNNEL_KEY_PAD,
 	TCA_TUNNEL_KEY_ENC_DST_PORT,	/* be16 */
+	TCA_TUNNEL_KEY_NO_CSUM,     	/* u8 */
+	TCA_TUNNEL_KEY_ENC_OPTS,        /* Nested TCA_TUNNEL_KEY_ENC_OPTS_
+                                     * attributes
+                                     */
+	TCA_TUNNEL_KEY_ENC_TOS,		    /* u8 */
+	TCA_TUNNEL_KEY_ENC_TTL,		    /* u8 */
 	__TCA_TUNNEL_KEY_MAX,
 };
 
 #define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
 
-#endif /* __KERNEL__ || HAVE_TCA_TUNNEL_KEY_ENC_DST_PORT */
+#endif /* __KERNEL__ || HAVE_TCA_TUNNEL_KEY_ENC_TTL */
 
 #endif /* __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H */
diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c
index c61197a..7ed0844 100644
--- a/lib/netdev-tc-offloads.c
+++ b/lib/netdev-tc-offloads.c
@@ -563,6 +563,14 @@  parse_tc_flower_to_match(struct tc_flower *flower,
                     nl_msg_put_in6_addr(buf, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
                                         &action->encap.ipv6.ipv6_dst);
                 }
+                if (action->encap.tos) {
+                    nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TOS,
+                                  action->encap.tos);
+                }
+                if (action->encap.ttl) {
+                    nl_msg_put_u8(buf, OVS_TUNNEL_KEY_ATTR_TTL,
+                                  action->encap.ttl);
+                }
                 nl_msg_put_be16(buf, OVS_TUNNEL_KEY_ATTR_TP_DST,
                                 action->encap.tp_dst);
 
@@ -746,6 +754,14 @@  parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
             action->encap.ipv4.ipv4_dst = nl_attr_get_be32(tun_attr);
         }
         break;
+        case OVS_TUNNEL_KEY_ATTR_TOS: {
+            action->encap.tos = nl_attr_get_u8(tun_attr);
+        }
+        break;
+        case OVS_TUNNEL_KEY_ATTR_TTL: {
+            action->encap.ttl = nl_attr_get_u8(tun_attr);
+        }
+        break;
         case OVS_TUNNEL_KEY_ATTR_IPV6_SRC: {
             action->encap.ipv6.ipv6_src =
                 nl_attr_get_in6_addr(tun_attr);
diff --git a/lib/tc.c b/lib/tc.c
index ec7efff..d9c9ffa 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -641,6 +641,8 @@  static const struct nl_policy tunnel_key_policy[] = {
                                       .optional = true, },
     [TCA_TUNNEL_KEY_ENC_KEY_ID] = { .type = NL_A_U32, .optional = true, },
     [TCA_TUNNEL_KEY_ENC_DST_PORT] = { .type = NL_A_U16, .optional = true, },
+    [TCA_TUNNEL_KEY_ENC_TOS] = { .type = NL_A_U8, .optional = true, },
+    [TCA_TUNNEL_KEY_ENC_TTL] = { .type = NL_A_U8, .optional = true, },
 };
 
 static int
@@ -666,6 +668,8 @@  nl_parse_act_tunnel_key(struct nlattr *options, struct tc_flower *flower)
         struct nlattr *ipv4_dst = tun_attrs[TCA_TUNNEL_KEY_ENC_IPV4_DST];
         struct nlattr *ipv6_src = tun_attrs[TCA_TUNNEL_KEY_ENC_IPV6_SRC];
         struct nlattr *ipv6_dst = tun_attrs[TCA_TUNNEL_KEY_ENC_IPV6_DST];
+        struct nlattr *tos = tun_attrs[TCA_TUNNEL_KEY_ENC_TOS];
+        struct nlattr *ttl = tun_attrs[TCA_TUNNEL_KEY_ENC_TTL];
 
         action = &flower->actions[flower->action_count++];
         action->type = TC_ACT_ENCAP;
@@ -679,6 +683,8 @@  nl_parse_act_tunnel_key(struct nlattr *options, struct tc_flower *flower)
         }
         action->encap.id = id ? be32_to_be64(nl_attr_get_be32(id)) : 0;
         action->encap.tp_dst = dst_port ? nl_attr_get_be16(dst_port) : 0;
+        action->encap.tos = tos ? nl_attr_get_u8(tos) : 0;
+        action->encap.ttl = ttl ? nl_attr_get_u8(ttl) : 0;
     } else if (tun->t_action == TCA_TUNNEL_KEY_ACT_RELEASE) {
         flower->tunnel.tunnel = true;
     } else {
@@ -1251,7 +1257,8 @@  nl_msg_put_act_tunnel_key_set(struct ofpbuf *request, ovs_be64 id,
                                 ovs_be32 ipv4_src, ovs_be32 ipv4_dst,
                                 struct in6_addr *ipv6_src,
                                 struct in6_addr *ipv6_dst,
-                                ovs_be16 tp_dst)
+                                ovs_be16 tp_dst,
+                                uint8_t tos, uint8_t ttl)
 {
     size_t offset;
 
@@ -1274,6 +1281,12 @@  nl_msg_put_act_tunnel_key_set(struct ofpbuf *request, ovs_be64 id,
             nl_msg_put_in6_addr(request, TCA_TUNNEL_KEY_ENC_IPV6_SRC,
                                 ipv6_src);
         }
+        if (tos) {
+            nl_msg_put_u8(request, TCA_TUNNEL_KEY_ENC_TOS, tos);
+        }
+        if (ttl) {
+            nl_msg_put_u8(request, TCA_TUNNEL_KEY_ENC_TTL, ttl);
+        }
         nl_msg_put_be16(request, TCA_TUNNEL_KEY_ENC_DST_PORT, tp_dst);
     }
     nl_msg_end_nested(request, offset);
@@ -1515,7 +1528,9 @@  nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                                               action->encap.ipv4.ipv4_dst,
                                               &action->encap.ipv6.ipv6_src,
                                               &action->encap.ipv6.ipv6_dst,
-                                              action->encap.tp_dst);
+                                              action->encap.tp_dst,
+                                              action->encap.tos,
+                                              action->encap.ttl);
                 nl_msg_end_nested(request, act_offset);
             }
             break;
diff --git a/lib/tc.h b/lib/tc.h
index 90ef32a..9a265f4 100644
--- a/lib/tc.h
+++ b/lib/tc.h
@@ -130,6 +130,8 @@  struct tc_action {
             ovs_be64 id;
             ovs_be16 tp_src;
             ovs_be16 tp_dst;
+            uint8_t tos;
+            uint8_t ttl;
             struct {
                 ovs_be32 ipv4_src;
                 ovs_be32 ipv4_dst;