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 | ||
