/*
* Confirm that local IP address exists using wildcards:
- * - dev: only on this interface, 0=any interface
+ * - 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(const struct net_device *dev, __be32 dst, __be32 local, int scope)
+__be32 inet_confirm_addr(struct in_device *in_dev,
+ __be32 dst, __be32 local, int scope)
{
__be32 addr = 0;
- struct in_device *in_dev;
+ struct net_device *dev;
+ struct net *net;
- 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;
- }
+ if (scope != RT_SCOPE_LINK)
+ return confirm_addr_indev(in_dev, dst, local, scope);
+ net = in_dev->dev->nd_net;
read_lock(&dev_base_lock);
rcu_read_lock();
- for_each_netdev(&init_net, dev) {
+ for_each_netdev(net, dev) {
if ((in_dev = __in_dev_get_rcu(dev))) {
addr = confirm_addr_indev(in_dev, dst, local, scope);
if (addr)
__devinet_sysctl_unregister(&idev->cnf);
neigh_sysctl_unregister(idev->arp_parms);
}
-#endif
static struct ctl_table ctl_forward_entry[] = {
{
{ .procname = "ipv4", .ctl_name = NET_IPV4, },
{ },
};
+#endif
static __net_init int devinet_init_net(struct net *net)
{
int err;
- struct ctl_table *tbl;
struct ipv4_devconf *all, *dflt;
+#ifdef CONFIG_SYSCTL
+ struct ctl_table *tbl = ctl_forward_entry;
struct ctl_table_header *forw_hdr;
+#endif
err = -ENOMEM;
all = &ipv4_devconf;
dflt = &ipv4_devconf_dflt;
- tbl = ctl_forward_entry;
if (net != &init_net) {
all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
if (dflt == NULL)
goto err_alloc_dflt;
+#ifdef CONFIG_SYSCTL
tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL);
if (tbl == NULL)
goto err_alloc_ctl;
tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1];
tbl[0].extra1 = all;
tbl[0].extra2 = net;
+#endif
}
#ifdef CONFIG_SYSCTL
forw_hdr = register_net_sysctl_table(net, net_ipv4_path, tbl);
if (forw_hdr == NULL)
goto err_reg_ctl;
+ net->ipv4.forw_hdr = forw_hdr;
#endif
- net->ipv4.forw_hdr = forw_hdr;
net->ipv4.devconf_all = all;
net->ipv4.devconf_dflt = dflt;
return 0;
err_reg_all:
if (tbl != ctl_forward_entry)
kfree(tbl);
-#endif
err_alloc_ctl:
+#endif
if (dflt != &ipv4_devconf_dflt)
kfree(dflt);
err_alloc_dflt:
static __net_exit void devinet_exit_net(struct net *net)
{
+#ifdef CONFIG_SYSCTL
struct ctl_table *tbl;
tbl = net->ipv4.forw_hdr->ctl_table_arg;
-#ifdef CONFIG_SYSCTL
unregister_net_sysctl_table(net->ipv4.forw_hdr);
__devinet_sysctl_unregister(net->ipv4.devconf_dflt);
__devinet_sysctl_unregister(net->ipv4.devconf_all);
-#endif
kfree(tbl);
+#endif
kfree(net->ipv4.devconf_dflt);
kfree(net->ipv4.devconf_all);
}