diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 56 |
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 | |||
480 | static 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 | ||