Make all kernel tunnel configuration attributes optional. Attributes
meaningful for null ports are processed first, and the rest are skipped for
null ports.

Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com>
---

v2 makes also flags optional, avoids setting any key flags for null ports,
and still requires remote IP to be configured on the API level as null ports
are not yet functional.

Not sure if any of the flags are useful for a null port, but it seems
that at least the TNL_F_IPSEC could to be still needed.

---
 datapath/tunnel.c            |   41 +++++++++++++++++++++++++++--------------
 include/openvswitch/tunnel.h |    8 ++++----
 lib/netdev-vport.c           |   38 ++++++++++++++++++++++++--------------
 3 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 26d9014..97c3d8e 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -1067,11 +1067,22 @@ static int tnl_set_config(struct net *net, struct 
nlattr *options,
        if (err)
                return err;
 
-       if (!a[OVS_TUNNEL_ATTR_FLAGS] || !a[OVS_TUNNEL_ATTR_DST_IPV4])
-               return -EINVAL;
+       /* Process attributes possibly useful for null_ports first */
+       if (a[OVS_TUNNEL_ATTR_FLAGS])
+               mutable->flags = nla_get_u32(a[OVS_TUNNEL_ATTR_FLAGS])
+                       & TNL_F_PUBLIC;
+
+       if (a[OVS_TUNNEL_ATTR_DST_PORT])
+               mutable->dst_port =
+                       htons(nla_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]));
 
-       mutable->flags = nla_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_PUBLIC;
-       mutable->key.daddr = nla_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+       if (a[OVS_TUNNEL_ATTR_DST_IPV4]) {
+               mutable->key.daddr = nla_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+       }
+
+       /* Skip the rest if configuring a null_port */
+       if (!mutable->key.daddr)
+               goto out;
 
        if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
                if (ipv4_is_multicast(mutable->key.daddr))
@@ -1089,10 +1100,6 @@ static int tnl_set_config(struct net *net, struct nlattr 
*options,
        if (a[OVS_TUNNEL_ATTR_TTL])
                mutable->ttl = nla_get_u8(a[OVS_TUNNEL_ATTR_TTL]);
 
-       if (a[OVS_TUNNEL_ATTR_DST_PORT])
-               mutable->dst_port =
-                       htons(nla_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]));
-
        if (!a[OVS_TUNNEL_ATTR_IN_KEY]) {
                mutable->key.tunnel_type |= TNL_T_KEY_MATCH;
                mutable->flags |= TNL_F_IN_KEY_MATCH;
@@ -1230,11 +1237,20 @@ int ovs_tnl_get_options(const struct vport *vport, 
struct sk_buff *skb)
        const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
        const struct tnl_mutable_config *mutable = 
rcu_dereference_rtnl(tnl_vport->mutable);
 
-       if (nla_put_u32(skb, OVS_TUNNEL_ATTR_FLAGS,
-                     mutable->flags & TNL_F_PUBLIC) ||
-           nla_put_be32(skb, OVS_TUNNEL_ATTR_DST_IPV4, mutable->key.daddr))
+       if (mutable->flags &&
+           nla_put_u32(skb, OVS_TUNNEL_ATTR_FLAGS,
+                       mutable->flags & TNL_F_PUBLIC))
+               goto nla_put_failure;
+       if (mutable->dst_port && nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT,
+                                            ntohs(mutable->dst_port)))
                goto nla_put_failure;
 
+       /* Skip the rest for null_ports */
+       if (!mutable->key.daddr)
+               return 0;
+
+       if (nla_put_be32(skb, OVS_TUNNEL_ATTR_DST_IPV4, mutable->key.daddr))
+               goto nla_put_failure;
        if (!(mutable->flags & TNL_F_IN_KEY_MATCH) &&
            nla_put_be64(skb, OVS_TUNNEL_ATTR_IN_KEY, mutable->key.in_key))
                goto nla_put_failure;
@@ -1248,9 +1264,6 @@ int ovs_tnl_get_options(const struct vport *vport, struct 
sk_buff *skb)
                goto nla_put_failure;
        if (mutable->ttl && nla_put_u8(skb, OVS_TUNNEL_ATTR_TTL, mutable->ttl))
                goto nla_put_failure;
-       if (mutable->dst_port && nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT,
-                                            ntohs(mutable->dst_port)))
-               goto nla_put_failure;
 
        return 0;
 
