From 6dd3c9ec2387725a8e529fae64415cd538b955b7 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 14 Feb 2014 13:14:39 +0100 Subject: [PATCH] ip_tunnel: return more precise errno value when adding tunnel fails Currently this always returns ENOBUFS, because the return value of __ip_tunnel_create is discarded. A more common failure is a duplicate name (EEXIST). Propagate the real error code so userspace can display a more meaningful error message. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv4/ip_tunnel.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 3400d737adc6..6d430ff2ba29 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -443,7 +443,7 @@ static struct ip_tunnel *ip_tunnel_create(struct net *net, fbt = netdev_priv(itn->fb_tunnel_dev); dev = __ip_tunnel_create(net, itn->fb_tunnel_dev->rtnl_link_ops, parms); if (IS_ERR(dev)) - return NULL; + return ERR_CAST(dev); dev->mtu = ip_tunnel_bind_dev(dev); @@ -796,9 +796,13 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); - if (!t && (cmd == SIOCADDTUNNEL)) + if (!t && (cmd == SIOCADDTUNNEL)) { t = ip_tunnel_create(net, itn, p); - + if (IS_ERR(t)) { + err = PTR_ERR(t); + break; + } + } if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { if (t != NULL) { if (t->dev != dev) { @@ -825,8 +829,9 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) if (t) { err = 0; ip_tunnel_update(itn, t, dev, p, true); - } else - err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); + } else { + err = -ENOENT; + } break; case SIOCDELTUNNEL: -- 2.20.1