Make OVS_TUNNEL_ATTR_DST_IPV4 optional to allow configuration of null_ports.
authorJarno Rajahalme <jarno.rajahalme@nsn.com>
Sat, 29 Dec 2012 06:58:40 +0000 (08:58 +0200)
committerJesse Gross <jesse@nicira.com>
Mon, 31 Dec 2012 22:39:26 +0000 (14:39 -0800)
Signed-off-by: Jarno Rajahalme <jarno.rajahalme@nsn.com>
[jesse: correct return type of get_u32_or_zero()]
Signed-off-by: Jesse Gross <jesse@nicira.com>
Conflicts:

datapath/tunnel.c
include/openvswitch/tunnel.h
lib/netdev-vport.c

datapath/tunnel.c
include/openvswitch/tunnel.h
lib/netdev-vport.c

index 0a9bb37..470461a 100644 (file)
@@ -1066,11 +1066,16 @@ 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;
+       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;
 
-       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_FLAGS])
+               mutable->flags = nla_get_u32(a[OVS_TUNNEL_ATTR_FLAGS])
+                       & TNL_F_PUBLIC;
 
        if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
                if (ipv4_is_multicast(mutable->key.daddr))
@@ -1225,11 +1230,15 @@ 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);
 
+       /* 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 (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))
+                       mutable->flags & TNL_F_PUBLIC))
                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;
index 42c3621..479f524 100644 (file)
 
 /* OVS_VPORT_ATTR_OPTIONS attributes for tunnels.
  *
- * OVS_TUNNEL_ATTR_FLAGS and OVS_TUNNEL_ATTR_DST_IPV4 are required.  All other
+ * OVS_TUNNEL_ATTR_DST_IPV4 is required for kernel tunnel ports, all other
  * attributes are optional.
+ * For flow-based tunnels, none of the options apply.
  */
 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. */
index 5171171..512763d 100644 (file)
@@ -136,6 +136,12 @@ netdev_vport_get_vport_type(const struct netdev *netdev)
             : OVS_VPORT_TYPE_UNSPEC);
 }
 
+static uint32_t
+get_u32_or_zero(const struct nlattr *a)
+{
+    return a ? nl_attr_get_u32(a) : 0;
+}
+
 const char *
 netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
 {
@@ -159,7 +165,7 @@ 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 (get_u32_or_zero(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
                 ? "ipsec_gre" : "gre");
 
     case OVS_VPORT_TYPE_GRE64:
@@ -167,7 +173,7 @@ 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 (get_u32_or_zero(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_IPSEC
                 ? "ipsec_gre64" : "gre64");
 
     case OVS_VPORT_TYPE_CAPWAP:
@@ -523,7 +529,6 @@ static const char *
 netdev_vport_get_tnl_iface(const struct netdev *netdev)
 {
     struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
-    ovs_be32 route;
     struct netdev_dev_vport *ndv;
     static char name[IFNAMSIZ];
 
@@ -532,12 +537,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]) {
+        ovs_be32 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;
 }
 \f
@@ -749,8 +755,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 },
@@ -779,7 +785,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;
 
@@ -788,9 +793,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]);
@@ -820,7 +826,8 @@ unparse_tunnel_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED,
         }
     }
 
-    flags = nl_attr_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]);
+    flags = get_u32_or_zero(a[OVS_TUNNEL_ATTR_FLAGS]);
+
     if (flags & TNL_F_TTL_INHERIT) {
         smap_add(args, "ttl", "inherit");
     } else if (a[OVS_TUNNEL_ATTR_TTL]) {