Signed-off-by: Jarno Rajahalme <[email protected]>
---
v3 restores compatibility with old userspace/kernel by
unconditionally sending flags (as expected by old code),
but making flags optional when received.
---
datapath/tunnel.c | 39 +++++++++++++++++++++++++--------------
include/openvswitch/tunnel.h | 7 ++++---
lib/netdev-vport.c | 35 +++++++++++++++++++++--------------
3 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 26d9014..08501ab 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -1067,11 +1067,21 @@ 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_DST_PORT])
+ mutable->dst_port =
+ htons(nla_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]));
+
+ if (a[OVS_TUNNEL_ATTR_DST_IPV4])
+ mutable->key.daddr = nla_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
- 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]);
+ /* Skip the rest if configuring a null_port */
+ if (!mutable->key.daddr)
+ goto out;
+
+ 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))
@@ -1089,10 +1099,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 +1236,19 @@ 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->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 (nla_put_u32(skb, OVS_TUNNEL_ATTR_FLAGS,
+ 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;
@@ -1248,9 +1262,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..8a53ef8 100644
--- a/include/openvswitch/tunnel.h
+++ b/include/openvswitch/tunnel.h
@@ -45,14 +45,15 @@
/* 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, only the OVS_TUNNEL_ATTR_DST_PORT is useful.
*/
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..3374c31 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -139,6 +139,12 @@ netdev_vport_get_vport_type(const struct netdev *netdev)
: OVS_VPORT_TYPE_UNSPEC);
}
+static uint64_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)
{
@@ -162,7 +168,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:
@@ -170,7 +176,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:
@@ -529,7 +535,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];
@@ -538,12 +543,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;
}
@@ -768,8 +774,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 +805,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 +813,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 +846,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]) {
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev