]> git.hungrycats.org Git - linux/commitdiff
[IPV6]: Allow per-device max addresses configurable via sysctl.
authorHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Thu, 15 Jan 2004 06:15:23 +0000 (22:15 -0800)
committerDavid S. Miller <davem@nuts.ninka.net>
Thu, 15 Jan 2004 06:15:23 +0000 (22:15 -0800)
Documentation/networking/ip-sysctl.txt
include/linux/ipv6.h
include/linux/sysctl.h
include/net/addrconf.h
net/ipv6/addrconf.c

index 030a5b67313a2a47eb76631286cb816d4bee26e0..f2b360b5ef0e4be922cf73f1f1f361be5cf9c008 100644 (file)
@@ -667,6 +667,13 @@ regen_max_retry - INTEGER
        valid temporary addresses.
        Default: 5
 
+max_addresses - INTEGER
+       Number of maximum addresses per interface.  0 disables limitation.
+       It is recommended not set too large value (or 0) because it would 
+       be too easy way to crash kernel to allow to create too much of 
+       autoconfigured addresses.
+       Default: 16
+
 icmp/*:
 ratelimit - INTEGER
        Limit the maximal rates for sending ICMPv6 packets.
index 7f5a5c4280f75452a2802728d2e4dd2fd60cf460..e073162776fa92c01bd0398e4053afabc7d3786e 100644 (file)
@@ -143,6 +143,7 @@ struct ipv6_devconf {
        __s32           regen_max_retry;
        __s32           max_desync_factor;
 #endif
+       __s32           max_addresses;
        void            *sysctl;
 };
 
@@ -165,6 +166,7 @@ enum {
        DEVCONF_REGEN_MAX_RETRY,
        DEVCONF_MAX_DESYNC_FACTOR,
 #endif
+       DEVCONF_MAX_ADDRESSES,
        DEVCONF_MAX
 };
 
index c94fb1d1862a71365f9bb99fb6bba8354d58c9ea..de7b8b5bc523f26e882ed6e11eeaba70aa0aa88e 100644 (file)
@@ -418,7 +418,8 @@ enum {
        NET_IPV6_TEMP_VALID_LFT=12,
        NET_IPV6_TEMP_PREFERED_LFT=13,
        NET_IPV6_REGEN_MAX_RETRY=14,
-       NET_IPV6_MAX_DESYNC_FACTOR=15
+       NET_IPV6_MAX_DESYNC_FACTOR=15,
+       NET_IPV6_MAX_ADDRESSES=16
 };
 
 /* /proc/sys/net/ipv6/icmp */
index 54fd7773f5b15e9fab75d1313e415e348fd72fd8..92cbb7794cac926ad2dd47e3d8810392f3a55a21 100644 (file)
@@ -15,6 +15,8 @@
 
 #define ADDR_CHECK_FREQUENCY           (120*HZ)
 
+#define IPV6_MAX_ADDRESSES             16
+
 struct prefix_info {
        __u8                    type;
        __u8                    length;
index 6f1dc6fba0a48fd21afe587d5d0f6adf583cc7b5..d20f6647bc70d7a81b0a63eea0002d7b41fd31b1 100644 (file)
@@ -81,8 +81,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-#define IPV6_MAX_ADDRESSES 16
-
 /* Set to 3 to get tracing... */
 #define ACONF_DEBUG 2
 
@@ -162,6 +160,7 @@ struct ipv6_devconf ipv6_devconf = {
        .regen_max_retry        = REGEN_MAX_RETRY,
        .max_desync_factor      = MAX_DESYNC_FACTOR,
 #endif
+       .max_addresses          = IPV6_MAX_ADDRESSES,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt = {
@@ -182,6 +181,7 @@ static struct ipv6_devconf ipv6_devconf_dflt = {
        .regen_max_retry        = REGEN_MAX_RETRY,
        .max_desync_factor      = MAX_DESYNC_FACTOR,
 #endif
+       .max_addresses          = IPV6_MAX_ADDRESSES,
 };
 
 /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -633,6 +633,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
        unsigned long tmp_prefered_lft, tmp_valid_lft;
        int tmp_plen;
        int ret = 0;
+       int max_addresses;
 
        if (ift) {
                spin_lock_bh(&ift->lock);
@@ -688,9 +689,11 @@ retry:
                                 ifp->prefered_lft, 
                                 idev->cnf.temp_prefered_lft - desync_factor / HZ);
        tmp_plen = ifp->prefix_len;
+       max_addresses = idev->cnf.max_addresses;
        write_unlock(&idev->lock);
        spin_unlock_bh(&ifp->lock);
-       ift = ipv6_count_addresses(idev) < IPV6_MAX_ADDRESSES ?
+       ift = !max_addresses ||
+             ipv6_count_addresses(idev) < max_addresses ? 
                ipv6_add_addr(idev, &addr, tmp_plen,
                              ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : 0;
        if (!ift || IS_ERR(ift)) {
@@ -1393,10 +1396,13 @@ ok:
                ifp = ipv6_get_ifaddr(&addr, dev);
 
                if (ifp == NULL && valid_lft) {
+                       int max_addresses = in6_dev->cnf.max_addresses;
+
                        /* Do not allow to create too much of autoconfigured
                         * addresses; this would be too easy way to crash kernel.
                         */
-                       if (ipv6_count_addresses(in6_dev) < IPV6_MAX_ADDRESSES)
+                       if (!max_addresses ||
+                           ipv6_count_addresses(in6_dev) < max_addresses)
                                ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
                                                    addr_type&IPV6_ADDR_SCOPE_MASK, 0);
 
@@ -2740,6 +2746,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
        array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry;
        array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
 #endif
+       array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
 }
 
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
@@ -3165,6 +3172,14 @@ static struct addrconf_sysctl_table
                        .proc_handler   =       &proc_dointvec,
                },
 #endif
+               {
+                       .ctl_name       =       NET_IPV6_MAX_ADDRESSES,
+                       .procname       =       "max_addresses",
+                       .data           =       &ipv6_devconf.max_addresses,
+                       .maxlen         =       sizeof(int),
+                       .mode           =       0644,
+                       .proc_handler   =       &proc_dointvec,
+               },
        },
        .addrconf_dev = {
                {