/* * Confirm that local IP address exists using wildcards: * - dev: only on this interface, 0=any interface * - dst: only in the same subnet as dst, 0=any dst * - local: address, 0=autoselect the local address * - scope: maximum allowed scope value for the local address */ __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope) { __be32 addr = 0; struct in_device *in_dev; if (dev) { rcu_read_lock(); if ((in_dev = __in_dev_get_rcu(dev))) addr = confirm_addr_indev(in_dev, dst, local, scope); rcu_read_unlock(); return addr; } read_lock(&dev_base_lock); rcu_read_lock(); for (dev = dev_base; dev; dev = dev->next) { if ((in_dev = __in_dev_get_rcu(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) break; } } rcu_read_unlock(); read_unlock(&dev_base_lock); return addr; }
/* * Confirm that local IP address exists using wildcards: * - in_dev: only on this interface, 0=any interface * - dst: only in the same subnet as dst, 0=any dst * - local: address, 0=autoselect the local address * - scope: maximum allowed scope value for the local address */ __be32 inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope) { __be32 addr = 0; struct net_device *dev; struct net *net; if (scope != RT_SCOPE_LINK) return confirm_addr_indev(in_dev, dst, local, scope); net = dev_net(in_dev->dev); read_lock(&dev_base_lock); rcu_read_lock(); for_each_netdev(net, dev) { if ((in_dev = __in_dev_get_rcu(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) break; } } rcu_read_unlock(); read_unlock(&dev_base_lock); return addr; }
/* * Confirm that local IP address exists using wildcards: * - dev: only on this interface, 0=any interface * - dst: only in the same subnet as dst, 0=any dst * - local: address, 0=autoselect the local address * - scope: maximum allowed scope value for the local address */ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope) { u32 addr = 0; struct in_device *in_dev; if (dev) { read_lock(&inetdev_lock); if ((in_dev = __in_dev_get(dev))) { read_lock(&in_dev->lock); addr = confirm_addr_indev(in_dev, dst, local, scope); read_unlock(&in_dev->lock); } read_unlock(&inetdev_lock); return addr; } read_lock(&dev_base_lock); read_lock(&inetdev_lock); for (dev = dev_base; dev; dev = dev->next) { if ((in_dev = __in_dev_get(dev))) { read_lock(&in_dev->lock); addr = confirm_addr_indev(in_dev, dst, local, scope); read_unlock(&in_dev->lock); if (addr) break; } } read_unlock(&inetdev_lock); read_unlock(&dev_base_lock); return addr; }