Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c0ce9fb304871daa0dd2bf0efb1b241b9fa4a279
Commit:     c0ce9fb304871daa0dd2bf0efb1b241b9fa4a279
Parent:     32e569b7277f13c4b27bb29c761189963e49ce7a
Author:     Pavel Emelyanov <[EMAIL PROTECTED]>
AuthorDate: Sun Dec 16 13:31:14 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 14:58:10 2008 -0800

    [IPV4]: Store the net pointer on devinet's ctl tables
    
    Some handers and strategies of devinet sysctl tables need
    to know the net to propagate the ctl change to all the
    net devices.
    
    I use the (currently unused) extra2 pointer on the tables
    to get it.
    
    Holding the reference on the struct net is not possible,
    because otherwise we'll get a net->ctl_table->net circular
    dependency. But since the ctl tables are unregistered during
    the net destruction, this is safe to get it w/o additional
    protection.
    
    Signed-off-by: Pavel Emelyanov <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/ipv4/devinet.c |   29 ++++++++++++++++++-----------
 1 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 82def2c..8b2a44c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1236,12 +1236,12 @@ errout:
 
 #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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to