diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 82def2c1c65050db75ea0a7163d00d0bfa72582c..8b2a44c4f82a17a45fa81e86031691169073c6a1 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1236,12 +1236,12 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh, #ifdef CONFIG_SYSCTL -static void devinet_copy_dflt_conf(int i) +static void devinet_copy_dflt_conf(struct net *net, int i) { struct net_device *dev; read_lock(&dev_base_lock); - for_each_netdev(&init_net, dev) { + for_each_netdev(net, dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); @@ -1252,7 +1252,7 @@ static void devinet_copy_dflt_conf(int i) read_unlock(&dev_base_lock); } -static void inet_forward_change(void) +static void inet_forward_change(struct net *net) { struct net_device *dev; int on = IPV4_DEVCONF_ALL(FORWARDING); @@ -1261,7 +1261,7 @@ static void inet_forward_change(void) IPV4_DEVCONF_DFLT(FORWARDING) = on; read_lock(&dev_base_lock); - for_each_netdev(&init_net, dev) { + for_each_netdev(net, dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); @@ -1282,12 +1282,13 @@ static int devinet_conf_proc(ctl_table *ctl, int write, if (write) { struct ipv4_devconf *cnf = ctl->extra1; + struct net *net = ctl->extra2; int i = (int *)ctl->data - cnf->data; set_bit(i, cnf->state); if (cnf == &ipv4_devconf_dflt) - devinet_copy_dflt_conf(i); + devinet_copy_dflt_conf(net, i); } return ret; @@ -1298,6 +1299,7 @@ static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen, void __user *newval, size_t newlen) { struct ipv4_devconf *cnf; + struct net *net; int *valp = table->data; int new; int i; @@ -1333,12 +1335,13 @@ static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen, *valp = new; cnf = table->extra1; + net = table->extra2; i = (int *)table->data - cnf->data; set_bit(i, cnf->state); if (cnf == &ipv4_devconf_dflt) - devinet_copy_dflt_conf(i); + devinet_copy_dflt_conf(net, i); return 1; } @@ -1352,8 +1355,10 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); if (write && *valp != val) { + struct net *net = ctl->extra2; + if (valp == &IPV4_DEVCONF_ALL(FORWARDING)) - inet_forward_change(); + inet_forward_change(net); else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING)) rt_cache_flush(0); } @@ -1477,6 +1482,7 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name, for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; t->devinet_vars[i].extra1 = p; + t->devinet_vars[i].extra2 = net; } /* @@ -1524,8 +1530,8 @@ static void devinet_sysctl_register(struct in_device *idev) { neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4", NULL, NULL); - __devinet_sysctl_register(idev->dev->name, idev->dev->ifindex, - &idev->cnf); + __devinet_sysctl_register(idev->dev->nd_net, idev->dev->name, + idev->dev->ifindex, &idev->cnf); } static void devinet_sysctl_unregister(struct in_device *idev) @@ -1546,6 +1552,7 @@ static struct ctl_table ctl_forward_entry[] = { .proc_handler = devinet_sysctl_forward, .strategy = devinet_conf_sysctl, .extra1 = &ipv4_devconf, + .extra2 = &init_net, }, { }, }; @@ -1565,9 +1572,9 @@ void __init devinet_init(void) rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); #ifdef CONFIG_SYSCTL - __devinet_sysctl_register("all", NET_PROTO_CONF_ALL, + __devinet_sysctl_register(&init_net, "all", NET_PROTO_CONF_ALL, &ipv4_devconf); - __devinet_sysctl_register("default", NET_PROTO_CONF_DEFAULT, + __devinet_sysctl_register(&init_net, "default", NET_PROTO_CONF_DEFAULT, &ipv4_devconf_dflt); register_sysctl_paths(net_ipv4_path, ctl_forward_entry); #endif