diff --git a/include/openvswitch/tunnel.h b/include/openvswitch/tunnel.h
index 23d8ba7..d18b6c9 100644
--- a/include/openvswitch/tunnel.h
+++ b/include/openvswitch/tunnel.h
@@ -45,14 +45,14 @@
 
 /* OVS_VPORT_ATTR_OPTIONS attributes for tunnels.
  *
- * OVS_TUNNEL_ATTR_FLAGS and OVS_TUNNEL_ATTR_DST_IPV4 are required.  All other
- * attributes are optional.
+ * OVS_TUNNEL_ATTR_DST_IPV4 is required for kernel tunnel ports, but not for
+ * flow-based tunnels. All other attributes are optional.
  */
 enum {
        OVS_TUNNEL_ATTR_UNSPEC,
        OVS_TUNNEL_ATTR_FLAGS,    /* 32-bit TNL_F_*. */
-       OVS_TUNNEL_ATTR_DST_IPV4, /* IPv4 destination address. */
-       OVS_TUNNEL_ATTR_SRC_IPV4, /* IPv4 source address. */
+       OVS_TUNNEL_ATTR_DST_IPV4, /* Remote IPv4 address. */
+       OVS_TUNNEL_ATTR_SRC_IPV4, /* Local IPv4 address. */
        OVS_TUNNEL_ATTR_OUT_KEY,  /* __be64 key to use on output. */
        OVS_TUNNEL_ATTR_IN_KEY,   /* __be64 key to match on input. */
        OVS_TUNNEL_ATTR_TOS,      /* 8-bit TOS value. */
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 2b493a7..9cf0906 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -162,7 +162,8 @@ netdev_vport_get_netdev_type(const struct dpif_linux_vport 
*vport)
                                         a)) {
             break;
         }
-        return (nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
+        return (a[OVS_TUNNEL_ATTR_FLAGS]
+                && nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
                 ? "ipsec_gre" : "gre");
 
     case OVS_VPORT_TYPE_GRE64:
@@ -170,7 +171,8 @@ netdev_vport_get_netdev_type(const struct dpif_linux_vport 
*vport)
                                         a)) {
             break;
         }
-        return (nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
+        return (a[OVS_TUNNEL_ATTR_FLAGS]
+                && nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
                 ? "ipsec_gre64" : "gre64");
 
     case OVS_VPORT_TYPE_CAPWAP:
@@ -538,12 +540,13 @@ netdev_vport_get_tnl_iface(const struct netdev *netdev)
                                     a)) {
         return NULL;
     }
-    route = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+    if (a[OVS_TUNNEL_ATTR_DST_IPV4]) {
+        route = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
 
-    if (route_table_get_name(route, name)) {
-        return name;
+        if (route_table_get_name(route, name)) {
+            return name;
+        }
     }
-
     return NULL;
 }
 
@@ -743,6 +746,8 @@ parse_tunnel_config(const char *name, const char *type,
     set_key(args, "in_key", OVS_TUNNEL_ATTR_IN_KEY, options);
     set_key(args, "out_key", OVS_TUNNEL_ATTR_OUT_KEY, options);
 
+    /* Remote_ip requirement will be removed when flow-based tunneling
+     * is complete. */
     if (!daddr) {
         VLOG_ERR("%s: %s type requires valid 'remote_ip' argument",
                  name, type);
@@ -758,7 +763,9 @@ parse_tunnel_config(const char *name, const char *type,
         }
     }
 
-    nl_msg_put_u32(options, OVS_TUNNEL_ATTR_FLAGS, flags);
+    if (flags) {
+        nl_msg_put_u32(options, OVS_TUNNEL_ATTR_FLAGS, flags);
+    }
 
     return 0;
 }
@@ -768,8 +775,8 @@ tnl_port_config_from_nlattr(const struct nlattr *options, 
size_t options_len,
                             struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1])
 {
     static const struct nl_policy ovs_tunnel_policy[] = {
-        [OVS_TUNNEL_ATTR_FLAGS] = { .type = NL_A_U32 },
-        [OVS_TUNNEL_ATTR_DST_IPV4] = { .type = NL_A_BE32 },
+        [OVS_TUNNEL_ATTR_FLAGS] = { .type = NL_A_U32, .optional = true },
+        [OVS_TUNNEL_ATTR_DST_IPV4] = { .type = NL_A_BE32, .optional = true },
         [OVS_TUNNEL_ATTR_SRC_IPV4] = { .type = NL_A_BE32, .optional = true },
         [OVS_TUNNEL_ATTR_IN_KEY] = { .type = NL_A_BE64, .optional = true },
         [OVS_TUNNEL_ATTR_OUT_KEY] = { .type = NL_A_BE64, .optional = true },
@@ -799,7 +806,6 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const 
char *type OVS_UNUSED,
                       struct smap *args)
 {
     struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
-    ovs_be32 daddr;
     uint32_t flags;
     int error;
 
@@ -808,9 +814,10 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const 
char *type OVS_UNUSED,
         return error;
     }
 
-
-    daddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
-    smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(daddr));
+    if (a[OVS_TUNNEL_ATTR_DST_IPV4]) {
+        ovs_be32 daddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+        smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(daddr));
+    }
 
     if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
         ovs_be32 saddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_SRC_IPV4]);
@@ -840,7 +847,10 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const 
char *type OVS_UNUSED,
         }
     }
 
-    flags = nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]);
+    flags = a[OVS_TUNNEL_ATTR_FLAGS]
+        ? nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS])
+        : 0;
+
     if (flags & TNL_F_TTL_INHERIT) {
         smap_add(args, "ttl", "inherit");
     } else if (a[OVS_TUNNEL_ATTR_TTL]) {
-- 
1.7.10.4

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

Reply via email to