ip_tunnel: return more precise errno value when adding tunnel fails
authorFlorian Westphal <fw@strlen.de>
Fri, 14 Feb 2014 12:14:39 +0000 (13:14 +0100)
committerDavid S. Miller <davem@davemloft.net>
Mon, 17 Feb 2014 05:07:09 +0000 (00:07 -0500)
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 <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_tunnel.c

index 3400d73..6d430ff 100644 (file)
@@ -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: