diff options
Diffstat (limited to 'net/sctp')
| -rw-r--r-- | net/sctp/associola.c | 15 | ||||
| -rw-r--r-- | net/sctp/bind_addr.c | 16 | ||||
| -rw-r--r-- | net/sctp/chunk.c | 2 | ||||
| -rw-r--r-- | net/sctp/endpointola.c | 19 | ||||
| -rw-r--r-- | net/sctp/input.c | 71 | ||||
| -rw-r--r-- | net/sctp/inqueue.c | 18 | ||||
| -rw-r--r-- | net/sctp/ipv6.c | 7 | ||||
| -rw-r--r-- | net/sctp/objcnt.c | 6 | ||||
| -rw-r--r-- | net/sctp/output.c | 22 | ||||
| -rw-r--r-- | net/sctp/outqueue.c | 50 | ||||
| -rw-r--r-- | net/sctp/proc.c | 1 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 7 | ||||
| -rw-r--r-- | net/sctp/sm_make_chunk.c | 27 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 13 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 16 | ||||
| -rw-r--r-- | net/sctp/socket.c | 2 | ||||
| -rw-r--r-- | net/sctp/ssnmap.c | 3 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 13 | ||||
| -rw-r--r-- | net/sctp/transport.c | 6 | ||||
| -rw-r--r-- | net/sctp/ulpevent.c | 19 | ||||
| -rw-r--r-- | net/sctp/ulpqueue.c | 9 |
21 files changed, 195 insertions, 147 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 7ae6aa772dab..5b24ae0650d3 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -71,7 +71,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 71 | const struct sctp_endpoint *ep, | 71 | const struct sctp_endpoint *ep, |
| 72 | const struct sock *sk, | 72 | const struct sock *sk, |
| 73 | sctp_scope_t scope, | 73 | sctp_scope_t scope, |
| 74 | int gfp) | 74 | unsigned int __nocast gfp) |
| 75 | { | 75 | { |
| 76 | struct sctp_sock *sp; | 76 | struct sctp_sock *sp; |
| 77 | int i; | 77 | int i; |
| @@ -203,7 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 203 | */ | 203 | */ |
| 204 | asoc->addip_serial = asoc->c.initial_tsn; | 204 | asoc->addip_serial = asoc->c.initial_tsn; |
| 205 | 205 | ||
| 206 | skb_queue_head_init(&asoc->addip_chunks); | 206 | INIT_LIST_HEAD(&asoc->addip_chunk_list); |
| 207 | 207 | ||
| 208 | /* Make an empty list of remote transport addresses. */ | 208 | /* Make an empty list of remote transport addresses. */ |
| 209 | INIT_LIST_HEAD(&asoc->peer.transport_addr_list); | 209 | INIT_LIST_HEAD(&asoc->peer.transport_addr_list); |
| @@ -272,7 +272,8 @@ fail_init: | |||
| 272 | /* Allocate and initialize a new association */ | 272 | /* Allocate and initialize a new association */ |
| 273 | struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep, | 273 | struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep, |
| 274 | const struct sock *sk, | 274 | const struct sock *sk, |
| 275 | sctp_scope_t scope, int gfp) | 275 | sctp_scope_t scope, |
| 276 | unsigned int __nocast gfp) | ||
| 276 | { | 277 | { |
| 277 | struct sctp_association *asoc; | 278 | struct sctp_association *asoc; |
| 278 | 279 | ||
| @@ -478,7 +479,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc, | |||
| 478 | /* Add a transport address to an association. */ | 479 | /* Add a transport address to an association. */ |
| 479 | struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, | 480 | struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, |
| 480 | const union sctp_addr *addr, | 481 | const union sctp_addr *addr, |
| 481 | const int gfp, | 482 | const unsigned int __nocast gfp, |
| 482 | const int peer_state) | 483 | const int peer_state) |
| 483 | { | 484 | { |
| 484 | struct sctp_transport *peer; | 485 | struct sctp_transport *peer; |
| @@ -1229,7 +1230,8 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
| 1229 | /* Build the bind address list for the association based on info from the | 1230 | /* Build the bind address list for the association based on info from the |
| 1230 | * local endpoint and the remote peer. | 1231 | * local endpoint and the remote peer. |
| 1231 | */ | 1232 | */ |
| 1232 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, int gfp) | 1233 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, |
| 1234 | unsigned int __nocast gfp) | ||
| 1233 | { | 1235 | { |
| 1234 | sctp_scope_t scope; | 1236 | sctp_scope_t scope; |
| 1235 | int flags; | 1237 | int flags; |
| @@ -1251,7 +1253,8 @@ int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, int gfp) | |||
| 1251 | 1253 | ||
| 1252 | /* Build the association's bind address list from the cookie. */ | 1254 | /* Build the association's bind address list from the cookie. */ |
| 1253 | int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc, | 1255 | int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc, |
| 1254 | struct sctp_cookie *cookie, int gfp) | 1256 | struct sctp_cookie *cookie, |
| 1257 | unsigned int __nocast gfp) | ||
| 1255 | { | 1258 | { |
| 1256 | int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length); | 1259 | int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length); |
| 1257 | int var_size3 = cookie->raw_addr_list_len; | 1260 | int var_size3 = cookie->raw_addr_list_len; |
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index f90eadfb60a2..f71549710f2e 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c | |||
| @@ -53,7 +53,8 @@ | |||
| 53 | 53 | ||
| 54 | /* Forward declarations for internal helpers. */ | 54 | /* Forward declarations for internal helpers. */ |
| 55 | static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *, | 55 | static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *, |
| 56 | sctp_scope_t scope, int gfp, int flags); | 56 | sctp_scope_t scope, unsigned int __nocast gfp, |
| 57 | int flags); | ||
| 57 | static void sctp_bind_addr_clean(struct sctp_bind_addr *); | 58 | static void sctp_bind_addr_clean(struct sctp_bind_addr *); |
| 58 | 59 | ||
| 59 | /* First Level Abstractions. */ | 60 | /* First Level Abstractions. */ |
| @@ -63,7 +64,8 @@ static void sctp_bind_addr_clean(struct sctp_bind_addr *); | |||
| 63 | */ | 64 | */ |
| 64 | int sctp_bind_addr_copy(struct sctp_bind_addr *dest, | 65 | int sctp_bind_addr_copy(struct sctp_bind_addr *dest, |
| 65 | const struct sctp_bind_addr *src, | 66 | const struct sctp_bind_addr *src, |
| 66 | sctp_scope_t scope, int gfp, int flags) | 67 | sctp_scope_t scope, unsigned int __nocast gfp, |
| 68 | int flags) | ||
| 67 | { | 69 | { |
| 68 | struct sctp_sockaddr_entry *addr; | 70 | struct sctp_sockaddr_entry *addr; |
| 69 | struct list_head *pos; | 71 | struct list_head *pos; |
| @@ -144,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) | |||
| 144 | 146 | ||
| 145 | /* Add an address to the bind address list in the SCTP_bind_addr structure. */ | 147 | /* Add an address to the bind address list in the SCTP_bind_addr structure. */ |
| 146 | int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, | 148 | int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, |
| 147 | int gfp) | 149 | unsigned int __nocast gfp) |
| 148 | { | 150 | { |
| 149 | struct sctp_sockaddr_entry *addr; | 151 | struct sctp_sockaddr_entry *addr; |
| 150 | 152 | ||
| @@ -197,7 +199,8 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) | |||
| 197 | * The second argument is the return value for the length. | 199 | * The second argument is the return value for the length. |
| 198 | */ | 200 | */ |
| 199 | union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, | 201 | union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp, |
| 200 | int *addrs_len, int gfp) | 202 | int *addrs_len, |
| 203 | unsigned int __nocast gfp) | ||
| 201 | { | 204 | { |
| 202 | union sctp_params addrparms; | 205 | union sctp_params addrparms; |
| 203 | union sctp_params retval; | 206 | union sctp_params retval; |
| @@ -249,7 +252,7 @@ end_raw: | |||
| 249 | * address parameters). | 252 | * address parameters). |
| 250 | */ | 253 | */ |
| 251 | int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, | 254 | int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, |
| 252 | int addrs_len, __u16 port, int gfp) | 255 | int addrs_len, __u16 port, unsigned int __nocast gfp) |
| 253 | { | 256 | { |
| 254 | union sctp_addr_param *rawaddr; | 257 | union sctp_addr_param *rawaddr; |
| 255 | struct sctp_paramhdr *param; | 258 | struct sctp_paramhdr *param; |
| @@ -347,7 +350,8 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr *bp, | |||
| 347 | /* Copy out addresses from the global local address list. */ | 350 | /* Copy out addresses from the global local address list. */ |
| 348 | static int sctp_copy_one_addr(struct sctp_bind_addr *dest, | 351 | static int sctp_copy_one_addr(struct sctp_bind_addr *dest, |
| 349 | union sctp_addr *addr, | 352 | union sctp_addr *addr, |
| 350 | sctp_scope_t scope, int gfp, int flags) | 353 | sctp_scope_t scope, unsigned int __nocast gfp, |
| 354 | int flags) | ||
| 351 | { | 355 | { |
| 352 | int error = 0; | 356 | int error = 0; |
| 353 | 357 | ||
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 0c2ab7885058..61da2937e641 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
| @@ -62,7 +62,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | /* Allocate and initialize datamsg. */ | 64 | /* Allocate and initialize datamsg. */ |
| 65 | SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(int gfp) | 65 | SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(unsigned int __nocast gfp) |
| 66 | { | 66 | { |
| 67 | struct sctp_datamsg *msg; | 67 | struct sctp_datamsg *msg; |
| 68 | msg = kmalloc(sizeof(struct sctp_datamsg), gfp); | 68 | msg = kmalloc(sizeof(struct sctp_datamsg), gfp); |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2ec0320fac3b..e47ac0d1a6d6 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
| @@ -67,7 +67,8 @@ static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep); | |||
| 67 | * Initialize the base fields of the endpoint structure. | 67 | * Initialize the base fields of the endpoint structure. |
| 68 | */ | 68 | */ |
| 69 | static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | 69 | static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, |
| 70 | struct sock *sk, int gfp) | 70 | struct sock *sk, |
| 71 | unsigned int __nocast gfp) | ||
| 71 | { | 72 | { |
| 72 | struct sctp_sock *sp = sctp_sk(sk); | 73 | struct sctp_sock *sp = sctp_sk(sk); |
| 73 | memset(ep, 0, sizeof(struct sctp_endpoint)); | 74 | memset(ep, 0, sizeof(struct sctp_endpoint)); |
| @@ -102,9 +103,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 102 | /* Set up the base timeout information. */ | 103 | /* Set up the base timeout information. */ |
| 103 | ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; | 104 | ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; |
| 104 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = | 105 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = |
| 105 | SCTP_DEFAULT_TIMEOUT_T1_COOKIE; | 106 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
| 106 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = | 107 | ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = |
| 107 | SCTP_DEFAULT_TIMEOUT_T1_INIT; | 108 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
| 108 | ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = | 109 | ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = |
| 109 | msecs_to_jiffies(sp->rtoinfo.srto_initial); | 110 | msecs_to_jiffies(sp->rtoinfo.srto_initial); |
| 110 | ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; | 111 | ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; |
| @@ -117,12 +118,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 117 | ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] | 118 | ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] |
| 118 | = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); | 119 | = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); |
| 119 | 120 | ||
| 120 | ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = | 121 | ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; |
| 121 | SCTP_DEFAULT_TIMEOUT_HEARTBEAT; | 122 | ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout; |
| 122 | ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = | 123 | ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; |
| 123 | SCTP_DEFAULT_TIMEOUT_SACK; | ||
| 124 | ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = | ||
| 125 | sp->autoclose * HZ; | ||
| 126 | 124 | ||
| 127 | /* Use SCTP specific send buffer space queues. */ | 125 | /* Use SCTP specific send buffer space queues. */ |
| 128 | ep->sndbuf_policy = sctp_sndbuf_policy; | 126 | ep->sndbuf_policy = sctp_sndbuf_policy; |
| @@ -140,7 +138,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 140 | /* Create a sctp_endpoint with all that boring stuff initialized. | 138 | /* Create a sctp_endpoint with all that boring stuff initialized. |
| 141 | * Returns NULL if there isn't enough memory. | 139 | * Returns NULL if there isn't enough memory. |
| 142 | */ | 140 | */ |
| 143 | struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp) | 141 | struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, |
| 142 | unsigned int __nocast gfp) | ||
| 144 | { | 143 | { |
| 145 | struct sctp_endpoint *ep; | 144 | struct sctp_endpoint *ep; |
| 146 | 145 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 339f7acfdb64..742be9171b7d 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -115,6 +115,17 @@ static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk) | |||
| 115 | atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc); | 115 | atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | struct sctp_input_cb { | ||
| 119 | union { | ||
| 120 | struct inet_skb_parm h4; | ||
| 121 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
| 122 | struct inet6_skb_parm h6; | ||
| 123 | #endif | ||
| 124 | } header; | ||
| 125 | struct sctp_chunk *chunk; | ||
| 126 | }; | ||
| 127 | #define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0])) | ||
| 128 | |||
| 118 | /* | 129 | /* |
| 119 | * This is the routine which IP calls when receiving an SCTP packet. | 130 | * This is the routine which IP calls when receiving an SCTP packet. |
| 120 | */ | 131 | */ |
| @@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 243 | ret = -ENOMEM; | 254 | ret = -ENOMEM; |
| 244 | goto discard_release; | 255 | goto discard_release; |
| 245 | } | 256 | } |
| 257 | SCTP_INPUT_CB(skb)->chunk = chunk; | ||
| 246 | 258 | ||
| 247 | sctp_rcv_set_owner_r(skb,sk); | 259 | sctp_rcv_set_owner_r(skb,sk); |
| 248 | 260 | ||
| @@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 265 | sctp_bh_lock_sock(sk); | 277 | sctp_bh_lock_sock(sk); |
| 266 | 278 | ||
| 267 | if (sock_owned_by_user(sk)) | 279 | if (sock_owned_by_user(sk)) |
| 268 | sk_add_backlog(sk, (struct sk_buff *) chunk); | 280 | sk_add_backlog(sk, skb); |
| 269 | else | 281 | else |
| 270 | sctp_backlog_rcv(sk, (struct sk_buff *) chunk); | 282 | sctp_backlog_rcv(sk, skb); |
| 271 | 283 | ||
| 272 | /* Release the sock and any reference counts we took in the | 284 | /* Release the sock and any reference counts we took in the |
| 273 | * lookup calls. | 285 | * lookup calls. |
| @@ -302,14 +314,8 @@ discard_release: | |||
| 302 | */ | 314 | */ |
| 303 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) | 315 | int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) |
| 304 | { | 316 | { |
| 305 | struct sctp_chunk *chunk; | 317 | struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk; |
| 306 | struct sctp_inq *inqueue; | 318 | struct sctp_inq *inqueue = &chunk->rcvr->inqueue; |
| 307 | |||
| 308 | /* One day chunk will live inside the skb, but for | ||
| 309 | * now this works. | ||
| 310 | */ | ||
| 311 | chunk = (struct sctp_chunk *) skb; | ||
| 312 | inqueue = &chunk->rcvr->inqueue; | ||
| 313 | 319 | ||
| 314 | sctp_inq_push(inqueue, chunk); | 320 | sctp_inq_push(inqueue, chunk); |
| 315 | return 0; | 321 | return 0; |
| @@ -345,7 +351,6 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
| 345 | * | 351 | * |
| 346 | */ | 352 | */ |
| 347 | void sctp_icmp_proto_unreachable(struct sock *sk, | 353 | void sctp_icmp_proto_unreachable(struct sock *sk, |
| 348 | struct sctp_endpoint *ep, | ||
| 349 | struct sctp_association *asoc, | 354 | struct sctp_association *asoc, |
| 350 | struct sctp_transport *t) | 355 | struct sctp_transport *t) |
| 351 | { | 356 | { |
| @@ -361,7 +366,6 @@ void sctp_icmp_proto_unreachable(struct sock *sk, | |||
| 361 | /* Common lookup code for icmp/icmpv6 error handler. */ | 366 | /* Common lookup code for icmp/icmpv6 error handler. */ |
| 362 | struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | 367 | struct sock *sctp_err_lookup(int family, struct sk_buff *skb, |
| 363 | struct sctphdr *sctphdr, | 368 | struct sctphdr *sctphdr, |
| 364 | struct sctp_endpoint **epp, | ||
| 365 | struct sctp_association **app, | 369 | struct sctp_association **app, |
| 366 | struct sctp_transport **tpp) | 370 | struct sctp_transport **tpp) |
| 367 | { | 371 | { |
| @@ -369,11 +373,10 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 369 | union sctp_addr daddr; | 373 | union sctp_addr daddr; |
| 370 | struct sctp_af *af; | 374 | struct sctp_af *af; |
| 371 | struct sock *sk = NULL; | 375 | struct sock *sk = NULL; |
| 372 | struct sctp_endpoint *ep = NULL; | ||
| 373 | struct sctp_association *asoc = NULL; | 376 | struct sctp_association *asoc = NULL; |
| 374 | struct sctp_transport *transport = NULL; | 377 | struct sctp_transport *transport = NULL; |
| 375 | 378 | ||
| 376 | *app = NULL; *epp = NULL; *tpp = NULL; | 379 | *app = NULL; *tpp = NULL; |
| 377 | 380 | ||
| 378 | af = sctp_get_af_specific(family); | 381 | af = sctp_get_af_specific(family); |
| 379 | if (unlikely(!af)) { | 382 | if (unlikely(!af)) { |
| @@ -388,26 +391,15 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 388 | * packet. | 391 | * packet. |
| 389 | */ | 392 | */ |
| 390 | asoc = __sctp_lookup_association(&saddr, &daddr, &transport); | 393 | asoc = __sctp_lookup_association(&saddr, &daddr, &transport); |
| 391 | if (!asoc) { | 394 | if (!asoc) |
| 392 | /* If there is no matching association, see if it matches any | 395 | return NULL; |
| 393 | * endpoint. This may happen for an ICMP error generated in | ||
| 394 | * response to an INIT_ACK. | ||
| 395 | */ | ||
| 396 | ep = __sctp_rcv_lookup_endpoint(&daddr); | ||
| 397 | if (!ep) { | ||
| 398 | return NULL; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | 396 | ||
| 402 | if (asoc) { | 397 | sk = asoc->base.sk; |
| 403 | sk = asoc->base.sk; | ||
| 404 | 398 | ||
| 405 | if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) { | 399 | if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) { |
| 406 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 400 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
| 407 | goto out; | 401 | goto out; |
| 408 | } | 402 | } |
| 409 | } else | ||
| 410 | sk = ep->base.sk; | ||
| 411 | 403 | ||
| 412 | sctp_bh_lock_sock(sk); | 404 | sctp_bh_lock_sock(sk); |
| 413 | 405 | ||
| @@ -417,7 +409,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb, | |||
| 417 | if (sock_owned_by_user(sk)) | 409 | if (sock_owned_by_user(sk)) |
| 418 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); | 410 | NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS); |
| 419 | 411 | ||
| 420 | *epp = ep; | ||
| 421 | *app = asoc; | 412 | *app = asoc; |
| 422 | *tpp = transport; | 413 | *tpp = transport; |
| 423 | return sk; | 414 | return sk; |
| @@ -426,21 +417,16 @@ out: | |||
| 426 | sock_put(sk); | 417 | sock_put(sk); |
| 427 | if (asoc) | 418 | if (asoc) |
| 428 | sctp_association_put(asoc); | 419 | sctp_association_put(asoc); |
| 429 | if (ep) | ||
| 430 | sctp_endpoint_put(ep); | ||
| 431 | return NULL; | 420 | return NULL; |
| 432 | } | 421 | } |
| 433 | 422 | ||
| 434 | /* Common cleanup code for icmp/icmpv6 error handler. */ | 423 | /* Common cleanup code for icmp/icmpv6 error handler. */ |
| 435 | void sctp_err_finish(struct sock *sk, struct sctp_endpoint *ep, | 424 | void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) |
| 436 | struct sctp_association *asoc) | ||
| 437 | { | 425 | { |
| 438 | sctp_bh_unlock_sock(sk); | 426 | sctp_bh_unlock_sock(sk); |
| 439 | sock_put(sk); | 427 | sock_put(sk); |
| 440 | if (asoc) | 428 | if (asoc) |
| 441 | sctp_association_put(asoc); | 429 | sctp_association_put(asoc); |
| 442 | if (ep) | ||
| 443 | sctp_endpoint_put(ep); | ||
| 444 | } | 430 | } |
| 445 | 431 | ||
| 446 | /* | 432 | /* |
| @@ -465,7 +451,6 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 465 | int type = skb->h.icmph->type; | 451 | int type = skb->h.icmph->type; |
| 466 | int code = skb->h.icmph->code; | 452 | int code = skb->h.icmph->code; |
| 467 | struct sock *sk; | 453 | struct sock *sk; |
| 468 | struct sctp_endpoint *ep; | ||
| 469 | struct sctp_association *asoc; | 454 | struct sctp_association *asoc; |
| 470 | struct sctp_transport *transport; | 455 | struct sctp_transport *transport; |
| 471 | struct inet_sock *inet; | 456 | struct inet_sock *inet; |
| @@ -482,7 +467,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 482 | savesctp = skb->h.raw; | 467 | savesctp = skb->h.raw; |
| 483 | skb->nh.iph = iph; | 468 | skb->nh.iph = iph; |
| 484 | skb->h.raw = (char *)sh; | 469 | skb->h.raw = (char *)sh; |
| 485 | sk = sctp_err_lookup(AF_INET, skb, sh, &ep, &asoc, &transport); | 470 | sk = sctp_err_lookup(AF_INET, skb, sh, &asoc, &transport); |
| 486 | /* Put back, the original pointers. */ | 471 | /* Put back, the original pointers. */ |
| 487 | skb->nh.raw = saveip; | 472 | skb->nh.raw = saveip; |
| 488 | skb->h.raw = savesctp; | 473 | skb->h.raw = savesctp; |
| @@ -509,7 +494,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 509 | } | 494 | } |
| 510 | else { | 495 | else { |
| 511 | if (ICMP_PROT_UNREACH == code) { | 496 | if (ICMP_PROT_UNREACH == code) { |
| 512 | sctp_icmp_proto_unreachable(sk, ep, asoc, | 497 | sctp_icmp_proto_unreachable(sk, asoc, |
| 513 | transport); | 498 | transport); |
| 514 | goto out_unlock; | 499 | goto out_unlock; |
| 515 | } | 500 | } |
| @@ -538,7 +523,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) | |||
| 538 | } | 523 | } |
| 539 | 524 | ||
| 540 | out_unlock: | 525 | out_unlock: |
| 541 | sctp_err_finish(sk, ep, asoc); | 526 | sctp_err_finish(sk, asoc); |
| 542 | } | 527 | } |
| 543 | 528 | ||
| 544 | /* | 529 | /* |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index cedf4351556c..2d33922c044b 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | /* Initialize an SCTP inqueue. */ | 50 | /* Initialize an SCTP inqueue. */ |
| 51 | void sctp_inq_init(struct sctp_inq *queue) | 51 | void sctp_inq_init(struct sctp_inq *queue) |
| 52 | { | 52 | { |
| 53 | skb_queue_head_init(&queue->in); | 53 | INIT_LIST_HEAD(&queue->in_chunk_list); |
| 54 | queue->in_progress = NULL; | 54 | queue->in_progress = NULL; |
| 55 | 55 | ||
| 56 | /* Create a task for delivering data. */ | 56 | /* Create a task for delivering data. */ |
| @@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queue) | |||
| 62 | /* Release the memory associated with an SCTP inqueue. */ | 62 | /* Release the memory associated with an SCTP inqueue. */ |
| 63 | void sctp_inq_free(struct sctp_inq *queue) | 63 | void sctp_inq_free(struct sctp_inq *queue) |
| 64 | { | 64 | { |
| 65 | struct sctp_chunk *chunk; | 65 | struct sctp_chunk *chunk, *tmp; |
| 66 | 66 | ||
| 67 | /* Empty the queue. */ | 67 | /* Empty the queue. */ |
| 68 | while ((chunk = (struct sctp_chunk *) skb_dequeue(&queue->in)) != NULL) | 68 | list_for_each_entry_safe(chunk, tmp, &queue->in_chunk_list, list) { |
| 69 | list_del_init(&chunk->list); | ||
| 69 | sctp_chunk_free(chunk); | 70 | sctp_chunk_free(chunk); |
| 71 | } | ||
| 70 | 72 | ||
| 71 | /* If there is a packet which is currently being worked on, | 73 | /* If there is a packet which is currently being worked on, |
| 72 | * free it as well. | 74 | * free it as well. |
| @@ -92,7 +94,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *packet) | |||
| 92 | * Eventually, we should clean up inqueue to not rely | 94 | * Eventually, we should clean up inqueue to not rely |
| 93 | * on the BH related data structures. | 95 | * on the BH related data structures. |
| 94 | */ | 96 | */ |
| 95 | skb_queue_tail(&(q->in), (struct sk_buff *) packet); | 97 | list_add_tail(&packet->list, &q->in_chunk_list); |
| 96 | q->immediate.func(q->immediate.data); | 98 | q->immediate.func(q->immediate.data); |
| 97 | } | 99 | } |
| 98 | 100 | ||
| @@ -131,12 +133,16 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | |||
| 131 | 133 | ||
| 132 | /* Do we need to take the next packet out of the queue to process? */ | 134 | /* Do we need to take the next packet out of the queue to process? */ |
| 133 | if (!chunk) { | 135 | if (!chunk) { |
| 136 | struct list_head *entry; | ||
| 137 | |||
| 134 | /* Is the queue empty? */ | 138 | /* Is the queue empty? */ |
| 135 | if (skb_queue_empty(&queue->in)) | 139 | if (list_empty(&queue->in_chunk_list)) |
| 136 | return NULL; | 140 | return NULL; |
| 137 | 141 | ||
| 142 | entry = queue->in_chunk_list.next; | ||
| 138 | chunk = queue->in_progress = | 143 | chunk = queue->in_progress = |
| 139 | (struct sctp_chunk *) skb_dequeue(&queue->in); | 144 | list_entry(entry, struct sctp_chunk, list); |
| 145 | list_del_init(entry); | ||
| 140 | 146 | ||
| 141 | /* This is the first chunk in the packet. */ | 147 | /* This is the first chunk in the packet. */ |
| 142 | chunk->singleton = 1; | 148 | chunk->singleton = 1; |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index c7e42d125b9c..e9b2fd480d61 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
| @@ -91,7 +91,6 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 91 | struct ipv6hdr *iph = (struct ipv6hdr *)skb->data; | 91 | struct ipv6hdr *iph = (struct ipv6hdr *)skb->data; |
| 92 | struct sctphdr *sh = (struct sctphdr *)(skb->data + offset); | 92 | struct sctphdr *sh = (struct sctphdr *)(skb->data + offset); |
| 93 | struct sock *sk; | 93 | struct sock *sk; |
| 94 | struct sctp_endpoint *ep; | ||
| 95 | struct sctp_association *asoc; | 94 | struct sctp_association *asoc; |
| 96 | struct sctp_transport *transport; | 95 | struct sctp_transport *transport; |
| 97 | struct ipv6_pinfo *np; | 96 | struct ipv6_pinfo *np; |
| @@ -105,7 +104,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 105 | savesctp = skb->h.raw; | 104 | savesctp = skb->h.raw; |
| 106 | skb->nh.ipv6h = iph; | 105 | skb->nh.ipv6h = iph; |
| 107 | skb->h.raw = (char *)sh; | 106 | skb->h.raw = (char *)sh; |
| 108 | sk = sctp_err_lookup(AF_INET6, skb, sh, &ep, &asoc, &transport); | 107 | sk = sctp_err_lookup(AF_INET6, skb, sh, &asoc, &transport); |
| 109 | /* Put back, the original pointers. */ | 108 | /* Put back, the original pointers. */ |
| 110 | skb->nh.raw = saveip; | 109 | skb->nh.raw = saveip; |
| 111 | skb->h.raw = savesctp; | 110 | skb->h.raw = savesctp; |
| @@ -124,7 +123,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 124 | goto out_unlock; | 123 | goto out_unlock; |
| 125 | case ICMPV6_PARAMPROB: | 124 | case ICMPV6_PARAMPROB: |
| 126 | if (ICMPV6_UNK_NEXTHDR == code) { | 125 | if (ICMPV6_UNK_NEXTHDR == code) { |
| 127 | sctp_icmp_proto_unreachable(sk, ep, asoc, transport); | 126 | sctp_icmp_proto_unreachable(sk, asoc, transport); |
| 128 | goto out_unlock; | 127 | goto out_unlock; |
| 129 | } | 128 | } |
| 130 | break; | 129 | break; |
| @@ -142,7 +141,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | out_unlock: | 143 | out_unlock: |
| 145 | sctp_err_finish(sk, ep, asoc); | 144 | sctp_err_finish(sk, asoc); |
| 146 | out: | 145 | out: |
| 147 | if (likely(idev != NULL)) | 146 | if (likely(idev != NULL)) |
| 148 | in6_dev_put(idev); | 147 | in6_dev_put(idev); |
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index 0781e5d509fd..8ff588f0d76a 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c | |||
| @@ -127,8 +127,12 @@ done: | |||
| 127 | /* Initialize the objcount in the proc filesystem. */ | 127 | /* Initialize the objcount in the proc filesystem. */ |
| 128 | void sctp_dbg_objcnt_init(void) | 128 | void sctp_dbg_objcnt_init(void) |
| 129 | { | 129 | { |
| 130 | create_proc_read_entry("sctp_dbg_objcnt", 0, proc_net_sctp, | 130 | struct proc_dir_entry *ent; |
| 131 | ent = create_proc_read_entry("sctp_dbg_objcnt", 0, proc_net_sctp, | ||
| 131 | sctp_dbg_objcnt_read, NULL); | 132 | sctp_dbg_objcnt_read, NULL); |
| 133 | if (!ent) | ||
| 134 | printk(KERN_WARNING | ||
| 135 | "sctp_dbg_objcnt: Unable to create /proc entry.\n"); | ||
| 132 | } | 136 | } |
| 133 | 137 | ||
| 134 | /* Cleanup the objcount entry in the proc filesystem. */ | 138 | /* Cleanup the objcount entry in the proc filesystem. */ |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 84b5b370b09d..931371633464 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, | |||
| 108 | packet->transport = transport; | 108 | packet->transport = transport; |
| 109 | packet->source_port = sport; | 109 | packet->source_port = sport; |
| 110 | packet->destination_port = dport; | 110 | packet->destination_port = dport; |
| 111 | skb_queue_head_init(&packet->chunks); | 111 | INIT_LIST_HEAD(&packet->chunk_list); |
| 112 | if (asoc) { | 112 | if (asoc) { |
| 113 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); | 113 | struct sctp_sock *sp = sctp_sk(asoc->base.sk); |
| 114 | overhead = sp->pf->af->net_header_len; | 114 | overhead = sp->pf->af->net_header_len; |
| @@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet, | |||
| 129 | /* Free a packet. */ | 129 | /* Free a packet. */ |
| 130 | void sctp_packet_free(struct sctp_packet *packet) | 130 | void sctp_packet_free(struct sctp_packet *packet) |
| 131 | { | 131 | { |
| 132 | struct sctp_chunk *chunk; | 132 | struct sctp_chunk *chunk, *tmp; |
| 133 | 133 | ||
| 134 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); | 134 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); |
| 135 | 135 | ||
| 136 | while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) | 136 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
| 137 | list_del_init(&chunk->list); | ||
| 137 | sctp_chunk_free(chunk); | 138 | sctp_chunk_free(chunk); |
| 139 | } | ||
| 138 | 140 | ||
| 139 | if (packet->malloced) | 141 | if (packet->malloced) |
| 140 | kfree(packet); | 142 | kfree(packet); |
| @@ -276,7 +278,7 @@ append: | |||
| 276 | packet->has_sack = 1; | 278 | packet->has_sack = 1; |
| 277 | 279 | ||
| 278 | /* It is OK to send this chunk. */ | 280 | /* It is OK to send this chunk. */ |
| 279 | __skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk); | 281 | list_add_tail(&chunk->list, &packet->chunk_list); |
| 280 | packet->size += chunk_len; | 282 | packet->size += chunk_len; |
| 281 | chunk->transport = packet->transport; | 283 | chunk->transport = packet->transport; |
| 282 | finish: | 284 | finish: |
| @@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 295 | struct sctphdr *sh; | 297 | struct sctphdr *sh; |
| 296 | __u32 crc32; | 298 | __u32 crc32; |
| 297 | struct sk_buff *nskb; | 299 | struct sk_buff *nskb; |
| 298 | struct sctp_chunk *chunk; | 300 | struct sctp_chunk *chunk, *tmp; |
| 299 | struct sock *sk; | 301 | struct sock *sk; |
| 300 | int err = 0; | 302 | int err = 0; |
| 301 | int padding; /* How much padding do we need? */ | 303 | int padding; /* How much padding do we need? */ |
| @@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 305 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); | 307 | SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); |
| 306 | 308 | ||
| 307 | /* Do NOT generate a chunkless packet. */ | 309 | /* Do NOT generate a chunkless packet. */ |
| 308 | chunk = (struct sctp_chunk *)skb_peek(&packet->chunks); | 310 | if (list_empty(&packet->chunk_list)) |
| 309 | if (unlikely(!chunk)) | ||
| 310 | return err; | 311 | return err; |
| 311 | 312 | ||
| 312 | /* Set up convenience variables... */ | 313 | /* Set up convenience variables... */ |
| 314 | chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); | ||
| 313 | sk = chunk->skb->sk; | 315 | sk = chunk->skb->sk; |
| 314 | 316 | ||
| 315 | /* Allocate the new skb. */ | 317 | /* Allocate the new skb. */ |
| @@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
| 370 | * [This whole comment explains WORD_ROUND() below.] | 372 | * [This whole comment explains WORD_ROUND() below.] |
| 371 | */ | 373 | */ |
| 372 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n"); | 374 | SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n"); |
| 373 | while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) { | 375 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
| 376 | list_del_init(&chunk->list); | ||
| 374 | if (sctp_chunk_is_data(chunk)) { | 377 | if (sctp_chunk_is_data(chunk)) { |
| 375 | 378 | ||
| 376 | if (!chunk->has_tsn) { | 379 | if (!chunk->has_tsn) { |
| @@ -511,7 +514,8 @@ err: | |||
| 511 | * will get resent or dropped later. | 514 | * will get resent or dropped later. |
| 512 | */ | 515 | */ |
| 513 | 516 | ||
| 514 | while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) { | 517 | list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) { |
| 518 | list_del_init(&chunk->list); | ||
| 515 | if (!sctp_chunk_is_data(chunk)) | 519 | if (!sctp_chunk_is_data(chunk)) |
| 516 | sctp_chunk_free(chunk); | 520 | sctp_chunk_free(chunk); |
| 517 | } | 521 | } |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 4eb81a1407b7..efb72faba20c 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -75,7 +75,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn); | |||
| 75 | static inline void sctp_outq_head_data(struct sctp_outq *q, | 75 | static inline void sctp_outq_head_data(struct sctp_outq *q, |
| 76 | struct sctp_chunk *ch) | 76 | struct sctp_chunk *ch) |
| 77 | { | 77 | { |
| 78 | __skb_queue_head(&q->out, (struct sk_buff *)ch); | 78 | list_add(&ch->list, &q->out_chunk_list); |
| 79 | q->out_qlen += ch->skb->len; | 79 | q->out_qlen += ch->skb->len; |
| 80 | return; | 80 | return; |
| 81 | } | 81 | } |
| @@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(struct sctp_outq *q, | |||
| 83 | /* Take data from the front of the queue. */ | 83 | /* Take data from the front of the queue. */ |
| 84 | static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q) | 84 | static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q) |
| 85 | { | 85 | { |
| 86 | struct sctp_chunk *ch; | 86 | struct sctp_chunk *ch = NULL; |
| 87 | ch = (struct sctp_chunk *)__skb_dequeue(&q->out); | 87 | |
| 88 | if (ch) | 88 | if (!list_empty(&q->out_chunk_list)) { |
| 89 | struct list_head *entry = q->out_chunk_list.next; | ||
| 90 | |||
| 91 | ch = list_entry(entry, struct sctp_chunk, list); | ||
| 92 | list_del_init(entry); | ||
| 89 | q->out_qlen -= ch->skb->len; | 93 | q->out_qlen -= ch->skb->len; |
| 94 | } | ||
| 90 | return ch; | 95 | return ch; |
| 91 | } | 96 | } |
| 92 | /* Add data chunk to the end of the queue. */ | 97 | /* Add data chunk to the end of the queue. */ |
| 93 | static inline void sctp_outq_tail_data(struct sctp_outq *q, | 98 | static inline void sctp_outq_tail_data(struct sctp_outq *q, |
| 94 | struct sctp_chunk *ch) | 99 | struct sctp_chunk *ch) |
| 95 | { | 100 | { |
| 96 | __skb_queue_tail(&q->out, (struct sk_buff *)ch); | 101 | list_add_tail(&ch->list, &q->out_chunk_list); |
| 97 | q->out_qlen += ch->skb->len; | 102 | q->out_qlen += ch->skb->len; |
| 98 | return; | 103 | return; |
| 99 | } | 104 | } |
| @@ -197,8 +202,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, | |||
| 197 | void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | 202 | void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) |
| 198 | { | 203 | { |
| 199 | q->asoc = asoc; | 204 | q->asoc = asoc; |
| 200 | skb_queue_head_init(&q->out); | 205 | INIT_LIST_HEAD(&q->out_chunk_list); |
| 201 | skb_queue_head_init(&q->control); | 206 | INIT_LIST_HEAD(&q->control_chunk_list); |
| 202 | INIT_LIST_HEAD(&q->retransmit); | 207 | INIT_LIST_HEAD(&q->retransmit); |
| 203 | INIT_LIST_HEAD(&q->sacked); | 208 | INIT_LIST_HEAD(&q->sacked); |
| 204 | INIT_LIST_HEAD(&q->abandoned); | 209 | INIT_LIST_HEAD(&q->abandoned); |
| @@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq *q) | |||
| 217 | { | 222 | { |
| 218 | struct sctp_transport *transport; | 223 | struct sctp_transport *transport; |
| 219 | struct list_head *lchunk, *pos, *temp; | 224 | struct list_head *lchunk, *pos, *temp; |
| 220 | struct sctp_chunk *chunk; | 225 | struct sctp_chunk *chunk, *tmp; |
| 221 | 226 | ||
| 222 | /* Throw away unacknowledged chunks. */ | 227 | /* Throw away unacknowledged chunks. */ |
| 223 | list_for_each(pos, &q->asoc->peer.transport_addr_list) { | 228 | list_for_each(pos, &q->asoc->peer.transport_addr_list) { |
| @@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq *q) | |||
| 269 | q->error = 0; | 274 | q->error = 0; |
| 270 | 275 | ||
| 271 | /* Throw away any leftover control chunks. */ | 276 | /* Throw away any leftover control chunks. */ |
| 272 | while ((chunk = (struct sctp_chunk *) skb_dequeue(&q->control)) != NULL) | 277 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { |
| 278 | list_del_init(&chunk->list); | ||
| 273 | sctp_chunk_free(chunk); | 279 | sctp_chunk_free(chunk); |
| 280 | } | ||
| 274 | } | 281 | } |
| 275 | 282 | ||
| 276 | /* Free the outqueue structure and any related pending chunks. */ | 283 | /* Free the outqueue structure and any related pending chunks. */ |
| @@ -333,7 +340,7 @@ int sctp_outq_tail(struct sctp_outq *q, struct sctp_chunk *chunk) | |||
| 333 | break; | 340 | break; |
| 334 | }; | 341 | }; |
| 335 | } else { | 342 | } else { |
| 336 | __skb_queue_tail(&q->control, (struct sk_buff *) chunk); | 343 | list_add_tail(&chunk->list, &q->control_chunk_list); |
| 337 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 344 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); |
| 338 | } | 345 | } |
| 339 | 346 | ||
| @@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
| 650 | __u16 sport = asoc->base.bind_addr.port; | 657 | __u16 sport = asoc->base.bind_addr.port; |
| 651 | __u16 dport = asoc->peer.port; | 658 | __u16 dport = asoc->peer.port; |
| 652 | __u32 vtag = asoc->peer.i.init_tag; | 659 | __u32 vtag = asoc->peer.i.init_tag; |
| 653 | struct sk_buff_head *queue; | ||
| 654 | struct sctp_transport *transport = NULL; | 660 | struct sctp_transport *transport = NULL; |
| 655 | struct sctp_transport *new_transport; | 661 | struct sctp_transport *new_transport; |
| 656 | struct sctp_chunk *chunk; | 662 | struct sctp_chunk *chunk, *tmp; |
| 657 | sctp_xmit_t status; | 663 | sctp_xmit_t status; |
| 658 | int error = 0; | 664 | int error = 0; |
| 659 | int start_timer = 0; | 665 | int start_timer = 0; |
| @@ -675,8 +681,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
| 675 | * ... | 681 | * ... |
| 676 | */ | 682 | */ |
| 677 | 683 | ||
| 678 | queue = &q->control; | 684 | list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) { |
| 679 | while ((chunk = (struct sctp_chunk *)skb_dequeue(queue)) != NULL) { | 685 | list_del_init(&chunk->list); |
| 686 | |||
| 680 | /* Pick the right transport to use. */ | 687 | /* Pick the right transport to use. */ |
| 681 | new_transport = chunk->transport; | 688 | new_transport = chunk->transport; |
| 682 | 689 | ||
| @@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
| 814 | 821 | ||
| 815 | /* Finally, transmit new packets. */ | 822 | /* Finally, transmit new packets. */ |
| 816 | start_timer = 0; | 823 | start_timer = 0; |
| 817 | queue = &q->out; | ||
| 818 | |||
| 819 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { | 824 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { |
| 820 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid | 825 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid |
| 821 | * stream identifier. | 826 | * stream identifier. |
| @@ -1149,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack) | |||
| 1149 | /* See if all chunks are acked. | 1154 | /* See if all chunks are acked. |
| 1150 | * Make sure the empty queue handler will get run later. | 1155 | * Make sure the empty queue handler will get run later. |
| 1151 | */ | 1156 | */ |
| 1152 | q->empty = skb_queue_empty(&q->out) && skb_queue_empty(&q->control) && | 1157 | q->empty = (list_empty(&q->out_chunk_list) && |
| 1153 | list_empty(&q->retransmit); | 1158 | list_empty(&q->control_chunk_list) && |
| 1159 | list_empty(&q->retransmit)); | ||
| 1154 | if (!q->empty) | 1160 | if (!q->empty) |
| 1155 | goto finish; | 1161 | goto finish; |
| 1156 | 1162 | ||
| @@ -1679,9 +1685,9 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn) | |||
| 1679 | if (TSN_lte(tsn, ctsn)) { | 1685 | if (TSN_lte(tsn, ctsn)) { |
| 1680 | list_del_init(lchunk); | 1686 | list_del_init(lchunk); |
| 1681 | if (!chunk->tsn_gap_acked) { | 1687 | if (!chunk->tsn_gap_acked) { |
| 1682 | chunk->transport->flight_size -= | 1688 | chunk->transport->flight_size -= |
| 1683 | sctp_data_size(chunk); | 1689 | sctp_data_size(chunk); |
| 1684 | q->outstanding_bytes -= sctp_data_size(chunk); | 1690 | q->outstanding_bytes -= sctp_data_size(chunk); |
| 1685 | } | 1691 | } |
| 1686 | sctp_chunk_free(chunk); | 1692 | sctp_chunk_free(chunk); |
| 1687 | } else { | 1693 | } else { |
| @@ -1729,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn) | |||
| 1729 | nskips, &ftsn_skip_arr[0]); | 1735 | nskips, &ftsn_skip_arr[0]); |
| 1730 | 1736 | ||
| 1731 | if (ftsn_chunk) { | 1737 | if (ftsn_chunk) { |
| 1732 | __skb_queue_tail(&q->control, (struct sk_buff *)ftsn_chunk); | 1738 | list_add_tail(&ftsn_chunk->list, &q->control_chunk_list); |
| 1733 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); | 1739 | SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); |
| 1734 | } | 1740 | } |
| 1735 | } | 1741 | } |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 98d49ec9b74b..b74f7772b576 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -57,6 +57,7 @@ static struct snmp_mib sctp_snmp_list[] = { | |||
| 57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), | 57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), |
| 58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), | 58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), |
| 59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), | 59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), |
| 60 | SNMP_MIB_SENTINEL | ||
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| 62 | /* Return the current value of a particular entry in the mib by adding its | 63 | /* Return the current value of a particular entry in the mib by adding its |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5135e1a25d25..ce9245e71fca 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -219,7 +219,7 @@ static void sctp_free_local_addr_list(void) | |||
| 219 | 219 | ||
| 220 | /* Copy the local addresses which are valid for 'scope' into 'bp'. */ | 220 | /* Copy the local addresses which are valid for 'scope' into 'bp'. */ |
| 221 | int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, | 221 | int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, |
| 222 | int gfp, int copy_flags) | 222 | unsigned int __nocast gfp, int copy_flags) |
| 223 | { | 223 | { |
| 224 | struct sctp_sockaddr_entry *addr; | 224 | struct sctp_sockaddr_entry *addr; |
| 225 | int error = 0; | 225 | int error = 0; |
| @@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1050 | sctp_sndbuf_policy = 0; | 1050 | sctp_sndbuf_policy = 0; |
| 1051 | 1051 | ||
| 1052 | /* HB.interval - 30 seconds */ | 1052 | /* HB.interval - 30 seconds */ |
| 1053 | sctp_hb_interval = 30 * HZ; | 1053 | sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; |
| 1054 | |||
| 1055 | /* delayed SACK timeout */ | ||
| 1056 | sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK; | ||
| 1054 | 1057 | ||
| 1055 | /* Implementation specific variables. */ | 1058 | /* Implementation specific variables. */ |
| 1056 | 1059 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 5baed9bb7de5..00d32b7c8266 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
| @@ -78,7 +78,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep, | |||
| 78 | static int sctp_process_param(struct sctp_association *asoc, | 78 | static int sctp_process_param(struct sctp_association *asoc, |
| 79 | union sctp_params param, | 79 | union sctp_params param, |
| 80 | const union sctp_addr *peer_addr, | 80 | const union sctp_addr *peer_addr, |
| 81 | int gfp); | 81 | unsigned int __nocast gfp); |
| 82 | 82 | ||
| 83 | /* What was the inbound interface for this chunk? */ | 83 | /* What was the inbound interface for this chunk? */ |
| 84 | int sctp_chunk_iif(const struct sctp_chunk *chunk) | 84 | int sctp_chunk_iif(const struct sctp_chunk *chunk) |
| @@ -174,7 +174,7 @@ void sctp_init_cause(struct sctp_chunk *chunk, __u16 cause_code, | |||
| 174 | */ | 174 | */ |
| 175 | struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | 175 | struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, |
| 176 | const struct sctp_bind_addr *bp, | 176 | const struct sctp_bind_addr *bp, |
| 177 | int gfp, int vparam_len) | 177 | unsigned int __nocast gfp, int vparam_len) |
| 178 | { | 178 | { |
| 179 | sctp_inithdr_t init; | 179 | sctp_inithdr_t init; |
| 180 | union sctp_params addrs; | 180 | union sctp_params addrs; |
| @@ -261,7 +261,7 @@ nodata: | |||
| 261 | 261 | ||
| 262 | struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, | 262 | struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc, |
| 263 | const struct sctp_chunk *chunk, | 263 | const struct sctp_chunk *chunk, |
| 264 | int gfp, int unkparam_len) | 264 | unsigned int __nocast gfp, int unkparam_len) |
| 265 | { | 265 | { |
| 266 | sctp_inithdr_t initack; | 266 | sctp_inithdr_t initack; |
| 267 | struct sctp_chunk *retval; | 267 | struct sctp_chunk *retval; |
| @@ -1003,6 +1003,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb, | |||
| 1003 | SCTP_DEBUG_PRINTK("chunkifying skb %p w/o an sk\n", skb); | 1003 | SCTP_DEBUG_PRINTK("chunkifying skb %p w/o an sk\n", skb); |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| 1006 | INIT_LIST_HEAD(&retval->list); | ||
| 1006 | retval->skb = skb; | 1007 | retval->skb = skb; |
| 1007 | retval->asoc = (struct sctp_association *)asoc; | 1008 | retval->asoc = (struct sctp_association *)asoc; |
| 1008 | retval->resent = 0; | 1009 | retval->resent = 0; |
| @@ -1116,8 +1117,7 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk) | |||
| 1116 | /* Possibly, free the chunk. */ | 1117 | /* Possibly, free the chunk. */ |
| 1117 | void sctp_chunk_free(struct sctp_chunk *chunk) | 1118 | void sctp_chunk_free(struct sctp_chunk *chunk) |
| 1118 | { | 1119 | { |
| 1119 | /* Make sure that we are not on any list. */ | 1120 | BUG_ON(!list_empty(&chunk->list)); |
| 1120 | skb_unlink((struct sk_buff *) chunk); | ||
| 1121 | list_del_init(&chunk->transmitted_list); | 1121 | list_del_init(&chunk->transmitted_list); |
| 1122 | 1122 | ||
| 1123 | /* Release our reference on the message tracker. */ | 1123 | /* Release our reference on the message tracker. */ |
| @@ -1233,7 +1233,8 @@ void sctp_chunk_assign_tsn(struct sctp_chunk *chunk) | |||
| 1233 | 1233 | ||
| 1234 | /* Create a CLOSED association to use with an incoming packet. */ | 1234 | /* Create a CLOSED association to use with an incoming packet. */ |
| 1235 | struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, | 1235 | struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, |
| 1236 | struct sctp_chunk *chunk, int gfp) | 1236 | struct sctp_chunk *chunk, |
| 1237 | unsigned int __nocast gfp) | ||
| 1237 | { | 1238 | { |
| 1238 | struct sctp_association *asoc; | 1239 | struct sctp_association *asoc; |
| 1239 | struct sk_buff *skb; | 1240 | struct sk_buff *skb; |
| @@ -1348,7 +1349,7 @@ nodata: | |||
| 1348 | struct sctp_association *sctp_unpack_cookie( | 1349 | struct sctp_association *sctp_unpack_cookie( |
| 1349 | const struct sctp_endpoint *ep, | 1350 | const struct sctp_endpoint *ep, |
| 1350 | const struct sctp_association *asoc, | 1351 | const struct sctp_association *asoc, |
| 1351 | struct sctp_chunk *chunk, int gfp, | 1352 | struct sctp_chunk *chunk, unsigned int __nocast gfp, |
| 1352 | int *error, struct sctp_chunk **errp) | 1353 | int *error, struct sctp_chunk **errp) |
| 1353 | { | 1354 | { |
| 1354 | struct sctp_association *retval = NULL; | 1355 | struct sctp_association *retval = NULL; |
| @@ -1812,7 +1813,7 @@ int sctp_verify_init(const struct sctp_association *asoc, | |||
| 1812 | */ | 1813 | */ |
| 1813 | int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, | 1814 | int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, |
| 1814 | const union sctp_addr *peer_addr, | 1815 | const union sctp_addr *peer_addr, |
| 1815 | sctp_init_chunk_t *peer_init, int gfp) | 1816 | sctp_init_chunk_t *peer_init, unsigned int __nocast gfp) |
| 1816 | { | 1817 | { |
| 1817 | union sctp_params param; | 1818 | union sctp_params param; |
| 1818 | struct sctp_transport *transport; | 1819 | struct sctp_transport *transport; |
| @@ -1983,7 +1984,7 @@ nomem: | |||
| 1983 | static int sctp_process_param(struct sctp_association *asoc, | 1984 | static int sctp_process_param(struct sctp_association *asoc, |
| 1984 | union sctp_params param, | 1985 | union sctp_params param, |
| 1985 | const union sctp_addr *peer_addr, | 1986 | const union sctp_addr *peer_addr, |
| 1986 | int gfp) | 1987 | unsigned int __nocast gfp) |
| 1987 | { | 1988 | { |
| 1988 | union sctp_addr addr; | 1989 | union sctp_addr addr; |
| 1989 | int i; | 1990 | int i; |
| @@ -2739,8 +2740,12 @@ int sctp_process_asconf_ack(struct sctp_association *asoc, | |||
| 2739 | asoc->addip_last_asconf = NULL; | 2740 | asoc->addip_last_asconf = NULL; |
| 2740 | 2741 | ||
| 2741 | /* Send the next asconf chunk from the addip chunk queue. */ | 2742 | /* Send the next asconf chunk from the addip chunk queue. */ |
| 2742 | asconf = (struct sctp_chunk *)__skb_dequeue(&asoc->addip_chunks); | 2743 | if (!list_empty(&asoc->addip_chunk_list)) { |
| 2743 | if (asconf) { | 2744 | struct list_head *entry = asoc->addip_chunk_list.next; |
| 2745 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
| 2746 | |||
| 2747 | list_del_init(entry); | ||
| 2748 | |||
| 2744 | /* Hold the chunk until an ASCONF_ACK is received. */ | 2749 | /* Hold the chunk until an ASCONF_ACK is received. */ |
| 2745 | sctp_chunk_hold(asconf); | 2750 | sctp_chunk_hold(asconf); |
| 2746 | if (sctp_primitive_ASCONF(asoc, asconf)) | 2751 | if (sctp_primitive_ASCONF(asoc, asconf)) |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 778639db125a..39c970b5b198 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 63 | void *event_arg, | 63 | void *event_arg, |
| 64 | sctp_disposition_t status, | 64 | sctp_disposition_t status, |
| 65 | sctp_cmd_seq_t *commands, | 65 | sctp_cmd_seq_t *commands, |
| 66 | int gfp); | 66 | unsigned int __nocast gfp); |
| 67 | static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, | 67 | static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, |
| 68 | sctp_state_t state, | 68 | sctp_state_t state, |
| 69 | struct sctp_endpoint *ep, | 69 | struct sctp_endpoint *ep, |
| @@ -71,7 +71,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, | |||
| 71 | void *event_arg, | 71 | void *event_arg, |
| 72 | sctp_disposition_t status, | 72 | sctp_disposition_t status, |
| 73 | sctp_cmd_seq_t *commands, | 73 | sctp_cmd_seq_t *commands, |
| 74 | int gfp); | 74 | unsigned int __nocast gfp); |
| 75 | 75 | ||
| 76 | /******************************************************************** | 76 | /******************************************************************** |
| 77 | * Helper functions | 77 | * Helper functions |
| @@ -497,7 +497,8 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands, | |||
| 497 | static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, | 497 | static int sctp_cmd_process_init(sctp_cmd_seq_t *commands, |
| 498 | struct sctp_association *asoc, | 498 | struct sctp_association *asoc, |
| 499 | struct sctp_chunk *chunk, | 499 | struct sctp_chunk *chunk, |
| 500 | sctp_init_chunk_t *peer_init, int gfp) | 500 | sctp_init_chunk_t *peer_init, |
| 501 | unsigned int __nocast gfp) | ||
| 501 | { | 502 | { |
| 502 | int error; | 503 | int error; |
| 503 | 504 | ||
| @@ -852,7 +853,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype, | |||
| 852 | struct sctp_endpoint *ep, | 853 | struct sctp_endpoint *ep, |
| 853 | struct sctp_association *asoc, | 854 | struct sctp_association *asoc, |
| 854 | void *event_arg, | 855 | void *event_arg, |
| 855 | int gfp) | 856 | unsigned int __nocast gfp) |
| 856 | { | 857 | { |
| 857 | sctp_cmd_seq_t commands; | 858 | sctp_cmd_seq_t commands; |
| 858 | const sctp_sm_table_entry_t *state_fn; | 859 | const sctp_sm_table_entry_t *state_fn; |
| @@ -897,7 +898,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, | |||
| 897 | void *event_arg, | 898 | void *event_arg, |
| 898 | sctp_disposition_t status, | 899 | sctp_disposition_t status, |
| 899 | sctp_cmd_seq_t *commands, | 900 | sctp_cmd_seq_t *commands, |
| 900 | int gfp) | 901 | unsigned int __nocast gfp) |
| 901 | { | 902 | { |
| 902 | int error; | 903 | int error; |
| 903 | 904 | ||
| @@ -985,7 +986,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 985 | void *event_arg, | 986 | void *event_arg, |
| 986 | sctp_disposition_t status, | 987 | sctp_disposition_t status, |
| 987 | sctp_cmd_seq_t *commands, | 988 | sctp_cmd_seq_t *commands, |
| 988 | int gfp) | 989 | unsigned int __nocast gfp) |
| 989 | { | 990 | { |
| 990 | int error = 0; | 991 | int error = 0; |
| 991 | int force; | 992 | int force; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 058189684c7c..86073df418f5 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -92,6 +92,17 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep, | |||
| 92 | sctp_cmd_seq_t *commands); | 92 | sctp_cmd_seq_t *commands); |
| 93 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); | 93 | static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); |
| 94 | 94 | ||
| 95 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | ||
| 96 | __u16 error, | ||
| 97 | const struct sctp_association *asoc, | ||
| 98 | struct sctp_transport *transport); | ||
| 99 | |||
| 100 | static sctp_disposition_t sctp_sf_violation_chunklen( | ||
| 101 | const struct sctp_endpoint *ep, | ||
| 102 | const struct sctp_association *asoc, | ||
| 103 | const sctp_subtype_t type, | ||
| 104 | void *arg, | ||
| 105 | sctp_cmd_seq_t *commands); | ||
| 95 | 106 | ||
| 96 | /* Small helper function that checks if the chunk length | 107 | /* Small helper function that checks if the chunk length |
| 97 | * is of the appropriate length. The 'required_length' argument | 108 | * is of the appropriate length. The 'required_length' argument |
| @@ -2328,7 +2339,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep, | |||
| 2328 | * | 2339 | * |
| 2329 | * This is common code called by several sctp_sf_*_abort() functions above. | 2340 | * This is common code called by several sctp_sf_*_abort() functions above. |
| 2330 | */ | 2341 | */ |
| 2331 | sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, | 2342 | static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, |
| 2332 | __u16 error, | 2343 | __u16 error, |
| 2333 | const struct sctp_association *asoc, | 2344 | const struct sctp_association *asoc, |
| 2334 | struct sctp_transport *transport) | 2345 | struct sctp_transport *transport) |
| @@ -3687,7 +3698,8 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep, | |||
| 3687 | * | 3698 | * |
| 3688 | * Generate an ABORT chunk and terminate the association. | 3699 | * Generate an ABORT chunk and terminate the association. |
| 3689 | */ | 3700 | */ |
| 3690 | sctp_disposition_t sctp_sf_violation_chunklen(const struct sctp_endpoint *ep, | 3701 | static sctp_disposition_t sctp_sf_violation_chunklen( |
| 3702 | const struct sctp_endpoint *ep, | ||
| 3691 | const struct sctp_association *asoc, | 3703 | const struct sctp_association *asoc, |
| 3692 | const sctp_subtype_t type, | 3704 | const sctp_subtype_t type, |
| 3693 | void *arg, | 3705 | void *arg, |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index aad55dc3792b..091a66f06a35 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -406,7 +406,7 @@ static int sctp_send_asconf(struct sctp_association *asoc, | |||
| 406 | * transmission. | 406 | * transmission. |
| 407 | */ | 407 | */ |
| 408 | if (asoc->addip_last_asconf) { | 408 | if (asoc->addip_last_asconf) { |
| 409 | __skb_queue_tail(&asoc->addip_chunks, (struct sk_buff *)chunk); | 409 | list_add_tail(&chunk->list, &asoc->addip_chunk_list); |
| 410 | goto out; | 410 | goto out; |
| 411 | } | 411 | } |
| 412 | 412 | ||
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c index e627d2b451b6..25037daf3fa0 100644 --- a/net/sctp/ssnmap.c +++ b/net/sctp/ssnmap.c | |||
| @@ -57,7 +57,8 @@ static inline size_t sctp_ssnmap_size(__u16 in, __u16 out) | |||
| 57 | /* Create a new sctp_ssnmap. | 57 | /* Create a new sctp_ssnmap. |
| 58 | * Allocate room to store at least 'len' contiguous TSNs. | 58 | * Allocate room to store at least 'len' contiguous TSNs. |
| 59 | */ | 59 | */ |
| 60 | struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp) | 60 | struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, |
| 61 | unsigned int __nocast gfp) | ||
| 61 | { | 62 | { |
| 62 | struct sctp_ssnmap *retval; | 63 | struct sctp_ssnmap *retval; |
| 63 | int size; | 64 | int size; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7fc31849312b..dc4893474f18 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
| @@ -47,6 +47,8 @@ | |||
| 47 | static ctl_handler sctp_sysctl_jiffies_ms; | 47 | static ctl_handler sctp_sysctl_jiffies_ms; |
| 48 | static long rto_timer_min = 1; | 48 | static long rto_timer_min = 1; |
| 49 | static long rto_timer_max = 86400000; /* One day */ | 49 | static long rto_timer_max = 86400000; /* One day */ |
| 50 | static long sack_timer_min = 1; | ||
| 51 | static long sack_timer_max = 500; | ||
| 50 | 52 | ||
| 51 | static ctl_table sctp_table[] = { | 53 | static ctl_table sctp_table[] = { |
| 52 | { | 54 | { |
| @@ -187,6 +189,17 @@ static ctl_table sctp_table[] = { | |||
| 187 | .mode = 0644, | 189 | .mode = 0644, |
| 188 | .proc_handler = &proc_dointvec | 190 | .proc_handler = &proc_dointvec |
| 189 | }, | 191 | }, |
| 192 | { | ||
| 193 | .ctl_name = NET_SCTP_SACK_TIMEOUT, | ||
| 194 | .procname = "sack_timeout", | ||
| 195 | .data = &sctp_sack_timeout, | ||
| 196 | .maxlen = sizeof(long), | ||
| 197 | .mode = 0644, | ||
| 198 | .proc_handler = &proc_doulongvec_ms_jiffies_minmax, | ||
| 199 | .strategy = &sctp_sysctl_jiffies_ms, | ||
| 200 | .extra1 = &sack_timer_min, | ||
| 201 | .extra2 = &sack_timer_max, | ||
| 202 | }, | ||
| 190 | { .ctl_name = 0 } | 203 | { .ctl_name = 0 } |
| 191 | }; | 204 | }; |
| 192 | 205 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0ec0fde6e6c5..d2f04ebe5081 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -57,7 +57,7 @@ | |||
| 57 | /* Initialize a new transport from provided memory. */ | 57 | /* Initialize a new transport from provided memory. */ |
| 58 | static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | 58 | static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, |
| 59 | const union sctp_addr *addr, | 59 | const union sctp_addr *addr, |
| 60 | int gfp) | 60 | unsigned int __nocast gfp) |
| 61 | { | 61 | { |
| 62 | /* Copy in the address. */ | 62 | /* Copy in the address. */ |
| 63 | peer->ipaddr = *addr; | 63 | peer->ipaddr = *addr; |
| @@ -103,7 +103,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
| 103 | 103 | ||
| 104 | /* Set up the heartbeat timer. */ | 104 | /* Set up the heartbeat timer. */ |
| 105 | init_timer(&peer->hb_timer); | 105 | init_timer(&peer->hb_timer); |
| 106 | peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; | ||
| 107 | peer->hb_timer.function = sctp_generate_heartbeat_event; | 106 | peer->hb_timer.function = sctp_generate_heartbeat_event; |
| 108 | peer->hb_timer.data = (unsigned long)peer; | 107 | peer->hb_timer.data = (unsigned long)peer; |
| 109 | 108 | ||
| @@ -122,7 +121,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | /* Allocate and initialize a new transport. */ | 123 | /* Allocate and initialize a new transport. */ |
| 125 | struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp) | 124 | struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, |
| 125 | unsigned int __nocast gfp) | ||
| 126 | { | 126 | { |
| 127 | struct sctp_transport *transport; | 127 | struct sctp_transport *transport; |
| 128 | 128 | ||
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 17d0ff534735..0abd5101107c 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -74,7 +74,7 @@ SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) | |||
| 74 | 74 | ||
| 75 | /* Create a new sctp_ulpevent. */ | 75 | /* Create a new sctp_ulpevent. */ |
| 76 | SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, | 76 | SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags, |
| 77 | int gfp) | 77 | unsigned int __nocast gfp) |
| 78 | { | 78 | { |
| 79 | struct sctp_ulpevent *event; | 79 | struct sctp_ulpevent *event; |
| 80 | struct sk_buff *skb; | 80 | struct sk_buff *skb; |
| @@ -136,7 +136,7 @@ static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) | |||
| 136 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | 136 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( |
| 137 | const struct sctp_association *asoc, | 137 | const struct sctp_association *asoc, |
| 138 | __u16 flags, __u16 state, __u16 error, __u16 outbound, | 138 | __u16 flags, __u16 state, __u16 error, __u16 outbound, |
| 139 | __u16 inbound, int gfp) | 139 | __u16 inbound, unsigned int __nocast gfp) |
| 140 | { | 140 | { |
| 141 | struct sctp_ulpevent *event; | 141 | struct sctp_ulpevent *event; |
| 142 | struct sctp_assoc_change *sac; | 142 | struct sctp_assoc_change *sac; |
| @@ -237,7 +237,7 @@ fail: | |||
| 237 | struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( | 237 | struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change( |
| 238 | const struct sctp_association *asoc, | 238 | const struct sctp_association *asoc, |
| 239 | const struct sockaddr_storage *aaddr, | 239 | const struct sockaddr_storage *aaddr, |
| 240 | int flags, int state, int error, int gfp) | 240 | int flags, int state, int error, unsigned int __nocast gfp) |
| 241 | { | 241 | { |
| 242 | struct sctp_ulpevent *event; | 242 | struct sctp_ulpevent *event; |
| 243 | struct sctp_paddr_change *spc; | 243 | struct sctp_paddr_change *spc; |
| @@ -350,7 +350,7 @@ fail: | |||
| 350 | */ | 350 | */ |
| 351 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( | 351 | struct sctp_ulpevent *sctp_ulpevent_make_remote_error( |
| 352 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | 352 | const struct sctp_association *asoc, struct sctp_chunk *chunk, |
| 353 | __u16 flags, int gfp) | 353 | __u16 flags, unsigned int __nocast gfp) |
| 354 | { | 354 | { |
| 355 | struct sctp_ulpevent *event; | 355 | struct sctp_ulpevent *event; |
| 356 | struct sctp_remote_error *sre; | 356 | struct sctp_remote_error *sre; |
| @@ -448,7 +448,7 @@ fail: | |||
| 448 | */ | 448 | */ |
| 449 | struct sctp_ulpevent *sctp_ulpevent_make_send_failed( | 449 | struct sctp_ulpevent *sctp_ulpevent_make_send_failed( |
| 450 | const struct sctp_association *asoc, struct sctp_chunk *chunk, | 450 | const struct sctp_association *asoc, struct sctp_chunk *chunk, |
| 451 | __u16 flags, __u32 error, int gfp) | 451 | __u16 flags, __u32 error, unsigned int __nocast gfp) |
| 452 | { | 452 | { |
| 453 | struct sctp_ulpevent *event; | 453 | struct sctp_ulpevent *event; |
| 454 | struct sctp_send_failed *ssf; | 454 | struct sctp_send_failed *ssf; |
| @@ -557,7 +557,7 @@ fail: | |||
| 557 | */ | 557 | */ |
| 558 | struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( | 558 | struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( |
| 559 | const struct sctp_association *asoc, | 559 | const struct sctp_association *asoc, |
| 560 | __u16 flags, int gfp) | 560 | __u16 flags, unsigned int __nocast gfp) |
| 561 | { | 561 | { |
| 562 | struct sctp_ulpevent *event; | 562 | struct sctp_ulpevent *event; |
| 563 | struct sctp_shutdown_event *sse; | 563 | struct sctp_shutdown_event *sse; |
| @@ -620,7 +620,7 @@ fail: | |||
| 620 | * 5.3.1.6 SCTP_ADAPTION_INDICATION | 620 | * 5.3.1.6 SCTP_ADAPTION_INDICATION |
| 621 | */ | 621 | */ |
| 622 | struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication( | 622 | struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication( |
| 623 | const struct sctp_association *asoc, int gfp) | 623 | const struct sctp_association *asoc, unsigned int __nocast gfp) |
| 624 | { | 624 | { |
| 625 | struct sctp_ulpevent *event; | 625 | struct sctp_ulpevent *event; |
| 626 | struct sctp_adaption_event *sai; | 626 | struct sctp_adaption_event *sai; |
| @@ -657,7 +657,7 @@ fail: | |||
| 657 | */ | 657 | */ |
| 658 | struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | 658 | struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, |
| 659 | struct sctp_chunk *chunk, | 659 | struct sctp_chunk *chunk, |
| 660 | int gfp) | 660 | unsigned int __nocast gfp) |
| 661 | { | 661 | { |
| 662 | struct sctp_ulpevent *event = NULL; | 662 | struct sctp_ulpevent *event = NULL; |
| 663 | struct sk_buff *skb; | 663 | struct sk_buff *skb; |
| @@ -718,7 +718,8 @@ fail: | |||
| 718 | * various events. | 718 | * various events. |
| 719 | */ | 719 | */ |
| 720 | struct sctp_ulpevent *sctp_ulpevent_make_pdapi( | 720 | struct sctp_ulpevent *sctp_ulpevent_make_pdapi( |
| 721 | const struct sctp_association *asoc, __u32 indication, int gfp) | 721 | const struct sctp_association *asoc, __u32 indication, |
| 722 | unsigned int __nocast gfp) | ||
| 722 | { | 723 | { |
| 723 | struct sctp_ulpevent *event; | 724 | struct sctp_ulpevent *event; |
| 724 | struct sctp_pdapi_event *pd; | 725 | struct sctp_pdapi_event *pd; |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index d5dd2cf7ac4a..8bbc279d6c99 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
| @@ -100,7 +100,7 @@ void sctp_ulpq_free(struct sctp_ulpq *ulpq) | |||
| 100 | 100 | ||
| 101 | /* Process an incoming DATA chunk. */ | 101 | /* Process an incoming DATA chunk. */ |
| 102 | int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | 102 | int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, |
| 103 | int gfp) | 103 | unsigned int __nocast gfp) |
| 104 | { | 104 | { |
| 105 | struct sk_buff_head temp; | 105 | struct sk_buff_head temp; |
| 106 | sctp_data_chunk_t *hdr; | 106 | sctp_data_chunk_t *hdr; |
| @@ -778,7 +778,8 @@ static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed) | |||
| 778 | 778 | ||
| 779 | /* Partial deliver the first message as there is pressure on rwnd. */ | 779 | /* Partial deliver the first message as there is pressure on rwnd. */ |
| 780 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, | 780 | void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, |
| 781 | struct sctp_chunk *chunk, int gfp) | 781 | struct sctp_chunk *chunk, |
| 782 | unsigned int __nocast gfp) | ||
| 782 | { | 783 | { |
| 783 | struct sctp_ulpevent *event; | 784 | struct sctp_ulpevent *event; |
| 784 | struct sctp_association *asoc; | 785 | struct sctp_association *asoc; |
| @@ -802,7 +803,7 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, | |||
| 802 | 803 | ||
| 803 | /* Renege some packets to make room for an incoming chunk. */ | 804 | /* Renege some packets to make room for an incoming chunk. */ |
| 804 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | 805 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, |
| 805 | int gfp) | 806 | unsigned int __nocast gfp) |
| 806 | { | 807 | { |
| 807 | struct sctp_association *asoc; | 808 | struct sctp_association *asoc; |
| 808 | __u16 needed, freed; | 809 | __u16 needed, freed; |
| @@ -841,7 +842,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | |||
| 841 | /* Notify the application if an association is aborted and in | 842 | /* Notify the application if an association is aborted and in |
| 842 | * partial delivery mode. Send up any pending received messages. | 843 | * partial delivery mode. Send up any pending received messages. |
| 843 | */ | 844 | */ |
| 844 | void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, int gfp) | 845 | void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, unsigned int __nocast gfp) |
| 845 | { | 846 | { |
| 846 | struct sctp_ulpevent *ev = NULL; | 847 | struct sctp_ulpevent *ev = NULL; |
| 847 | struct sock *sk; | 848 | struct sock *sk; |
