aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-12-05 04:50:24 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:56:32 -0500
commitc8fecf2242a0ab7230210665986b8ef915e1ae9e (patch)
treeb8255d6a621cc64042a22f1edd9019aba1914d9f /net/ipv6/addrconf.c
parent68dd299bc84dede6aef32e6f4777a676314f5d21 (diff)
[IPV6]: Eliminate difference in actions of sysctl and proc handler for conf.all.forwarding
The only difference in this case is that updating all.forwarding causes the update in default.forwarding when done via proc, but not via the system call. Besides, this consolidates a good portion of code. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c56
1 files changed, 20 insertions, 36 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index dbff389b7003..95cf3aa41c98 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -476,6 +476,21 @@ static void addrconf_forward_change(void)
476 } 476 }
477 read_unlock(&dev_base_lock); 477 read_unlock(&dev_base_lock);
478} 478}
479
480static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
481{
482 if (p == &ipv6_devconf_dflt.forwarding)
483 return;
484
485 if (p == &ipv6_devconf.forwarding) {
486 ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
487 addrconf_forward_change();
488 } else if ((!*p) ^ (!old))
489 dev_forward_change((struct inet6_dev *)table->extra1);
490
491 if (*p)
492 rt6_purge_dflt_routers();
493}
479#endif 494#endif
480 495
481/* Nobody refers to this ifaddr, destroy it */ 496/* Nobody refers to this ifaddr, destroy it */
@@ -3771,22 +3786,8 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
3771 3786
3772 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 3787 ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
3773 3788
3774 if (write && valp != &ipv6_devconf_dflt.forwarding) { 3789 if (write)
3775 if (valp != &ipv6_devconf.forwarding) { 3790 addrconf_fixup_forwarding(ctl, valp, val);
3776 if ((!*valp) ^ (!val)) {
3777 struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
3778 if (idev == NULL)
3779 return ret;
3780 dev_forward_change(idev);
3781 }
3782 } else {
3783 ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
3784 addrconf_forward_change();
3785 }
3786 if (*valp)
3787 rt6_purge_dflt_routers();
3788 }
3789
3790 return ret; 3791 return ret;
3791} 3792}
3792 3793
@@ -3797,6 +3798,7 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
3797 void __user *newval, size_t newlen) 3798 void __user *newval, size_t newlen)
3798{ 3799{
3799 int *valp = table->data; 3800 int *valp = table->data;
3801 int val = *valp;
3800 int new; 3802 int new;
3801 3803
3802 if (!newval || !newlen) 3804 if (!newval || !newlen)
@@ -3821,26 +3823,8 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
3821 } 3823 }
3822 } 3824 }
3823 3825
3824 if (valp != &ipv6_devconf_dflt.forwarding) { 3826 *valp = new;
3825 if (valp != &ipv6_devconf.forwarding) { 3827 addrconf_fixup_forwarding(table, valp, val);
3826 struct inet6_dev *idev = (struct inet6_dev *)table->extra1;
3827 int changed;
3828 if (unlikely(idev == NULL))
3829 return -ENODEV;
3830 changed = (!*valp) ^ (!new);
3831 *valp = new;
3832 if (changed)
3833 dev_forward_change(idev);
3834 } else {
3835 *valp = new;
3836 addrconf_forward_change();
3837 }
3838
3839 if (*valp)
3840 rt6_purge_dflt_routers();
3841 } else
3842 *valp = new;
3843
3844 return 1; 3828 return 1;
3845} 3829}
3846 3830