From: Jarno Rajahalme Date: Sat, 29 Dec 2012 06:58:40 +0000 (+0200) Subject: Make OVS_TUNNEL_ATTR_DST_IPV4 optional to allow configuration of null_ports. X-Git-Tag: sliver-openvswitch-1.9.90-3~10^2~55 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=7f804ea5a3e44b1831e5cfbd09eab46cc36a1459;p=sliver-openvswitch.git Make OVS_TUNNEL_ATTR_DST_IPV4 optional to allow configuration of null_ports. Signed-off-by: Jarno Rajahalme [jesse: correct return type of get_u32_or_zero()] Signed-off-by: Jesse Gross --- diff --git a/datapath/tunnel.c b/datapath/tunnel.c index ae99cc16b..d03b708ed 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -1066,11 +1066,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)) @@ -1088,10 +1098,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; @@ -1229,11 +1235,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; @@ -1247,9 +1261,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 23d8ba7fa..8a53ef802 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 e50103b9f..e93e5b4fe 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -137,6 +137,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) { @@ -160,7 +166,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: @@ -168,7 +174,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: @@ -455,7 +461,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]; @@ -464,12 +469,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; } @@ -694,8 +700,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 }, @@ -725,7 +731,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; @@ -734,9 +739,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]); @@ -766,7 +772,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]) {