aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/protocol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r--net/sctp/protocol.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 9258dfe784ae..ed9acffe8105 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -52,6 +52,8 @@
52#include <linux/inetdevice.h> 52#include <linux/inetdevice.h>
53#include <linux/seq_file.h> 53#include <linux/seq_file.h>
54#include <linux/bootmem.h> 54#include <linux/bootmem.h>
55#include <linux/highmem.h>
56#include <linux/swap.h>
55#include <net/net_namespace.h> 57#include <net/net_namespace.h>
56#include <net/protocol.h> 58#include <net/protocol.h>
57#include <net/ip.h> 59#include <net/ip.h>
@@ -64,9 +66,12 @@
64 66
65/* Global data structures. */ 67/* Global data structures. */
66struct sctp_globals sctp_globals __read_mostly; 68struct sctp_globals sctp_globals __read_mostly;
67struct proc_dir_entry *proc_net_sctp;
68DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; 69DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly;
69 70
71#ifdef CONFIG_PROC_FS
72struct proc_dir_entry *proc_net_sctp;
73#endif
74
70struct idr sctp_assocs_id; 75struct idr sctp_assocs_id;
71DEFINE_SPINLOCK(sctp_assocs_id_lock); 76DEFINE_SPINLOCK(sctp_assocs_id_lock);
72 77
@@ -97,6 +102,7 @@ struct sock *sctp_get_ctl_sock(void)
97/* Set up the proc fs entry for the SCTP protocol. */ 102/* Set up the proc fs entry for the SCTP protocol. */
98static __init int sctp_proc_init(void) 103static __init int sctp_proc_init(void)
99{ 104{
105#ifdef CONFIG_PROC_FS
100 if (!proc_net_sctp) { 106 if (!proc_net_sctp) {
101 struct proc_dir_entry *ent; 107 struct proc_dir_entry *ent;
102 ent = proc_mkdir("sctp", init_net.proc_net); 108 ent = proc_mkdir("sctp", init_net.proc_net);
@@ -113,9 +119,13 @@ static __init int sctp_proc_init(void)
113 goto out_eps_proc_init; 119 goto out_eps_proc_init;
114 if (sctp_assocs_proc_init()) 120 if (sctp_assocs_proc_init())
115 goto out_assocs_proc_init; 121 goto out_assocs_proc_init;
122 if (sctp_remaddr_proc_init())
123 goto out_remaddr_proc_init;
116 124
117 return 0; 125 return 0;
118 126
127out_remaddr_proc_init:
128 sctp_assocs_proc_exit();
119out_assocs_proc_init: 129out_assocs_proc_init:
120 sctp_eps_proc_exit(); 130 sctp_eps_proc_exit();
121out_eps_proc_init: 131out_eps_proc_init:
@@ -127,6 +137,9 @@ out_snmp_proc_init:
127 } 137 }
128out_nomem: 138out_nomem:
129 return -ENOMEM; 139 return -ENOMEM;
140#else
141 return 0;
142#endif /* CONFIG_PROC_FS */
130} 143}
131 144
132/* Clean up the proc fs entry for the SCTP protocol. 145/* Clean up the proc fs entry for the SCTP protocol.
@@ -135,14 +148,17 @@ out_nomem:
135 */ 148 */
136static void sctp_proc_exit(void) 149static void sctp_proc_exit(void)
137{ 150{
151#ifdef CONFIG_PROC_FS
138 sctp_snmp_proc_exit(); 152 sctp_snmp_proc_exit();
139 sctp_eps_proc_exit(); 153 sctp_eps_proc_exit();
140 sctp_assocs_proc_exit(); 154 sctp_assocs_proc_exit();
155 sctp_remaddr_proc_exit();
141 156
142 if (proc_net_sctp) { 157 if (proc_net_sctp) {
143 proc_net_sctp = NULL; 158 proc_net_sctp = NULL;
144 remove_proc_entry("sctp", init_net.proc_net); 159 remove_proc_entry("sctp", init_net.proc_net);
145 } 160 }
161#endif
146} 162}
147 163
148/* Private helper to extract ipv4 address and stash them in 164/* Private helper to extract ipv4 address and stash them in
@@ -367,6 +383,10 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
367 struct sctp_sock *sp, 383 struct sctp_sock *sp,
368 const struct sk_buff *skb) 384 const struct sk_buff *skb)
369{ 385{
386 /* IPv4 addresses not allowed */
387 if (sp && ipv6_only_sock(sctp_opt2sk(sp)))
388 return 0;
389
370 /* Is this a non-unicast address or a unusable SCTP address? */ 390 /* Is this a non-unicast address or a unusable SCTP address? */
371 if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) 391 if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr))
372 return 0; 392 return 0;
@@ -390,6 +410,9 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
390 !sysctl_ip_nonlocal_bind) 410 !sysctl_ip_nonlocal_bind)
391 return 0; 411 return 0;
392 412
413 if (ipv6_only_sock(sctp_opt2sk(sp)))
414 return 0;
415
393 return 1; 416 return 1;
394} 417}
395 418
@@ -1059,6 +1082,7 @@ SCTP_STATIC __init int sctp_init(void)
1059 int status = -EINVAL; 1082 int status = -EINVAL;
1060 unsigned long goal; 1083 unsigned long goal;
1061 unsigned long limit; 1084 unsigned long limit;
1085 unsigned long nr_pages;
1062 int max_share; 1086 int max_share;
1063 int order; 1087 int order;
1064 1088
@@ -1154,8 +1178,9 @@ SCTP_STATIC __init int sctp_init(void)
1154 * Note this initalizes the data in sctpv6_prot too 1178 * Note this initalizes the data in sctpv6_prot too
1155 * Unabashedly stolen from tcp_init 1179 * Unabashedly stolen from tcp_init
1156 */ 1180 */
1157 limit = min(num_physpages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); 1181 nr_pages = totalram_pages - totalhigh_pages;
1158 limit = (limit * (num_physpages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); 1182 limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
1183 limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
1159 limit = max(limit, 128UL); 1184 limit = max(limit, 128UL);
1160 sysctl_sctp_mem[0] = limit / 4 * 3; 1185 sysctl_sctp_mem[0] = limit / 4 * 3;
1161 sysctl_sctp_mem[1] = limit; 1186 sysctl_sctp_mem[1] = limit;
@@ -1165,7 +1190,7 @@ SCTP_STATIC __init int sctp_init(void)
1165 limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7); 1190 limit = (sysctl_sctp_mem[1]) << (PAGE_SHIFT - 7);
1166 max_share = min(4UL*1024*1024, limit); 1191 max_share = min(4UL*1024*1024, limit);
1167 1192
1168 sysctl_sctp_rmem[0] = PAGE_SIZE; /* give each asoc 1 page min */ 1193 sysctl_sctp_rmem[0] = SK_MEM_QUANTUM; /* give each asoc 1 page min */
1169 sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1)); 1194 sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1));
1170 sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share); 1195 sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share);
1171 1196