Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com> --- 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev