]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/protocol.c
x86: mark the .rodata section also NX
[linux-2.6-omap-h63xx.git] / net / sctp / protocol.c
index 3d036cdfae41574d254d85356cf9400166f93d0e..1339742e49f177c714a578d51d1edb52026350b0 100644 (file)
@@ -51,6 +51,8 @@
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 #include <linux/seq_file.h>
+#include <linux/bootmem.h>
+#include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -82,6 +84,10 @@ static struct sctp_af *sctp_af_v6_specific;
 struct kmem_cache *sctp_chunk_cachep __read_mostly;
 struct kmem_cache *sctp_bucket_cachep __read_mostly;
 
+int sysctl_sctp_mem[3];
+int sysctl_sctp_rmem[3];
+int sysctl_sctp_wmem[3];
+
 /* Return the address of the control sock. */
 struct sock *sctp_get_ctl_sock(void)
 {
@@ -93,7 +99,7 @@ static __init int sctp_proc_init(void)
 {
        if (!proc_net_sctp) {
                struct proc_dir_entry *ent;
-               ent = proc_mkdir("net/sctp", NULL);
+               ent = proc_mkdir("sctp", init_net.proc_net);
                if (ent) {
                        ent->owner = THIS_MODULE;
                        proc_net_sctp = ent;
@@ -126,7 +132,7 @@ static void sctp_proc_exit(void)
 
        if (proc_net_sctp) {
                proc_net_sctp = NULL;
-               remove_proc_entry("net/sctp", NULL);
+               remove_proc_entry("sctp", init_net.proc_net);
        }
 }
 
@@ -173,7 +179,7 @@ static void sctp_get_local_addr_list(void)
        struct sctp_af *af;
 
        read_lock(&dev_base_lock);
-       for_each_netdev(dev) {
+       for_each_netdev(&init_net, dev) {
                __list_for_each(pos, &sctp_address_families) {
                        af = list_entry(pos, struct sctp_af, list);
                        af->copy_addrlist(&sctp_local_addr_list, dev);
@@ -223,8 +229,8 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
                            (((AF_INET6 == addr->a.sa.sa_family) &&
                              (copy_flags & SCTP_ADDR6_ALLOWED) &&
                              (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
-                               error = sctp_add_bind_addr(bp, &addr->a, 1,
-                                                   GFP_ATOMIC);
+                               error = sctp_add_bind_addr(bp, &addr->a,
+                                                   SCTP_ADDR_SRC, GFP_ATOMIC);
                                if (error)
                                        goto end_copy;
                        }
@@ -353,7 +359,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
                              const struct sk_buff *skb)
 {
        /* Is this a non-unicast address or a unusable SCTP address? */
-       if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
+       if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr))
                return 0;
 
        /* Is this a broadcast address? */
@@ -366,7 +372,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
 /* Should this be available for binding?   */
 static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
-       int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
+       int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
 
 
        if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
@@ -402,13 +408,15 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
         */
 
        /* Check for unusable SCTP addresses. */
-       if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) {
                retval =  SCTP_SCOPE_UNUSABLE;
-       } else if (LOOPBACK(addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_loopback(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_LOOPBACK;
-       } else if (IS_IPV4_LINK_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_linklocal_169(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_LINK;
-       } else if (IS_IPV4_PRIVATE_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_private_10(addr->v4.sin_addr.s_addr) ||
+                  ipv4_is_private_172(addr->v4.sin_addr.s_addr) ||
+                  ipv4_is_private_192(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_PRIVATE;
        } else {
                retval = SCTP_SCOPE_GLOBAL;
@@ -446,7 +454,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
                          __FUNCTION__, NIPQUAD(fl.fl4_dst),
                          NIPQUAD(fl.fl4_src));
 
-       if (!ip_route_output_key(&rt, &fl)) {
+       if (!ip_route_output_key(&init_net, &rt, &fl)) {
                dst = &rt->u.dst;
        }
 
@@ -464,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
                 */
                rcu_read_lock();
                list_for_each_entry_rcu(laddr, &bp->address_list, list) {
-                       if (!laddr->valid || !laddr->use_as_src)
+                       if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
                                continue;
                        sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
                        if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
@@ -486,10 +494,10 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
        list_for_each_entry_rcu(laddr, &bp->address_list, list) {
                if (!laddr->valid)
                        continue;
-               if ((laddr->use_as_src) &&
+               if ((laddr->state == SCTP_ADDR_SRC) &&
                    (AF_INET == laddr->a.sa.sa_family)) {
                        fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
-                       if (!ip_route_output_key(&rt, &fl)) {
+                       if (!ip_route_output_key(&init_net, &rt, &fl)) {
                                dst = &rt->u.dst;
                                goto out_unlock;
                        }
@@ -546,7 +554,8 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
 {
        struct inet_sock *inet = inet_sk(sk);
        struct inet_sock *newinet;
-       struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
+       struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL,
+                       sk->sk_prot);
 
        if (!newsk)
                goto out;
@@ -987,6 +996,8 @@ SCTP_STATIC __init int sctp_init(void)
        int i;
        int status = -EINVAL;
        unsigned long goal;
+       unsigned long limit;
+       int max_share;
        int order;
 
        /* SCTP_DEBUG sanity check. */
@@ -1077,6 +1088,31 @@ SCTP_STATIC __init int sctp_init(void)
        /* Initialize handle used for association ids. */
        idr_init(&sctp_assocs_id);
 
+       /* Set the pressure threshold to be a fraction of global memory that
+        * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
+        * memory, with a floor of 128 pages.
+        * Note this initalizes the data in sctpv6_prot too
+        * Unabashedly stolen from tcp_init
+        */
+       limit = min(num_physpages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+       limit = (limit * (num_physpages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+       limit = max(limit, 128UL);
+       sysctl_sctp_mem[0] = limit / 4 * 3;
+       sysctl_sctp_mem[1] = limit;
+       sysctl_sctp_mem[2] = sysctl_sctp_mem[0] * 2;
+
+       /* Set per-socket limits to no more than 1/128 the pressure threshold*/
+       limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7);
+       max_share = min(4UL*1024*1024, limit);
+
+       sysctl_sctp_rmem[0] = PAGE_SIZE; /* give each asoc 1 page min */
+       sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1));
+       sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share);
+
+       sysctl_sctp_wmem[0] = SK_MEM_QUANTUM;
+       sysctl_sctp_wmem[1] = 16*1024;
+       sysctl_sctp_wmem[2] = max(64*1024, max_share);
+
        /* Size and allocate the association hash table.
         * The methodology is similar to that of the tcp hash tables.
         */
@@ -1103,7 +1139,7 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_assoc_hashsize; i++) {
                rwlock_init(&sctp_assoc_hashtable[i].lock);
-               sctp_assoc_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
        }
 
        /* Allocate and initialize the endpoint hash table.  */
@@ -1117,7 +1153,7 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_ep_hashsize; i++) {
                rwlock_init(&sctp_ep_hashtable[i].lock);
-               sctp_ep_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
        }
 
        /* Allocate and initialize the SCTP port hash table.  */
@@ -1136,22 +1172,23 @@ SCTP_STATIC __init int sctp_init(void)
        }
        for (i = 0; i < sctp_port_hashsize; i++) {
                spin_lock_init(&sctp_port_hashtable[i].lock);
-               sctp_port_hashtable[i].chain = NULL;
+               INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
        }
 
-       spin_lock_init(&sctp_port_alloc_lock);
-       sctp_port_rover = sysctl_local_port_range[0] - 1;
-
        printk(KERN_INFO "SCTP: Hash tables configured "
                         "(established %d bind %d)\n",
                sctp_assoc_hashsize, sctp_port_hashsize);
 
        /* Disable ADDIP by default. */
        sctp_addip_enable = 0;
+       sctp_addip_noauth = 0;
 
        /* Enable PR-SCTP by default. */
        sctp_prsctp_enable = 1;
 
+       /* Disable AUTH by default. */
+       sctp_auth_enable = 0;
+
        sctp_sysctl_register();
 
        INIT_LIST_HEAD(&sctp_address_families);
@@ -1195,7 +1232,6 @@ SCTP_STATIC __init int sctp_init(void)
        if (status)
                goto err_v6_add_protocol;
 
-       __unsafe(THIS_MODULE);
        status = 0;
 out:
        return status;