aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-05-12 19:20:04 -0400
committerThomas Gleixner <tglx@linutronix.de>2010-05-12 19:20:04 -0400
commit1540c84b5ed657ed71dce06915bba461e6b09574 (patch)
treea449dc166800a1b0c429bb038bfc974e577eaf72 /net/sctp
parent1a3a403aa98b0ccabeb12abd7da90d33250ea36b (diff)
parent4640b4e7d9919e9629fe8456df94f71658431ef9 (diff)
Merge branch '2.6.33.4' into rt/2.6.33
Conflicts: Makefile Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/associola.c6
-rw-r--r--net/sctp/endpointola.c1
-rw-r--r--net/sctp/sm_make_chunk.c32
-rw-r--r--net/sctp/sm_sideeffect.c26
-rw-r--r--net/sctp/sm_statefuns.c8
-rw-r--r--net/sctp/socket.c14
6 files changed, 60 insertions, 27 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index df5abbff63e2..99c93ee98ad9 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc,
1194 /* Remove any peer addresses not present in the new association. */ 1194 /* Remove any peer addresses not present in the new association. */
1195 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 1195 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1196 trans = list_entry(pos, struct sctp_transport, transports); 1196 trans = list_entry(pos, struct sctp_transport, transports);
1197 if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) 1197 if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) {
1198 sctp_assoc_del_peer(asoc, &trans->ipaddr); 1198 sctp_assoc_rm_peer(asoc, trans);
1199 continue;
1200 }
1199 1201
1200 if (asoc->state >= SCTP_STATE_ESTABLISHED) 1202 if (asoc->state >= SCTP_STATE_ESTABLISHED)
1201 sctp_transport_reset(trans); 1203 sctp_transport_reset(trans);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 905fda582b92..7ec09ba03a1c 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
144 /* Use SCTP specific send buffer space queues. */ 144 /* Use SCTP specific send buffer space queues. */
145 ep->sndbuf_policy = sctp_sndbuf_policy; 145 ep->sndbuf_policy = sctp_sndbuf_policy;
146 146
147 sk->sk_data_ready = sctp_data_ready;
147 sk->sk_write_space = sctp_write_space; 148 sk->sk_write_space = sctp_write_space;
148 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 149 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
149 150
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 9e732916b671..224db014fb6b 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -207,7 +207,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
207 sp = sctp_sk(asoc->base.sk); 207 sp = sctp_sk(asoc->base.sk);
208 num_types = sp->pf->supported_addrs(sp, types); 208 num_types = sp->pf->supported_addrs(sp, types);
209 209
210 chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); 210 chunksize = sizeof(init) + addrs_len;
211 chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
211 chunksize += sizeof(ecap_param); 212 chunksize += sizeof(ecap_param);
212 213
213 if (sctp_prsctp_enable) 214 if (sctp_prsctp_enable)
@@ -237,14 +238,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
237 /* Add HMACS parameter length if any were defined */ 238 /* Add HMACS parameter length if any were defined */
238 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; 239 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
239 if (auth_hmacs->length) 240 if (auth_hmacs->length)
240 chunksize += ntohs(auth_hmacs->length); 241 chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
241 else 242 else
242 auth_hmacs = NULL; 243 auth_hmacs = NULL;
243 244
244 /* Add CHUNKS parameter length */ 245 /* Add CHUNKS parameter length */
245 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; 246 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
246 if (auth_chunks->length) 247 if (auth_chunks->length)
247 chunksize += ntohs(auth_chunks->length); 248 chunksize += WORD_ROUND(ntohs(auth_chunks->length));
248 else 249 else
249 auth_chunks = NULL; 250 auth_chunks = NULL;
250 251
@@ -254,7 +255,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
254 255
255 /* If we have any extensions to report, account for that */ 256 /* If we have any extensions to report, account for that */
256 if (num_ext) 257 if (num_ext)
257 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; 258 chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
259 num_ext);
258 260
259 /* RFC 2960 3.3.2 Initiation (INIT) (1) 261 /* RFC 2960 3.3.2 Initiation (INIT) (1)
260 * 262 *
@@ -396,13 +398,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
396 398
397 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; 399 auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
398 if (auth_hmacs->length) 400 if (auth_hmacs->length)
399 chunksize += ntohs(auth_hmacs->length); 401 chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
400 else 402 else
401 auth_hmacs = NULL; 403 auth_hmacs = NULL;
402 404
403 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; 405 auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
404 if (auth_chunks->length) 406 if (auth_chunks->length)
405 chunksize += ntohs(auth_chunks->length); 407 chunksize += WORD_ROUND(ntohs(auth_chunks->length));
406 else 408 else
407 auth_chunks = NULL; 409 auth_chunks = NULL;
408 410
@@ -411,7 +413,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
411 } 413 }
412 414
413 if (num_ext) 415 if (num_ext)
414 chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; 416 chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
417 num_ext);
415 418
416 /* Now allocate and fill out the chunk. */ 419 /* Now allocate and fill out the chunk. */
417 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); 420 retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
@@ -3314,21 +3317,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
3314 sctp_chunk_free(asconf); 3317 sctp_chunk_free(asconf);
3315 asoc->addip_last_asconf = NULL; 3318 asoc->addip_last_asconf = NULL;
3316 3319
3317 /* Send the next asconf chunk from the addip chunk queue. */
3318 if (!list_empty(&asoc->addip_chunk_list)) {
3319 struct list_head *entry = asoc->addip_chunk_list.next;
3320 asconf = list_entry(entry, struct sctp_chunk, list);
3321
3322 list_del_init(entry);
3323
3324 /* Hold the chunk until an ASCONF_ACK is received. */
3325 sctp_chunk_hold(asconf);
3326 if (sctp_primitive_ASCONF(asoc, asconf))
3327 sctp_chunk_free(asconf);
3328 else
3329 asoc->addip_last_asconf = asconf;
3330 }
3331
3332 return retval; 3320 return retval;
3333} 3321}
3334 3322
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 4e4ca65cd320..42bbb2410550 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -961,6 +961,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
961} 961}
962 962
963 963
964/* Sent the next ASCONF packet currently stored in the association.
965 * This happens after the ASCONF_ACK was succeffully processed.
966 */
967static void sctp_cmd_send_asconf(struct sctp_association *asoc)
968{
969 /* Send the next asconf chunk from the addip chunk
970 * queue.
971 */
972 if (!list_empty(&asoc->addip_chunk_list)) {
973 struct list_head *entry = asoc->addip_chunk_list.next;
974 struct sctp_chunk *asconf = list_entry(entry,
975 struct sctp_chunk, list);
976 list_del_init(entry);
977
978 /* Hold the chunk until an ASCONF_ACK is received. */
979 sctp_chunk_hold(asconf);
980 if (sctp_primitive_ASCONF(asoc, asconf))
981 sctp_chunk_free(asconf);
982 else
983 asoc->addip_last_asconf = asconf;
984 }
985}
986
964 987
965/* These three macros allow us to pull the debugging code out of the 988/* These three macros allow us to pull the debugging code out of the
966 * main flow of sctp_do_sm() to keep attention focused on the real 989 * main flow of sctp_do_sm() to keep attention focused on the real
@@ -1616,6 +1639,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1616 } 1639 }
1617 error = sctp_cmd_send_msg(asoc, cmd->obj.msg); 1640 error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
1618 break; 1641 break;
1642 case SCTP_CMD_SEND_NEXT_ASCONF:
1643 sctp_cmd_send_asconf(asoc);
1644 break;
1619 default: 1645 default:
1620 printk(KERN_WARNING "Impossible command: %u, %p\n", 1646 printk(KERN_WARNING "Impossible command: %u, %p\n",
1621 cmd->verb, cmd->obj.ptr); 1647 cmd->verb, cmd->obj.ptr);
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 47bc20d3a85b..c3f75e79bedc 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3675,8 +3675,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3675 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); 3675 SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
3676 3676
3677 if (!sctp_process_asconf_ack((struct sctp_association *)asoc, 3677 if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
3678 asconf_ack)) 3678 asconf_ack)) {
3679 /* Successfully processed ASCONF_ACK. We can
3680 * release the next asconf if we have one.
3681 */
3682 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF,
3683 SCTP_NULL());
3679 return SCTP_DISPOSITION_CONSUME; 3684 return SCTP_DISPOSITION_CONSUME;
3685 }
3680 3686
3681 abort = sctp_make_abort(asoc, asconf_ack, 3687 abort = sctp_make_abort(asoc, asconf_ack,
3682 sizeof(sctp_errhdr_t)); 3688 sizeof(sctp_errhdr_t));
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9bd9d82a70c3..aa3ba60de54c 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3718,12 +3718,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3718 sp->hmac = NULL; 3718 sp->hmac = NULL;
3719 3719
3720 SCTP_DBG_OBJCNT_INC(sock); 3720 SCTP_DBG_OBJCNT_INC(sock);
3721 percpu_counter_inc(&sctp_sockets_allocated);
3722 3721
3723 /* Set socket backlog limit. */ 3722 /* Set socket backlog limit. */
3724 sk->sk_backlog.limit = sysctl_sctp_rmem[1]; 3723 sk->sk_backlog.limit = sysctl_sctp_rmem[1];
3725 3724
3726 local_bh_disable(); 3725 local_bh_disable();
3726 percpu_counter_inc(&sctp_sockets_allocated);
3727 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 3727 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
3728 local_bh_enable(); 3728 local_bh_enable();
3729 3729
@@ -3740,8 +3740,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
3740 /* Release our hold on the endpoint. */ 3740 /* Release our hold on the endpoint. */
3741 ep = sctp_sk(sk)->ep; 3741 ep = sctp_sk(sk)->ep;
3742 sctp_endpoint_free(ep); 3742 sctp_endpoint_free(ep);
3743 percpu_counter_dec(&sctp_sockets_allocated);
3744 local_bh_disable(); 3743 local_bh_disable();
3744 percpu_counter_dec(&sctp_sockets_allocated);
3745 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 3745 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
3746 local_bh_enable(); 3746 local_bh_enable();
3747} 3747}
@@ -6188,6 +6188,16 @@ do_nonblock:
6188 goto out; 6188 goto out;
6189} 6189}
6190 6190
6191void sctp_data_ready(struct sock *sk, int len)
6192{
6193 read_lock_bh(&sk->sk_callback_lock);
6194 if (sk_has_sleeper(sk))
6195 wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
6196 POLLRDNORM | POLLRDBAND);
6197 sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
6198 read_unlock_bh(&sk->sk_callback_lock);
6199}
6200
6191/* If socket sndbuf has changed, wake up all per association waiters. */ 6201/* If socket sndbuf has changed, wake up all per association waiters. */
6192void sctp_write_space(struct sock *sk) 6202void sctp_write_space(struct sock *sk)
6193{ 6203{