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>
- 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))
if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
if (ipv4_is_multicast(mutable->key.daddr))
if (a[OVS_TUNNEL_ATTR_TTL])
mutable->ttl = nla_get_u8(a[OVS_TUNNEL_ATTR_TTL]);
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;
if (!a[OVS_TUNNEL_ATTR_IN_KEY]) {
mutable->key.tunnel_type |= TNL_T_KEY_MATCH;
mutable->flags |= TNL_F_IN_KEY_MATCH;
const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
const struct tnl_mutable_config *mutable = rcu_dereference_rtnl(tnl_vport->mutable);
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)))
+ /* 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;
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;
goto nla_put_failure;
if (mutable->ttl && nla_put_u8(skb, OVS_TUNNEL_ATTR_TTL, mutable->ttl))
goto nla_put_failure;
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;
/* OVS_VPORT_ATTR_OPTIONS attributes for tunnels.
*
/* 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.
* 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_*. */
*/
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. */
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. */
: OVS_VPORT_TYPE_UNSPEC);
}
: 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)
{
const char *
netdev_vport_get_netdev_type(const struct dpif_linux_vport *vport)
{
- 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:
? "ipsec_gre" : "gre");
case OVS_VPORT_TYPE_GRE64:
- 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:
? "ipsec_gre64" : "gre64");
case OVS_VPORT_TYPE_CAPWAP:
netdev_vport_get_tnl_iface(const struct netdev *netdev)
{
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
netdev_vport_get_tnl_iface(const struct netdev *netdev)
{
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
struct netdev_dev_vport *ndv;
static char name[IFNAMSIZ];
struct netdev_dev_vport *ndv;
static char name[IFNAMSIZ];
- 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;
+ }
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1])
{
static const struct nl_policy ovs_tunnel_policy[] = {
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 },
[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 },
struct smap *args)
{
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
struct smap *args)
{
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
uint32_t flags;
int error;
uint32_t flags;
int 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]);
if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
ovs_be32 saddr = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_SRC_IPV4]);
- 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]) {
if (flags & TNL_F_TTL_INHERIT) {
smap_add(args, "ttl", "inherit");
} else if (a[OVS_TUNNEL_ATTR_TTL]) {