summaryrefslogtreecommitdiff
path: root/lib/netdev-vport.c
diff options
context:
space:
mode:
authorDaniele Di Proietto <diproiettod@vmware.com>2016-12-20 17:58:14 -0800
committerDaniele Di Proietto <diproiettod@vmware.com>2017-01-11 18:29:39 -0800
commit9fff138ec3a6dbe75073d16cba7fbe86ac273c36 (patch)
tree641387779a4ad2a35a429d4a47c8c0f99e254f5d /lib/netdev-vport.c
parentbd4e172b287c76bf9fea0a5afa751dc3fe37e2d4 (diff)
downloadopenvswitch-9fff138ec3a6dbe75073d16cba7fbe86ac273c36.tar.gz
netdev: Add 'errp' to set_config().
Since 55e075e65ef9("netdev-dpdk: Arbitrary 'dpdk' port naming"), set_config() is used to identify a DPDK device, so it's better to report its detailed error message to the user. Tunnel devices and patch ports rely a lot on set_config() as well. This commit adds a param to set_config() that can be used to return an error message and makes use of that in netdev-dpdk and netdev-vport. Before this patch: $ ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk ovs-vsctl: Error detected while setting up 'dpdk0': dpdk0: could not set configuration (Invalid argument). See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". $ ovs-vsctl add-port br0 p+ -- set Interface p+ type=patch ovs-vsctl: Error detected while setting up 'p+': p+: could not set configuration (Invalid argument). See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". $ ovs-vsctl add-port br0 gnv0 -- set Interface gnv0 type=geneve ovs-vsctl: Error detected while setting up 'gnv0': gnv0: could not set configuration (Invalid argument). See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". After this patch: $ ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk ovs-vsctl: Error detected while setting up 'dpdk0': 'dpdk0' is missing 'options:dpdk-devargs'. The old 'dpdk<port_id>' names are not supported. See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". $ ovs-vsctl add-port br0 p+ -- set Interface p+ type=patch ovs-vsctl: Error detected while setting up 'p+': p+: patch type requires valid 'peer' argument. See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". $ ovs-vsctl add-port br0 gnv0 -- set Interface gnv0 type=geneve ovs-vsctl: Error detected while setting up 'gnv0': gnv0: geneve type requires valid 'remote_ip' argument. See ovs-vswitchd log for details. ovs-vsctl: The default log directory is "/var/log/openvswitch/". CC: Ciara Loftus <ciara.loftus@intel.com> CC: Kevin Traynor <ktraynor@redhat.com> Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com> Acked-by: Kevin Traynor <ktraynor@redhat.com> Tested-by: Ciara Loftus <ciara.loftus@intel.com>
Diffstat (limited to 'lib/netdev-vport.c')
-rw-r--r--lib/netdev-vport.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index 02a246aff..ad5ffcc81 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -35,6 +35,7 @@
#include "netdev-native-tnl.h"
#include "netdev-provider.h"
#include "netdev-vport-private.h"
+#include "openvswitch/dynamic-string.h"
#include "ovs-router.h"
#include "packets.h"
#include "poll-loop.h"
@@ -397,15 +398,17 @@ parse_tunnel_ip(const char *value, bool accept_mcast, bool *flow,
}
static int
-set_tunnel_config(struct netdev *dev_, const struct smap *args)
+set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp)
{
struct netdev_vport *dev = netdev_vport_cast(dev_);
const char *name = netdev_get_name(dev_);
const char *type = netdev_get_type(dev_);
+ struct ds errors = DS_EMPTY_INITIALIZER;
bool needs_dst_port, has_csum;
uint16_t dst_proto = 0, src_proto = 0;
struct netdev_tunnel_config tnl_cfg;
struct smap_node *node;
+ int err;
has_csum = strstr(type, "gre") || strstr(type, "geneve") ||
strstr(type, "stt") || strstr(type, "vxlan");
@@ -433,25 +436,24 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
SMAP_FOR_EACH (node, args) {
if (!strcmp(node->key, "remote_ip")) {
- int err;
err = parse_tunnel_ip(node->value, false, &tnl_cfg.ip_dst_flow,
&tnl_cfg.ipv6_dst, &dst_proto);
switch (err) {
case ENOENT:
- VLOG_WARN("%s: bad %s 'remote_ip'", name, type);
+ ds_put_format(&errors, "%s: bad %s 'remote_ip'\n", name, type);
break;
case EINVAL:
- VLOG_WARN("%s: multicast remote_ip=%s not allowed",
- name, node->value);
- return EINVAL;
+ ds_put_format(&errors,
+ "%s: multicast remote_ip=%s not allowed\n",
+ name, node->value);
+ goto out;
}
} else if (!strcmp(node->key, "local_ip")) {
- int err;
err = parse_tunnel_ip(node->value, true, &tnl_cfg.ip_src_flow,
&tnl_cfg.ipv6_src, &src_proto);
switch (err) {
case ENOENT:
- VLOG_WARN("%s: bad %s 'local_ip'", name, type);
+ ds_put_format(&errors, "%s: bad %s 'local_ip'\n", name, type);
break;
}
} else if (!strcmp(node->key, "tos")) {
@@ -464,7 +466,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
if (*endptr == '\0' && tos == (tos & IP_DSCP_MASK)) {
tnl_cfg.tos = tos;
} else {
- VLOG_WARN("%s: invalid TOS %s", name, node->value);
+ ds_put_format(&errors, "%s: invalid TOS %s\n", name,
+ node->value);
}
}
} else if (!strcmp(node->key, "ttl")) {
@@ -498,7 +501,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) {
tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP);
} else {
- VLOG_WARN("%s: unknown extension '%s'", name, ext);
+ ds_put_format(&errors, "%s: unknown extension '%s'\n",
+ name, ext);
}
ext = strtok_r(NULL, ",", &save_ptr);
@@ -506,24 +510,33 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
free(str);
} else {
- VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key);
+ ds_put_format(&errors, "%s: unknown %s argument '%s'\n",
+ name, type, node->key);
}
}
if (!ipv6_addr_is_set(&tnl_cfg.ipv6_dst) && !tnl_cfg.ip_dst_flow) {
- VLOG_ERR("%s: %s type requires valid 'remote_ip' argument",
- name, type);
- return EINVAL;
+ ds_put_format(&errors,
+ "%s: %s type requires valid 'remote_ip' argument\n",
+ name, type);
+ err = EINVAL;
+ goto out;
}
if (tnl_cfg.ip_src_flow && !tnl_cfg.ip_dst_flow) {
- VLOG_ERR("%s: %s type requires 'remote_ip=flow' with 'local_ip=flow'",
- name, type);
- return EINVAL;
+ ds_put_format(&errors,
+ "%s: %s type requires 'remote_ip=flow' "
+ "with 'local_ip=flow'\n",
+ name, type);
+ err = EINVAL;
+ goto out;
}
if (src_proto && dst_proto && src_proto != dst_proto) {
- VLOG_ERR("%s: 'remote_ip' and 'local_ip' has to be of the same address family",
- name);
- return EINVAL;
+ ds_put_format(&errors,
+ "%s: 'remote_ip' and 'local_ip' "
+ "has to be of the same address family\n",
+ name);
+ err = EINVAL;
+ goto out;
}
if (!tnl_cfg.ttl) {
tnl_cfg.ttl = DEFAULT_TTL;
@@ -545,7 +558,18 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
}
ovs_mutex_unlock(&dev->mutex);
- return 0;
+ err = 0;
+
+out:
+ ds_chomp(&errors, '\n');
+ VLOG_WARN("%s", ds_cstr(&errors));
+ if (err) {
+ *errp = ds_steal_cstr(&errors);
+ }
+
+ ds_destroy(&errors);
+
+ return err;
}
static int
@@ -693,7 +717,7 @@ get_patch_config(const struct netdev *dev_, struct smap *args)
}
static int
-set_patch_config(struct netdev *dev_, const struct smap *args)
+set_patch_config(struct netdev *dev_, const struct smap *args, char **errp)
{
struct netdev_vport *dev = netdev_vport_cast(dev_);
const char *name = netdev_get_name(dev_);
@@ -701,17 +725,19 @@ set_patch_config(struct netdev *dev_, const struct smap *args)
peer = smap_get(args, "peer");
if (!peer) {
- VLOG_ERR("%s: patch type requires valid 'peer' argument", name);
+ VLOG_ERR_BUF(errp, "%s: patch type requires valid 'peer' argument",
+ name);
return EINVAL;
}
if (smap_count(args) > 1) {
- VLOG_ERR("%s: patch type takes only a 'peer' argument", name);
+ VLOG_ERR_BUF(errp, "%s: patch type takes only a 'peer' argument",
+ name);
return EINVAL;
}
if (!strcmp(name, peer)) {
- VLOG_ERR("%s: patch peer must not be self", name);
+ VLOG_ERR_BUF(errp, "%s: patch peer must not be self", name);
return EINVAL;
}