Message ID | 1237945752-14362-1-git-send-email-brian.haley@hp.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
Brian Haley wrote: > This is the quick and easy patch to add autoconf and > disable_ipv6 module parameters to IPv6. I don't think anything > more complicated is needed, assuming you play with the /etc > configuration files. > > For example, if you wanted to enable IPv6 just on 'lo' you > would: > > 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) > > 2. Add this to /etc/modprobe.conf: > > options ipv6 disable_ipv6=1 > > 3. Add these to /etc/sysctl.conf: > > net.ipv6.conf.all.disable_ipv6=0 > net.ipv6.conf.lo.disable_ipv6=0 This is kind of confusing. First you say, disable IPv6, then you say enable IPv6, but nothing happens. Unless you typo-ed the 'all.disable_ipv6 = 0'... Also, it looks like if someone decides to switch IPv6 back on for a particular interface, they would have to wait until the next RA to get an address. Not an optimum solution. > > # ip -6 a > 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 > inet6 ::1/128 scope host > valid_lft forever preferred_lft forever > > The wording can probably be cleaned-up a little in ipv6.txt, > comments welcome. > > > --------------------------------------------------------------- > > Add 'autoconf' and 'disable_ipv6' parameters to the IPv6 module. > > The first controls if IPv6 addresses are autoconfigured from > prefixes received in Router Advertisements. The IPv6 loopback > (::1) and link-local addresses are still configured. > > The second controls if IPv6 addresses are desired at all. No > IPv6 addresses will be added to any interfaces. > > Signed-off-by: Brian Haley <brian.haley@hp.com> > --- > Documentation/networking/ipv6.txt | 37 +++++++++++++++++++++++++++++++++++++ > include/linux/ipv6.h | 6 ++++++ > net/ipv6/addrconf.c | 12 +++++++++--- > net/ipv6/af_inet6.c | 22 +++++++++++++++++----- > 4 files changed, 69 insertions(+), 8 deletions(-) > > diff --git a/Documentation/networking/ipv6.txt b/Documentation/networking/ipv6.txt > index 268e5c1..9fd7e21 100644 > --- a/Documentation/networking/ipv6.txt > +++ b/Documentation/networking/ipv6.txt > @@ -33,3 +33,40 @@ disable > > A reboot is required to enable IPv6. > > +autoconf > + > + Specifies whether to enable IPv6 address autoconfiguration > + on all interfaces. This might be used when one does not wish > + for addresses to be automatically generated from prefixes > + received in Router Advertisements. > + > + The possible values and their effects are: > + > + 0 > + IPv6 address autoconfiguration is disabled on all interfaces. > + > + Only the IPv6 loopback address (::1) and link-local addresses > + will be added to interfaces. > + > + 1 > + IPv6 address autoconfiguration is enabled on all interfaces. > + > + This is the default value. > + > +disable_ipv6 > + > + Specifies whether to disable IPv6 on all interfaces. > + This might be used when no IPv6 addresses are desired. > + > + The possible values and their effects are: > + > + 0 > + IPv6 is enabled on all interfaces. > + > + This is the default value. > + > + 1 > + IPv6 is disabled on all interfaces. > + > + No IPv6 addresses will be added to interfaces. > + > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > index 476d946..c662efa 100644 > --- a/include/linux/ipv6.h > +++ b/include/linux/ipv6.h > @@ -169,6 +169,12 @@ struct ipv6_devconf { > __s32 accept_dad; > void *sysctl; > }; > + > +struct ipv6_params { > + __s32 disable_ipv6; > + __s32 autoconf; > +}; > +extern struct ipv6_params ipv6_defaults; > #endif > > /* index values for the variables in ipv6_devconf */ > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 8499da9..da6f01e 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -1784,6 +1784,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > __u32 prefered_lft; > int addr_type; > struct inet6_dev *in6_dev; > + struct net *net = dev_net(dev); > > pinfo = (struct prefix_info *) opt; > > @@ -1841,7 +1842,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > if (addrconf_finite_timeout(rt_expires)) > rt_expires *= HZ; > > - rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, > + rt = rt6_lookup(net, &pinfo->prefix, NULL, > dev->ifindex, 1); > > if (rt && addrconf_is_prefix_route(rt)) { > @@ -1874,11 +1875,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > > /* Try to figure out our local address for this prefix */ > > - if (pinfo->autoconf && in6_dev->cnf.autoconf) { > + if (pinfo->autoconf && in6_dev->cnf.autoconf && > + net->ipv6.devconf_all->autoconf) { > struct inet6_ifaddr * ifp; > struct in6_addr addr; > int create = 0, update_lft = 0; > - struct net *net = dev_net(dev); > > if (pinfo->prefix_len == 64) { > memcpy(&addr, &pinfo->prefix, 8); > @@ -4378,6 +4379,11 @@ static int addrconf_init_net(struct net *net) > dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); > if (dflt == NULL) > goto err_alloc_dflt; > + } else { > + /* these will be inherited by all namespaces */ > + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; > + all->disable_ipv6 = dflt->disable_ipv6 = > + ipv6_defaults.disable_ipv6; Why set 'all'? Since no interfaces are created yet, setting dflt accomplishes what you want. -vlad > } > > net->ipv6.devconf_all = all; > diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c > index fbf533c..7278dce 100644 > --- a/net/ipv6/af_inet6.c > +++ b/net/ipv6/af_inet6.c > @@ -72,9 +72,21 @@ MODULE_LICENSE("GPL"); > static struct list_head inetsw6[SOCK_MAX]; > static DEFINE_SPINLOCK(inetsw6_lock); > > -static int disable_ipv6 = 0; > -module_param_named(disable, disable_ipv6, int, 0); > -MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); > +struct ipv6_params ipv6_defaults = { > + .disable_ipv6 = 0, > + .autoconf = 1, > +}; > + > +static int disable_ipv6_mod = 0; > + > +module_param_named(disable, disable_ipv6_mod, int, 0444); > +MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); > + > +module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); > +MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); > + > +module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); > +MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); > > static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) > { > @@ -1013,7 +1025,7 @@ static int __init inet6_init(void) > for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) > INIT_LIST_HEAD(r); > > - if (disable_ipv6) { > + if (disable_ipv6_mod) { > printk(KERN_INFO > "IPv6: Loaded, but administratively disabled, " > "reboot required to enable\n"); > @@ -1202,7 +1214,7 @@ module_init(inet6_init); > > static void __exit inet6_exit(void) > { > - if (disable_ipv6) > + if (disable_ipv6_mod) > return; > > /* First of all disallow new sockets creation. */ -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 24 Mar 2009, Vlad Yasevich wrote: > Brian Haley wrote: > > This is the quick and easy patch to add autoconf and > > disable_ipv6 module parameters to IPv6. I don't think anything > > more complicated is needed, assuming you play with the /etc > > configuration files. > > > > For example, if you wanted to enable IPv6 just on 'lo' you > > would: > > > > 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) > > > > 2. Add this to /etc/modprobe.conf: > > > > options ipv6 disable_ipv6=1 > > > > 3. Add these to /etc/sysctl.conf: > > > > net.ipv6.conf.all.disable_ipv6=0 > > net.ipv6.conf.lo.disable_ipv6=0 > > This is kind of confusing. First you say, disable IPv6, then you say enable IPv6, but > nothing happens. Unless you typo-ed the 'all.disable_ipv6 = 0'... I bet that should have been "net.ipv6.conf.all.disable_ipv6=1" yes. :) > Also, it looks like if someone decides to switch IPv6 back on for a particular > interface, they would have to wait until the next RA to get an address. Not an > optimum solution. Isnt this the normal way anyways, or do new interfaces send some sort of "I'm new here, give me a prefix and router announcement, please!" normally when they go online? If so, maybe that should be done here as well. > > # ip -6 a > > 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 > > inet6 ::1/128 scope host > > valid_lft forever preferred_lft forever > > > > The wording can probably be cleaned-up a little in ipv6.txt, > > comments welcome. > > > > > > --------------------------------------------------------------- > > > > Add 'autoconf' and 'disable_ipv6' parameters to the IPv6 module. > > > > The first controls if IPv6 addresses are autoconfigured from > > prefixes received in Router Advertisements. The IPv6 loopback > > (::1) and link-local addresses are still configured. > > > > The second controls if IPv6 addresses are desired at all. No > > IPv6 addresses will be added to any interfaces. > > > > Signed-off-by: Brian Haley <brian.haley@hp.com> > > --- > > Documentation/networking/ipv6.txt | 37 +++++++++++++++++++++++++++++++++++++ > > include/linux/ipv6.h | 6 ++++++ > > net/ipv6/addrconf.c | 12 +++++++++--- > > net/ipv6/af_inet6.c | 22 +++++++++++++++++----- > > 4 files changed, 69 insertions(+), 8 deletions(-) > > > > diff --git a/Documentation/networking/ipv6.txt b/Documentation/networking/ipv6.txt > > index 268e5c1..9fd7e21 100644 > > --- a/Documentation/networking/ipv6.txt > > +++ b/Documentation/networking/ipv6.txt > > @@ -33,3 +33,40 @@ disable > > > > A reboot is required to enable IPv6. > > > > +autoconf > > + > > + Specifies whether to enable IPv6 address autoconfiguration > > + on all interfaces. This might be used when one does not wish > > + for addresses to be automatically generated from prefixes > > + received in Router Advertisements. > > + > > + The possible values and their effects are: > > + > > + 0 > > + IPv6 address autoconfiguration is disabled on all interfaces. > > + > > + Only the IPv6 loopback address (::1) and link-local addresses > > + will be added to interfaces. > > + > > + 1 > > + IPv6 address autoconfiguration is enabled on all interfaces. > > + > > + This is the default value. > > + > > +disable_ipv6 > > + > > + Specifies whether to disable IPv6 on all interfaces. > > + This might be used when no IPv6 addresses are desired. > > + > > + The possible values and their effects are: > > + > > + 0 > > + IPv6 is enabled on all interfaces. > > + > > + This is the default value. > > + > > + 1 > > + IPv6 is disabled on all interfaces. > > + > > + No IPv6 addresses will be added to interfaces. > > + > > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > > index 476d946..c662efa 100644 > > --- a/include/linux/ipv6.h > > +++ b/include/linux/ipv6.h > > @@ -169,6 +169,12 @@ struct ipv6_devconf { > > __s32 accept_dad; > > void *sysctl; > > }; > > + > > +struct ipv6_params { > > + __s32 disable_ipv6; > > + __s32 autoconf; > > +}; > > +extern struct ipv6_params ipv6_defaults; > > #endif > > > > /* index values for the variables in ipv6_devconf */ > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > > index 8499da9..da6f01e 100644 > > --- a/net/ipv6/addrconf.c > > +++ b/net/ipv6/addrconf.c > > @@ -1784,6 +1784,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > > __u32 prefered_lft; > > int addr_type; > > struct inet6_dev *in6_dev; > > + struct net *net = dev_net(dev); > > > > pinfo = (struct prefix_info *) opt; > > > > @@ -1841,7 +1842,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > > if (addrconf_finite_timeout(rt_expires)) > > rt_expires *= HZ; > > > > - rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, > > + rt = rt6_lookup(net, &pinfo->prefix, NULL, > > dev->ifindex, 1); > > > > if (rt && addrconf_is_prefix_route(rt)) { > > @@ -1874,11 +1875,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) > > > > /* Try to figure out our local address for this prefix */ > > > > - if (pinfo->autoconf && in6_dev->cnf.autoconf) { > > + if (pinfo->autoconf && in6_dev->cnf.autoconf && > > + net->ipv6.devconf_all->autoconf) { > > struct inet6_ifaddr * ifp; > > struct in6_addr addr; > > int create = 0, update_lft = 0; > > - struct net *net = dev_net(dev); > > > > if (pinfo->prefix_len == 64) { > > memcpy(&addr, &pinfo->prefix, 8); > > @@ -4378,6 +4379,11 @@ static int addrconf_init_net(struct net *net) > > dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); > > if (dflt == NULL) > > goto err_alloc_dflt; > > + } else { > > + /* these will be inherited by all namespaces */ > > + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; > > + all->disable_ipv6 = dflt->disable_ipv6 = > > + ipv6_defaults.disable_ipv6; > > Why set 'all'? Since no interfaces are created yet, setting dflt accomplishes > what you want. How do you know that no interfaces are created? The IPv6 modules might not have been loaded on boot, but at a later stage. > > } > > > > net->ipv6.devconf_all = all; > > diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c > > index fbf533c..7278dce 100644 > > --- a/net/ipv6/af_inet6.c > > +++ b/net/ipv6/af_inet6.c > > @@ -72,9 +72,21 @@ MODULE_LICENSE("GPL"); > > static struct list_head inetsw6[SOCK_MAX]; > > static DEFINE_SPINLOCK(inetsw6_lock); > > > > -static int disable_ipv6 = 0; > > -module_param_named(disable, disable_ipv6, int, 0); > > -MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); > > +struct ipv6_params ipv6_defaults = { > > + .disable_ipv6 = 0, > > + .autoconf = 1, > > +}; > > + > > +static int disable_ipv6_mod = 0; > > + > > +module_param_named(disable, disable_ipv6_mod, int, 0444); > > +MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); > > + > > +module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); > > +MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); > > + > > +module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); > > +MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); > > > > static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) > > { > > @@ -1013,7 +1025,7 @@ static int __init inet6_init(void) > > for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) > > INIT_LIST_HEAD(r); > > > > - if (disable_ipv6) { > > + if (disable_ipv6_mod) { > > printk(KERN_INFO > > "IPv6: Loaded, but administratively disabled, " > > "reboot required to enable\n"); > > @@ -1202,7 +1214,7 @@ module_init(inet6_init); > > > > static void __exit inet6_exit(void) > > { > > - if (disable_ipv6) > > + if (disable_ipv6_mod) > > return; > > > > /* First of all disallow new sockets creation. */ -- kolla -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Kolbjørn Barmen wrote: > >> Also, it looks like if someone decides to switch IPv6 back on for a particular >> interface, they would have to wait until the next RA to get an address. Not an >> optimum solution. > > Isnt this the normal way anyways, or do new interfaces send some sort of > "I'm new here, give me a prefix and router announcement, please!" normally > when they go online? If so, maybe that should be done here as well. > When the interface first comes up, it sends a Router Solicitation that triggers the RA. >>> @@ -1874,11 +1875,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) >>> >>> /* Try to figure out our local address for this prefix */ >>> >>> - if (pinfo->autoconf && in6_dev->cnf.autoconf) { >>> + if (pinfo->autoconf && in6_dev->cnf.autoconf && >>> + net->ipv6.devconf_all->autoconf) { >>> struct inet6_ifaddr * ifp; >>> struct in6_addr addr; >>> int create = 0, update_lft = 0; >>> - struct net *net = dev_net(dev); >>> >>> if (pinfo->prefix_len == 64) { >>> memcpy(&addr, &pinfo->prefix, 8); >>> @@ -4378,6 +4379,11 @@ static int addrconf_init_net(struct net *net) >>> dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); >>> if (dflt == NULL) >>> goto err_alloc_dflt; >>> + } else { >>> + /* these will be inherited by all namespaces */ >>> + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; >>> + all->disable_ipv6 = dflt->disable_ipv6 = >>> + ipv6_defaults.disable_ipv6; >> Why set 'all'? Since no interfaces are created yet, setting dflt accomplishes >> what you want. > > How do you know that no interfaces are created? The IPv6 modules might not > have been loaded on boot, but at a later stage. > Ah, but the IPv6 portions of the interface are created by the ipv6 module when it loads. At the addrconf_init_net() time, no interface are created yet. -vlad -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Oh, and another issue I just figured out this morning... Vlad Yasevich wrote: > Brian Haley wrote: >> This is the quick and easy patch to add autoconf and >> disable_ipv6 module parameters to IPv6. I don't think anything >> more complicated is needed, assuming you play with the /etc >> configuration files. >> >> For example, if you wanted to enable IPv6 just on 'lo' you >> would: >> >> 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) >> >> 2. Add this to /etc/modprobe.conf: >> >> options ipv6 disable_ipv6=1 >> >> 3. Add these to /etc/sysctl.conf: >> >> net.ipv6.conf.all.disable_ipv6=0 >> net.ipv6.conf.lo.disable_ipv6=0 > > This is kind of confusing. First you say, disable IPv6, then you say enable IPv6, but > nothing happens. Unless you typo-ed the 'all.disable_ipv6 = 0'... > > Also, it looks like if someone decides to switch IPv6 back on for a particular > interface, they would have to wait until the next RA to get an address. Not an > optimum solution. > >> # ip -6 a >> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 >> inet6 ::1/128 scope host >> valid_lft forever preferred_lft forever >> >> The wording can probably be cleaned-up a little in ipv6.txt, >> comments welcome. >> >> >> --------------------------------------------------------------- >> >> Add 'autoconf' and 'disable_ipv6' parameters to the IPv6 module. >> >> The first controls if IPv6 addresses are autoconfigured from >> prefixes received in Router Advertisements. The IPv6 loopback >> (::1) and link-local addresses are still configured. You are letting link-locals to autoconfigure, but did not correctly finish DAD, because once you set disable_ipv6, ip6_output and ipv6_rcv will drop all IPv6 packets. Then later, when you re-enable IPv6, you will not run DAD because the interface will think that it's already finished. So there is a possibility of duplicates not being detected. -vlad >> >> The second controls if IPv6 addresses are desired at all. No >> IPv6 addresses will be added to any interfaces. >> >> Signed-off-by: Brian Haley <brian.haley@hp.com> >> --- >> Documentation/networking/ipv6.txt | 37 +++++++++++++++++++++++++++++++++++++ >> include/linux/ipv6.h | 6 ++++++ >> net/ipv6/addrconf.c | 12 +++++++++--- >> net/ipv6/af_inet6.c | 22 +++++++++++++++++----- >> 4 files changed, 69 insertions(+), 8 deletions(-) >> >> diff --git a/Documentation/networking/ipv6.txt b/Documentation/networking/ipv6.txt >> index 268e5c1..9fd7e21 100644 >> --- a/Documentation/networking/ipv6.txt >> +++ b/Documentation/networking/ipv6.txt >> @@ -33,3 +33,40 @@ disable >> >> A reboot is required to enable IPv6. >> >> +autoconf >> + >> + Specifies whether to enable IPv6 address autoconfiguration >> + on all interfaces. This might be used when one does not wish >> + for addresses to be automatically generated from prefixes >> + received in Router Advertisements. >> + >> + The possible values and their effects are: >> + >> + 0 >> + IPv6 address autoconfiguration is disabled on all interfaces. >> + >> + Only the IPv6 loopback address (::1) and link-local addresses >> + will be added to interfaces. >> + >> + 1 >> + IPv6 address autoconfiguration is enabled on all interfaces. >> + >> + This is the default value. >> + >> +disable_ipv6 >> + >> + Specifies whether to disable IPv6 on all interfaces. >> + This might be used when no IPv6 addresses are desired. >> + >> + The possible values and their effects are: >> + >> + 0 >> + IPv6 is enabled on all interfaces. >> + >> + This is the default value. >> + >> + 1 >> + IPv6 is disabled on all interfaces. >> + >> + No IPv6 addresses will be added to interfaces. >> + >> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h >> index 476d946..c662efa 100644 >> --- a/include/linux/ipv6.h >> +++ b/include/linux/ipv6.h >> @@ -169,6 +169,12 @@ struct ipv6_devconf { >> __s32 accept_dad; >> void *sysctl; >> }; >> + >> +struct ipv6_params { >> + __s32 disable_ipv6; >> + __s32 autoconf; >> +}; >> +extern struct ipv6_params ipv6_defaults; >> #endif >> >> /* index values for the variables in ipv6_devconf */ >> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c >> index 8499da9..da6f01e 100644 >> --- a/net/ipv6/addrconf.c >> +++ b/net/ipv6/addrconf.c >> @@ -1784,6 +1784,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) >> __u32 prefered_lft; >> int addr_type; >> struct inet6_dev *in6_dev; >> + struct net *net = dev_net(dev); >> >> pinfo = (struct prefix_info *) opt; >> >> @@ -1841,7 +1842,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) >> if (addrconf_finite_timeout(rt_expires)) >> rt_expires *= HZ; >> >> - rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, >> + rt = rt6_lookup(net, &pinfo->prefix, NULL, >> dev->ifindex, 1); >> >> if (rt && addrconf_is_prefix_route(rt)) { >> @@ -1874,11 +1875,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) >> >> /* Try to figure out our local address for this prefix */ >> >> - if (pinfo->autoconf && in6_dev->cnf.autoconf) { >> + if (pinfo->autoconf && in6_dev->cnf.autoconf && >> + net->ipv6.devconf_all->autoconf) { >> struct inet6_ifaddr * ifp; >> struct in6_addr addr; >> int create = 0, update_lft = 0; >> - struct net *net = dev_net(dev); >> >> if (pinfo->prefix_len == 64) { >> memcpy(&addr, &pinfo->prefix, 8); >> @@ -4378,6 +4379,11 @@ static int addrconf_init_net(struct net *net) >> dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); >> if (dflt == NULL) >> goto err_alloc_dflt; >> + } else { >> + /* these will be inherited by all namespaces */ >> + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; >> + all->disable_ipv6 = dflt->disable_ipv6 = >> + ipv6_defaults.disable_ipv6; > > Why set 'all'? Since no interfaces are created yet, setting dflt accomplishes > what you want. > > -vlad > >> } >> >> net->ipv6.devconf_all = all; >> diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c >> index fbf533c..7278dce 100644 >> --- a/net/ipv6/af_inet6.c >> +++ b/net/ipv6/af_inet6.c >> @@ -72,9 +72,21 @@ MODULE_LICENSE("GPL"); >> static struct list_head inetsw6[SOCK_MAX]; >> static DEFINE_SPINLOCK(inetsw6_lock); >> >> -static int disable_ipv6 = 0; >> -module_param_named(disable, disable_ipv6, int, 0); >> -MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); >> +struct ipv6_params ipv6_defaults = { >> + .disable_ipv6 = 0, >> + .autoconf = 1, >> +}; >> + >> +static int disable_ipv6_mod = 0; >> + >> +module_param_named(disable, disable_ipv6_mod, int, 0444); >> +MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); >> + >> +module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); >> +MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); >> + >> +module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); >> +MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); >> >> static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) >> { >> @@ -1013,7 +1025,7 @@ static int __init inet6_init(void) >> for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) >> INIT_LIST_HEAD(r); >> >> - if (disable_ipv6) { >> + if (disable_ipv6_mod) { >> printk(KERN_INFO >> "IPv6: Loaded, but administratively disabled, " >> "reboot required to enable\n"); >> @@ -1202,7 +1214,7 @@ module_init(inet6_init); >> >> static void __exit inet6_exit(void) >> { >> - if (disable_ipv6) >> + if (disable_ipv6_mod) >> return; >> >> /* First of all disallow new sockets creation. */ > > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Vlad Yasevich wrote: > Brian Haley wrote: >> This is the quick and easy patch to add autoconf and >> disable_ipv6 module parameters to IPv6. I don't think anything >> more complicated is needed, assuming you play with the /etc >> configuration files. >> >> For example, if you wanted to enable IPv6 just on 'lo' you >> would: >> >> 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) >> >> 2. Add this to /etc/modprobe.conf: >> >> options ipv6 disable_ipv6=1 >> >> 3. Add these to /etc/sysctl.conf: >> >> net.ipv6.conf.all.disable_ipv6=0 >> net.ipv6.conf.lo.disable_ipv6=0 > > This is kind of confusing. First you say, disable IPv6, then you say enable IPv6, but > nothing happens. Unless you typo-ed the 'all.disable_ipv6 = 0'... Well, at least on my test system, this worked. Loading the IPv6 module with disable_ipv6=1 sets the .all and .default (and all interfaces) to disable, then sysctl turns them back on selectively. If you don't enable the .all.disable_ipv6 knob nothing will actually work - see the change in addrconf_prefix_rcv(). You still have to enable it on each interface for anything to happen. > Also, it looks like if someone decides to switch IPv6 back on for a particular > interface, they would have to wait until the next RA to get an address. Not an > optimum solution. Yes, if someone later-on enables IPv6 on an interface they'll need to ifdown/ifup. >> + } else { >> + /* these will be inherited by all namespaces */ >> + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; >> + all->disable_ipv6 = dflt->disable_ipv6 = >> + ipv6_defaults.disable_ipv6; > > Why set 'all'? Since no interfaces are created yet, setting dflt accomplishes > what you want. Yeah, that's probably not necessary, I assumed if the user passed the parameter and saw .all.foo different than .default.foo they might be confused. -Brian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Kolbjørn Barmen wrote: > On Tue, 24 Mar 2009, Vlad Yasevich wrote: > >> Brian Haley wrote: >>> This is the quick and easy patch to add autoconf and >>> disable_ipv6 module parameters to IPv6. I don't think anything >>> more complicated is needed, assuming you play with the /etc >>> configuration files. >>> >>> For example, if you wanted to enable IPv6 just on 'lo' you >>> would: >>> >>> 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) >>> >>> 2. Add this to /etc/modprobe.conf: >>> >>> options ipv6 disable_ipv6=1 >>> >>> 3. Add these to /etc/sysctl.conf: >>> >>> net.ipv6.conf.all.disable_ipv6=0 >>> net.ipv6.conf.lo.disable_ipv6=0 >> This is kind of confusing. First you say, disable IPv6, then you say enable IPv6, but >> nothing happens. Unless you typo-ed the 'all.disable_ipv6 = 0'... > > I bet that should have been "net.ipv6.conf.all.disable_ipv6=1" yes. :) No, the module parameter disabled it, but we need to re-enable the .all.disable_ipv6 knob in order for lo to be able to configure itself. If I follow Vlad's advice of only setting the .default knob then you won't have to do this. >> Also, it looks like if someone decides to switch IPv6 back on for a particular >> interface, they would have to wait until the next RA to get an address. Not an >> optimum solution. > > Isnt this the normal way anyways, or do new interfaces send some sort of > "I'm new here, give me a prefix and router announcement, please!" normally > when they go online? If so, maybe that should be done here as well. I'll see about putting in a callback to send a router solicitation. But on the flip side if someone changes eth0.disable_ipv6=0 to 1, we won't be removing the address either. An ifdown/ifup cycle would remove the need for us to do anything here. -Brian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Vlad Yasevich wrote: > Oh, and another issue I just figured out this morning... >>> Add 'autoconf' and 'disable_ipv6' parameters to the IPv6 module. >>> >>> The first controls if IPv6 addresses are autoconfigured from >>> prefixes received in Router Advertisements. The IPv6 loopback >>> (::1) and link-local addresses are still configured. > > You are letting link-locals to autoconfigure, but did not correctly > finish DAD, because once you set disable_ipv6, ip6_output and ipv6_rcv > will drop all IPv6 packets. > > Then later, when you re-enable IPv6, you will not run DAD because the > interface will think that it's already finished. > > So there is a possibility of duplicates not being detected. If you just set autoconf=0 and don't set disable_ipv6=1, then DAD will complete for the link-locals just fine. If you "disable" them both you won't get any addresses at all. So I guess your point is that if you then enable IPv6 on an interface and it gets a prefix in an RA, you'll add a global without having link-local? It almost looked like the code in addrconf_prefix_rcv() prevented that from happening (ipv6_inherit_eui64()), but it doesn't. -Brian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers, remember me? :) Regarding the autoconf parameter for the ipv6 module, was it not the intention that it should cover accept_ra as well? I ask since I have used this paramater in the belief that it also did cover accept_ra, however on a couple of systems that are using bridge interface, I noticed that they "fall off" ipv6-wise, unless I explisitly ping them. So I finally got around to find out what was going on, and to my surprise I see that they both have autoconfigured routes on eth0 (using link local) that they want to use instead of what I have statically configured for br0. So, could "autoconf" also please turn off accept_ra? Or, if you like, add another parameter for it :P I tried using disable_ipv6 in all kinds of tricky ways to get what I want, but it's close to impossble, with interfaces coming and going in the bridge I always end up with autoconfigured addresses where I dont want them, strange routing issues etc. I cannot just add entries in sysctl.conf for bridge interfaces, since the bridge interfaces (and others for that matter) are not there when sysctl is run on bootup. And the entire "all" vs. "default" still confuses me. * "default" is supposed to cover _all future_ interfaces? * "all" is supposed to cover _all existing_ interfaces, and change them? If not, then what is its function? And lastly - all this would be a non-issue if the defaults values were so that all autoconf/accept_ra were 0 - it's _so_ easy to turn on, but incredibly complicated to turn off. The harder it is to make sense out of things like this, the harder it is to have people start with IPv6. Cheers again! :) -- kolla -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Kolbjorn, Kolbjørn Barmen wrote: > Cheers, remember me? :) > > Regarding the autoconf parameter for the ipv6 module, was it not the > intention that it should cover accept_ra as well? It wasn't my intention, but I see how there's a bit of a mess here. > I ask since I have used this paramater in the belief that it also did > cover accept_ra, however on a couple of systems that are using bridge > interface, I noticed that they "fall off" ipv6-wise, unless I explisitly > ping them. > > So I finally got around to find out what was going on, and to my surprise > I see that they both have autoconfigured routes on eth0 (using link local) > that they want to use instead of what I have statically configured for br0. So I re-read RFCs 4861 and 4862 to see what the recommendation was here, and found this paragraph which I think explains what the Linux kernel is doing: [RFC 4861, Section 6.3.4] Note: Implementations can choose to process the on-link aspects of the prefixes separately from the stateless address autoconfiguration aspects of the prefixes by, e.g., passing a copy of each valid Router Advertisement message to both an "on-link" and an "addrconf" function. Each function can then operate independently on the prefixes that have the appropriate flag set. I'm guessing whoever wrote this code followed this suggestion for a reason. For a test, can you turn-off accept_ra/accept_ra_defrtr/accept_ra_pinfo and see if you can get the behavior you want? > So, could "autoconf" also please turn off accept_ra? > Or, if you like, add another parameter for it :P There are other things in the RA that are useful, like MTU, turning-off accept_ra would miss that, I think maybe ignoring the prefix info options when autoconf=0 might be what you want. I guess we could do another module parameter if we had to. > I tried using disable_ipv6 in all kinds of tricky ways to get what I want, > but it's close to impossble, with interfaces coming and going in the > bridge I always end up with autoconfigured addresses where I dont want > them, strange routing issues etc. I cannot just add entries in sysctl.conf > for bridge interfaces, since the bridge interfaces (and others for that > matter) are not there when sysctl is run on bootup. If you set "default.disable_ipv6=1" that should be inherited when a new interface is configured. > And the entire "all" vs. "default" still confuses me. > > * "default" is supposed to cover _all future_ interfaces? > * "all" is supposed to cover _all existing_ interfaces, and change them? > If not, then what is its function? Yes, "default" covers future interfaces, but "all" behavior depends on the option - "all->forwarding" and "all->disable_ipv6" will reset interfaces and "all->proxy_ndp" affects all interfaces. Other than that, the "all" variables seem not to be used. Making it more like the IPv4 code sooner than later might be a good thing, maybe others have thoughts on that? > And lastly - all this would be a non-issue if the defaults values were so > that all autoconf/accept_ra were 0 - it's _so_ easy to turn on, but > incredibly complicated to turn off. The harder it is to make sense out of > things like this, the harder it is to have people start with IPv6. I don't think that default is going to change since it would effectively disable IPv6 for 99.9% of users, my grandmother would wonder why nothing works any more and not know how to fix it :) In other words, people not doing autoconfiguration are in the minority, and might need to change all these default settings, but we should make it easier to use. Hope that helps. -Brian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, 20 Jan 2010, Brian Haley wrote: > Hi Kolbjorn, Hello, thanks for answering, and I'm sorry that I havent replied earlier. > Kolbjørn Barmen wrote: > > Cheers, remember me? :) > > > > Regarding the autoconf parameter for the ipv6 module, was it not the > > intention that it should cover accept_ra as well? > > It wasn't my intention, but I see how there's a bit of a mess here. > > > I ask since I have used this paramater in the belief that it also did > > cover accept_ra, however on a couple of systems that are using bridge > > interface, I noticed that they "fall off" ipv6-wise, unless I > > explisitly ping them. > > > > So I finally got around to find out what was going on, and to my > > surprise I see that they both have autoconfigured routes on eth0 > > (using link local) that they want to use instead of what I have > > statically configured for br0. > > So I re-read RFCs 4861 and 4862 to see what the recommendation was here, > and found this paragraph which I think explains what the Linux kernel is > doing: > > [RFC 4861, Section 6.3.4] > > Note: Implementations can choose to process the on-link aspects of > the prefixes separately from the stateless address > autoconfiguration aspects of the prefixes by, e.g., passing a copy > of each valid Router Advertisement message to both an "on-link" > and an "addrconf" function. Each function can then operate > independently on the prefixes that have the appropriate flag set. > > I'm guessing whoever wrote this code followed this suggestion for a > reason. > > For a test, can you turno-off accept_ra/accept_ra_defrtr/accept_ra_pinfo What are they, documented anywhere? > and see if you can get the behavior you want? I must admit that I havent tried using those yet, but still I somehow managed to get what I want like this: ~ # cat /etc/modprobe.d/ipv6.conf options ipv6 disable_ipv6=1 autoconf=0 ~ # cat /etc/sysctl.d/ipv6.conf net.ipv6.conf.default.autoconf=0 net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.default.disable_ipv6 = 0 net.ipv6.conf.all.autoconf=0 net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.lo.disable_ipv6=0 I'm still not convinced it really works, but it looks good so far. > > So, could "autoconf" also please turn off accept_ra? > > Or, if you like, add another parameter for it :P > > There are other things in the RA that are useful, like MTU, turning-off > accept_ra would miss that So what is one supposed to do when one wants fully statically configured IPv6 addresses and routes? Or is that not supposed to be possible? > I think maybe ignoring the prefix info options when autoconf=0 might be > what you want. I guess we could do another module parameter if we had > to. Yes - all I want is ignore prefix and router announcements, they are not to be trusted. > > I tried using disable_ipv6 in all kinds of tricky ways to get what I want, > > but it's close to impossble, with interfaces coming and going in the > > bridge I always end up with autoconfigured addresses where I dont want > > them, strange routing issues etc. I cannot just add entries in sysctl.conf > > for bridge interfaces, since the bridge interfaces (and others for that > > matter) are not there when sysctl is run on bootup. > > If you set "default.disable_ipv6=1" that should be inherited when a new > interface is configured. Right. > > And the entire "all" vs. "default" still confuses me. > > > > * "default" is supposed to cover _all future_ interfaces? > > * "all" is supposed to cover _all existing_ interfaces, and change them? > > If not, then what is its function? > > Yes, "default" covers future interfaces, but "all" behavior depends on > the option - "all->forwarding" and "all->disable_ipv6" will reset > interfaces and "all->proxy_ndp" affects all interfaces. Other than > that, the "all" variables seem not to be used. Making it more like the > IPv4 code sooner than later might be a good thing, maybe others have > thoughts on that? I'd say yes, and the sooner the better. (I've noticed the Debian has "Full IPv6 support" in their feature list for next release this summer, it would be nice to have something ready for that.) > > And lastly - all this would be a non-issue if the defaults values were so > > that all autoconf/accept_ra were 0 - it's _so_ easy to turn on, but > > incredibly complicated to turn off. The harder it is to make sense out of > > things like this, the harder it is to have people start with IPv6. > > I don't think that default is going to change since it would effectively > disable IPv6 for 99.9% of users, my grandmother would wonder why nothing works > any more and not know how to fix it :) In other words, people not doing > autoconfiguration are in the minority, and might need to change all these > default settings, but we should make it easier to use. Right, here it comes, the "most users" argument. Sorry, but I just want to rant a little over this ;) Your grandmother will be pretty fed up anyways since some random wifi stumbler with 6to4 accidently turned on, jumps on her weakly configured access point, announcing routes so that her computer now routes all traffic through the stumblers laptop, which works fine till the stumbler vanishes, leaving your grandmother's computer with lots of stalled TCP sessions and a broken default gateway. Not to mention all the timeouts she will have to wait for as her computer attempts to contact all the ipv6 addresses it resolves before finally, maybe, trying ipv4 instead. I have worked with ipv6 in "production" long enough to know that the overly optimistic view on how things are supposed to work is one of the big obstacles for deployment of IPv6, it's just too fragile... 6to4 accidently activated on a machine on the LAN? Boom! Loop between LANs as resault of accident plugging on switch? Boom! Multihomed machine accidently forwards between interfaces? Boom! And what do you do when suddenly you have heaploads of machiens with nonworking IPv6 configurations? DHCPv6 to the rescue? Or not? :) Not to mention all the IPv6 related bugs that exist in network gear like controllers and gateways/bridges (wifi, VPN, whatever). Ooops, I guess I just did. :) Cheers! -- kolla -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Kolla, Kolbjørn Barmen wrote: >> For a test, can you turno-off accept_ra/accept_ra_defrtr/accept_ra_pinfo > > What are they, documented anywhere? Documentation/networking/ip-sysctl.txt >> and see if you can get the behavior you want? > > I must admit that I havent tried using those yet, but still > I somehow managed to get what I want like this: > > ~ # cat /etc/modprobe.d/ipv6.conf > options ipv6 disable_ipv6=1 autoconf=0 > ~ # cat /etc/sysctl.d/ipv6.conf > net.ipv6.conf.default.autoconf=0 > net.ipv6.conf.default.accept_ra=0 > net.ipv6.conf.default.disable_ipv6 = 0 > net.ipv6.conf.all.autoconf=0 > net.ipv6.conf.all.accept_ra=0 > net.ipv6.conf.lo.disable_ipv6=0 > > I'm still not convinced it really works, but it looks good so far. Ok, so when the IPv6 module is loaded, it won't configure any addresses. Then you enable IPv6 on future interfaces that are added, and enable it on lo. So after this you just have an address on lo and your bridges, right? >>> So, could "autoconf" also please turn off accept_ra? >>> Or, if you like, add another parameter for it :P >> There are other things in the RA that are useful, like MTU, turning-off >> accept_ra would miss that > > So what is one supposed to do when one wants fully statically configured > IPv6 addresses and routes? Or is that not supposed to be possible? This sequence worked for me on a single interface: # sysctl net.ipv6.conf.eth0.disable_ipv6=1 # sysctl net.ipv6.conf.eth0.accept_ra_defrtr=0 # sysctl net.ipv6.conf.eth0.accept_ra_pinfo=0 # sysctl net.ipv6.conf.eth0.disable_ipv6=0 Interface now has just link-local and you can add addresses and routes as necessary. So it looks possible to modify your conf file like this: net.ipv6.conf.all.accept_ra_defrtr=0 net.ipv6.conf.all.accept_ra_pinfo=0 >> I think maybe ignoring the prefix info options when autoconf=0 might be >> what you want. I guess we could do another module parameter if we had >> to. > > Yes - all I want is ignore prefix and router announcements, they are not > to be trusted. By router announcements do you mean you don't want to make the sender the default router? >>> And the entire "all" vs. "default" still confuses me. >>> >>> * "default" is supposed to cover _all future_ interfaces? >>> * "all" is supposed to cover _all existing_ interfaces, and change them? >>> If not, then what is its function? >> Yes, "default" covers future interfaces, but "all" behavior depends on >> the option - "all->forwarding" and "all->disable_ipv6" will reset >> interfaces and "all->proxy_ndp" affects all interfaces. Other than >> that, the "all" variables seem not to be used. Making it more like the >> IPv4 code sooner than later might be a good thing, maybe others have >> thoughts on that? > > I'd say yes, and the sooner the better. > (I've noticed the Debian has "Full IPv6 support" in their feature list for > next release this summer, it would be nice to have something ready for that.) Well, I'll see what I can do... >>> And lastly - all this would be a non-issue if the defaults values were so >>> that all autoconf/accept_ra were 0 - it's _so_ easy to turn on, but >>> incredibly complicated to turn off. The harder it is to make sense out of >>> things like this, the harder it is to have people start with IPv6. >> I don't think that default is going to change since it would effectively >> disable IPv6 for 99.9% of users, my grandmother would wonder why nothing works >> any more and not know how to fix it :) In other words, people not doing >> autoconfiguration are in the minority, and might need to change all these >> default settings, but we should make it easier to use. > > Right, here it comes, the "most users" argument. > Sorry, but I just want to rant a little over this ;) > > Your grandmother will be pretty fed up anyways since some random wifi > stumbler with 6to4 accidently turned on, jumps on her weakly configured > access point, announcing routes so that her computer now routes all > traffic through the stumblers laptop, which works fine till the stumbler > vanishes, leaving your grandmother's computer with lots of stalled TCP > sessions and a broken default gateway. Not to mention all the timeouts she > will have to wait for as her computer attempts to contact all the ipv6 > addresses it resolves before finally, maybe, trying ipv4 instead. Yes, I've seen this too when someone configures their laptop to be an IPv6 router at home, and then comes into the office. We then track them down and "educate" them :) The only solution to this is SeND I believe, and that's not widely deployed at all. > I have worked with ipv6 in "production" long enough to know that the > overly optimistic view on how things are supposed to work is one of the > big obstacles for deployment of IPv6, it's just too fragile... > > 6to4 accidently activated on a machine on the LAN? Boom! > Loop between LANs as resault of accident plugging on switch? Boom! > Multihomed machine accidently forwards between interfaces? Boom! > > And what do you do when suddenly you have heaploads of machiens with > nonworking IPv6 configurations? DHCPv6 to the rescue? Or not? :) DHCPv6 is going to be widely used from what I know, as enterprises typically use DHCPv4 today, they don't want the end-user to be administering this stuff at all. -Brian -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/Documentation/networking/ipv6.txt b/Documentation/networking/ipv6.txt index 268e5c1..9fd7e21 100644 --- a/Documentation/networking/ipv6.txt +++ b/Documentation/networking/ipv6.txt @@ -33,3 +33,40 @@ disable A reboot is required to enable IPv6. +autoconf + + Specifies whether to enable IPv6 address autoconfiguration + on all interfaces. This might be used when one does not wish + for addresses to be automatically generated from prefixes + received in Router Advertisements. + + The possible values and their effects are: + + 0 + IPv6 address autoconfiguration is disabled on all interfaces. + + Only the IPv6 loopback address (::1) and link-local addresses + will be added to interfaces. + + 1 + IPv6 address autoconfiguration is enabled on all interfaces. + + This is the default value. + +disable_ipv6 + + Specifies whether to disable IPv6 on all interfaces. + This might be used when no IPv6 addresses are desired. + + The possible values and their effects are: + + 0 + IPv6 is enabled on all interfaces. + + This is the default value. + + 1 + IPv6 is disabled on all interfaces. + + No IPv6 addresses will be added to interfaces. + diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 476d946..c662efa 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -169,6 +169,12 @@ struct ipv6_devconf { __s32 accept_dad; void *sysctl; }; + +struct ipv6_params { + __s32 disable_ipv6; + __s32 autoconf; +}; +extern struct ipv6_params ipv6_defaults; #endif /* index values for the variables in ipv6_devconf */ diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8499da9..da6f01e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1784,6 +1784,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) __u32 prefered_lft; int addr_type; struct inet6_dev *in6_dev; + struct net *net = dev_net(dev); pinfo = (struct prefix_info *) opt; @@ -1841,7 +1842,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) if (addrconf_finite_timeout(rt_expires)) rt_expires *= HZ; - rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, + rt = rt6_lookup(net, &pinfo->prefix, NULL, dev->ifindex, 1); if (rt && addrconf_is_prefix_route(rt)) { @@ -1874,11 +1875,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) /* Try to figure out our local address for this prefix */ - if (pinfo->autoconf && in6_dev->cnf.autoconf) { + if (pinfo->autoconf && in6_dev->cnf.autoconf && + net->ipv6.devconf_all->autoconf) { struct inet6_ifaddr * ifp; struct in6_addr addr; int create = 0, update_lft = 0; - struct net *net = dev_net(dev); if (pinfo->prefix_len == 64) { memcpy(&addr, &pinfo->prefix, 8); @@ -4378,6 +4379,11 @@ static int addrconf_init_net(struct net *net) dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL); if (dflt == NULL) goto err_alloc_dflt; + } else { + /* these will be inherited by all namespaces */ + all->autoconf = dflt->autoconf = ipv6_defaults.autoconf; + all->disable_ipv6 = dflt->disable_ipv6 = + ipv6_defaults.disable_ipv6; } net->ipv6.devconf_all = all; diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index fbf533c..7278dce 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -72,9 +72,21 @@ MODULE_LICENSE("GPL"); static struct list_head inetsw6[SOCK_MAX]; static DEFINE_SPINLOCK(inetsw6_lock); -static int disable_ipv6 = 0; -module_param_named(disable, disable_ipv6, int, 0); -MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional"); +struct ipv6_params ipv6_defaults = { + .disable_ipv6 = 0, + .autoconf = 1, +}; + +static int disable_ipv6_mod = 0; + +module_param_named(disable, disable_ipv6_mod, int, 0444); +MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); + +module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444); +MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); + +module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); +MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) { @@ -1013,7 +1025,7 @@ static int __init inet6_init(void) for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) INIT_LIST_HEAD(r); - if (disable_ipv6) { + if (disable_ipv6_mod) { printk(KERN_INFO "IPv6: Loaded, but administratively disabled, " "reboot required to enable\n"); @@ -1202,7 +1214,7 @@ module_init(inet6_init); static void __exit inet6_exit(void) { - if (disable_ipv6) + if (disable_ipv6_mod) return; /* First of all disallow new sockets creation. */
This is the quick and easy patch to add autoconf and disable_ipv6 module parameters to IPv6. I don't think anything more complicated is needed, assuming you play with the /etc configuration files. For example, if you wanted to enable IPv6 just on 'lo' you would: 1. Add "ipv6" to /etc/modules (if you don't, step #3 might fail) 2. Add this to /etc/modprobe.conf: options ipv6 disable_ipv6=1 3. Add these to /etc/sysctl.conf: net.ipv6.conf.all.disable_ipv6=0 net.ipv6.conf.lo.disable_ipv6=0 # ip -6 a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 inet6 ::1/128 scope host valid_lft forever preferred_lft forever The wording can probably be cleaned-up a little in ipv6.txt, comments welcome. --------------------------------------------------------------- Add 'autoconf' and 'disable_ipv6' parameters to the IPv6 module. The first controls if IPv6 addresses are autoconfigured from prefixes received in Router Advertisements. The IPv6 loopback (::1) and link-local addresses are still configured. The second controls if IPv6 addresses are desired at all. No IPv6 addresses will be added to any interfaces. Signed-off-by: Brian Haley <brian.haley@hp.com> --- Documentation/networking/ipv6.txt | 37 +++++++++++++++++++++++++++++++++++++ include/linux/ipv6.h | 6 ++++++ net/ipv6/addrconf.c | 12 +++++++++--- net/ipv6/af_inet6.c | 22 +++++++++++++++++----- 4 files changed, 69 insertions(+), 8 deletions(-)