I stepped back a bit and re-considered. Realised I'd missed something
important.

The -ENOBUFS in devinit_ioctl() isn't the only place this error value
could be set.

If the allocation in devinet_ioctl() succeeds execution continues
through to:

                ret = inet_set_ifa(dev, ifa);
                break;

That calls:

net/ipv4/devinet.c::inet_set_ifa()
{
        struct in_device *in_dev = __in_dev_get_rtnl(dev);

        ASSERT_RTNL();

        if (!in_dev) {
                inet_free_ifa(ifa);
                return -ENOBUFS;
        }

-ENOBUFS will happen if __in_dev_get_rtnl(dev) fails.

include/linux/inetdevice.h::__in_dev_get_rtnl():

static __inline__ struct in_device *
__in_dev_get_rtnl(const struct net_device *dev)
{
        return (struct in_device*)dev->ip_ptr;
}

So if dev->ip_ptr is NULL the -ENOBUFS could be fired.

There aren't many places where this will be set. One of them is

net/ipv4/devinet.c::inetdev_init()

...
        /* Account for reference dev->ip_ptr (below) */
        in_dev_hold(in_dev);
...
        /* we can receive as soon as ip_ptr is set -- do this last */
        rcu_assign_pointer(dev->ip_ptr, in_dev);


which is only ever called from

net/ipv4/devinit.c::inetdev_event()

        if (!in_dev) {
                if (event == NETDEV_REGISTER) {
                        in_dev = inetdev_init(dev);
...
                } else if (event == NETDEV_CHANGEMTU) {
                        /* Re-enabling IP */
                        if (inetdev_valid_mtu(dev->mtu))
                                in_dev = inetdev_init(dev);

I'm wondering if this is an obscure RCU issue. Having read up on other
changes to similar code it could be that inet_set_ifa() should be:

static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
{
        struct in_device *in_dev;
        rcu_read_lock();
        in_dev = __in_dev_get_rcu(dev);

        ASSERT_RTNL();

-- 
No NET with 2.6.27: No buffer space available
https://bugs.launchpad.net/bugs/284377
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to