/*
- * Copyright (c) 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
size_t options_len,
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1]);
-static const char *netdev_vport_get_tnl_iface(const struct netdev *netdev);
-
static bool
is_vport_class(const struct netdev_class *class)
{
return CONTAINER_OF(netdev_dev, struct netdev_dev_vport, netdev_dev);
}
+static struct netdev_dev_vport *
+netdev_vport_get_dev(const struct netdev *netdev)
+{
+ return netdev_dev_vport_cast(netdev_get_dev(netdev));
+}
+
static struct netdev_vport *
netdev_vport_cast(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)
{
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:
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:
}
static int
-netdev_vport_get_drv_info(const struct netdev *netdev, struct smap *smap)
+tunnel_get_status(const struct netdev *netdev, struct smap *smap)
{
- const char *iface = netdev_vport_get_tnl_iface(netdev);
+ struct netdev_dev_vport *ndv = netdev_vport_get_dev(netdev);
+ struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
+ static char iface[IFNAMSIZ];
+ ovs_be32 route;
+
+ if (!ndv->options) {
+ /* Race condition when 'ndv' was created, but did not have it's
+ * configuration set yet. */
+ return 0;
+ }
+
+ if (tnl_port_config_from_nlattr(ndv->options->data,
+ ndv->options->size, a)) {
+ return 0;
+ }
+ route = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
- if (iface) {
+ if (route_table_get_name(route, iface)) {
struct netdev *egress_netdev;
smap_add(smap, "tunnel_egress_iface", iface);
static unsigned int
netdev_vport_change_seq(const struct netdev *netdev)
{
- return netdev_dev_vport_cast(netdev_get_dev(netdev))->change_seq;
+ return netdev_vport_get_dev(netdev)->change_seq;
}
static void
route_table_wait();
}
\f
-/* get_tnl_iface() implementation. */
-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];
-
- ndv = netdev_dev_vport_cast(netdev_get_dev(netdev));
- if (tnl_port_config_from_nlattr(ndv->options->data, ndv->options->size,
- a)) {
- return NULL;
- }
- route = nl_attr_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
-
- if (route_table_get_name(route, name)) {
- return name;
- }
-
- return NULL;
-}
-\f
/* Helper functions. */
static void
netdev_vport_poll_notify(const struct netdev *netdev)
{
- struct netdev_dev_vport *ndv;
-
- ndv = netdev_dev_vport_cast(netdev_get_dev(netdev));
+ struct netdev_dev_vport *ndv = netdev_vport_get_dev(netdev);
ndv->change_seq++;
if (!ndv->change_seq) {
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 },
struct smap *args)
{
struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1];
- ovs_be32 daddr;
uint32_t flags;
int error;
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]);
}
}
- 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]) {
{
static const struct vport_class vport_classes[] = {
{ OVS_VPORT_TYPE_GRE,
- { "gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "gre", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_GRE,
- { "ipsec_gre", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "ipsec_gre", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_GRE64,
- { "gre64", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "gre64", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_GRE64,
- { "ipsec_gre64", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "ipsec_gre64", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_CAPWAP,
- { "capwap", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "capwap", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_VXLAN,
- { "vxlan", VPORT_FUNCTIONS(netdev_vport_get_drv_info) },
+ { "vxlan", VPORT_FUNCTIONS(tunnel_get_status) },
parse_tunnel_config, unparse_tunnel_config },
{ OVS_VPORT_TYPE_PATCH,