diff options
Diffstat (limited to 'net/sctp/protocol.c')
-rw-r--r-- | net/sctp/protocol.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 9258dfe784ae..a6e0818bcff5 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. */ |
66 | struct sctp_globals sctp_globals __read_mostly; | 68 | struct sctp_globals sctp_globals __read_mostly; |
67 | struct proc_dir_entry *proc_net_sctp; | ||
68 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; | 69 | DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics) __read_mostly; |
69 | 70 | ||
71 | #ifdef CONFIG_PROC_FS | ||
72 | struct proc_dir_entry *proc_net_sctp; | ||
73 | #endif | ||
74 | |||
70 | struct idr sctp_assocs_id; | 75 | struct idr sctp_assocs_id; |
71 | DEFINE_SPINLOCK(sctp_assocs_id_lock); | 76 | DEFINE_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. */ |
98 | static __init int sctp_proc_init(void) | 103 | static __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 | ||
127 | out_remaddr_proc_init: | ||
128 | sctp_assocs_proc_exit(); | ||
119 | out_assocs_proc_init: | 129 | out_assocs_proc_init: |
120 | sctp_eps_proc_exit(); | 130 | sctp_eps_proc_exit(); |
121 | out_eps_proc_init: | 131 | out_eps_proc_init: |
@@ -127,6 +137,9 @@ out_snmp_proc_init: | |||
127 | } | 137 | } |
128 | out_nomem: | 138 | out_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 | */ |
136 | static void sctp_proc_exit(void) | 149 | static 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 | ||
@@ -645,7 +668,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, | |||
645 | struct sctp_sockaddr_entry *temp; | 668 | struct sctp_sockaddr_entry *temp; |
646 | int found = 0; | 669 | int found = 0; |
647 | 670 | ||
648 | if (dev_net(ifa->ifa_dev->dev) != &init_net) | 671 | if (!net_eq(dev_net(ifa->ifa_dev->dev), &init_net)) |
649 | return NOTIFY_DONE; | 672 | return NOTIFY_DONE; |
650 | 673 | ||
651 | switch (ev) { | 674 | switch (ev) { |
@@ -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 | ||