aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/debug.c4
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c14
-rw-r--r--net/sctp/ipv6.c36
-rw-r--r--net/sctp/output.c21
-rw-r--r--net/sctp/outqueue.c6
-rw-r--r--net/sctp/protocol.c31
-rw-r--r--net/sctp/sm_make_chunk.c37
-rw-r--r--net/sctp/sm_sideeffect.c43
-rw-r--r--net/sctp/sm_statefuns.c6
-rw-r--r--net/sctp/socket.c216
-rw-r--r--net/sctp/transport.c9
12 files changed, 191 insertions, 235 deletions
diff --git a/net/sctp/debug.c b/net/sctp/debug.c
index 67715f4eb849..7ff548a30cfb 100644
--- a/net/sctp/debug.c
+++ b/net/sctp/debug.c
@@ -86,6 +86,9 @@ const char *sctp_cname(const sctp_subtype_t cid)
86 case SCTP_CID_FWD_TSN: 86 case SCTP_CID_FWD_TSN:
87 return "FWD_TSN"; 87 return "FWD_TSN";
88 88
89 case SCTP_CID_AUTH:
90 return "AUTH";
91
89 default: 92 default:
90 break; 93 break;
91 } 94 }
@@ -135,6 +138,7 @@ static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = {
135 "PRIMITIVE_ABORT", 138 "PRIMITIVE_ABORT",
136 "PRIMITIVE_SEND", 139 "PRIMITIVE_SEND",
137 "PRIMITIVE_REQUESTHEARTBEAT", 140 "PRIMITIVE_REQUESTHEARTBEAT",
141 "PRIMITIVE_ASCONF",
138}; 142};
139 143
140/* Lookup primitive debug name. */ 144/* Lookup primitive debug name. */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 4c8d9f45ce09..905fda582b92 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -111,7 +111,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
111 if (sctp_addip_enable) { 111 if (sctp_addip_enable) {
112 auth_chunks->chunks[0] = SCTP_CID_ASCONF; 112 auth_chunks->chunks[0] = SCTP_CID_ASCONF;
113 auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; 113 auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
114 auth_chunks->param_hdr.length += htons(2); 114 auth_chunks->param_hdr.length =
115 htons(sizeof(sctp_paramhdr_t) + 2);
115 } 116 }
116 } 117 }
117 118
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 2e4a8646dbc3..d2e98803ffe3 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -83,14 +83,15 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb)
83{ 83{
84 struct sk_buff *list = skb_shinfo(skb)->frag_list; 84 struct sk_buff *list = skb_shinfo(skb)->frag_list;
85 struct sctphdr *sh = sctp_hdr(skb); 85 struct sctphdr *sh = sctp_hdr(skb);
86 __be32 cmp = sh->checksum; 86 __le32 cmp = sh->checksum;
87 __be32 val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb)); 87 __le32 val;
88 __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
88 89
89 for (; list; list = list->next) 90 for (; list; list = list->next)
90 val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list), 91 tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
91 val); 92 tmp);
92 93
93 val = sctp_end_cksum(val); 94 val = sctp_end_cksum(tmp);
94 95
95 if (val != cmp) { 96 if (val != cmp) {
96 /* CRC failure, dump it. */ 97 /* CRC failure, dump it. */
@@ -142,7 +143,8 @@ int sctp_rcv(struct sk_buff *skb)
142 __skb_pull(skb, skb_transport_offset(skb)); 143 __skb_pull(skb, skb_transport_offset(skb));
143 if (skb->len < sizeof(struct sctphdr)) 144 if (skb->len < sizeof(struct sctphdr))
144 goto discard_it; 145 goto discard_it;
145 if (!skb_csum_unnecessary(skb) && sctp_rcv_checksum(skb) < 0) 146 if (!sctp_checksum_disable && !skb_csum_unnecessary(skb) &&
147 sctp_rcv_checksum(skb) < 0)
146 goto discard_it; 148 goto discard_it;
147 149
148 skb_pull(skb, sizeof(struct sctphdr)); 150 skb_pull(skb, sizeof(struct sctphdr));
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index ceaa4aa066ea..a63de3f7f185 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -97,8 +97,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
97 if (addr) { 97 if (addr) {
98 addr->a.v6.sin6_family = AF_INET6; 98 addr->a.v6.sin6_family = AF_INET6;
99 addr->a.v6.sin6_port = 0; 99 addr->a.v6.sin6_port = 0;
100 memcpy(&addr->a.v6.sin6_addr, &ifa->addr, 100 ipv6_addr_copy(&addr->a.v6.sin6_addr, &ifa->addr);
101 sizeof(struct in6_addr));
102 addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; 101 addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
103 addr->valid = 1; 102 addr->valid = 1;
104 spin_lock_bh(&sctp_local_addr_lock); 103 spin_lock_bh(&sctp_local_addr_lock);
@@ -628,9 +627,7 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
628static struct sock *sctp_v6_create_accept_sk(struct sock *sk, 627static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
629 struct sctp_association *asoc) 628 struct sctp_association *asoc)
630{ 629{
631 struct inet_sock *inet = inet_sk(sk);
632 struct sock *newsk; 630 struct sock *newsk;
633 struct inet_sock *newinet;
634 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 631 struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
635 struct sctp6_sock *newsctp6sk; 632 struct sctp6_sock *newsctp6sk;
636 633
@@ -640,17 +637,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
640 637
641 sock_init_data(NULL, newsk); 638 sock_init_data(NULL, newsk);
642 639
643 newsk->sk_type = SOCK_STREAM; 640 sctp_copy_sock(newsk, sk, asoc);
644
645 newsk->sk_prot = sk->sk_prot;
646 newsk->sk_no_check = sk->sk_no_check;
647 newsk->sk_reuse = sk->sk_reuse;
648
649 newsk->sk_destruct = inet_sock_destruct;
650 newsk->sk_family = PF_INET6;
651 newsk->sk_protocol = IPPROTO_SCTP;
652 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
653 newsk->sk_shutdown = sk->sk_shutdown;
654 sock_reset_flag(sk, SOCK_ZAPPED); 641 sock_reset_flag(sk, SOCK_ZAPPED);
655 642
656 newsctp6sk = (struct sctp6_sock *)newsk; 643 newsctp6sk = (struct sctp6_sock *)newsk;
@@ -658,7 +645,6 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
658 645
659 sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped; 646 sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped;
660 647
661 newinet = inet_sk(newsk);
662 newnp = inet6_sk(newsk); 648 newnp = inet6_sk(newsk);
663 649
664 memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 650 memcpy(newnp, np, sizeof(struct ipv6_pinfo));
@@ -666,26 +652,8 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
666 /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname() 652 /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
667 * and getpeername(). 653 * and getpeername().
668 */ 654 */
669 newinet->sport = inet->sport;
670 newnp->saddr = np->saddr;
671 newnp->rcv_saddr = np->rcv_saddr;
672 newinet->dport = htons(asoc->peer.port);
673 sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk); 655 sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk);
674 656
675 /* Init the ipv4 part of the socket since we can have sockets
676 * using v6 API for ipv4.
677 */
678 newinet->uc_ttl = -1;
679 newinet->mc_loop = 1;
680 newinet->mc_ttl = 1;
681 newinet->mc_index = 0;
682 newinet->mc_list = NULL;
683
684 if (ipv4_config.no_pmtu_disc)
685 newinet->pmtudisc = IP_PMTUDISC_DONT;
686 else
687 newinet->pmtudisc = IP_PMTUDISC_WANT;
688
689 sk_refcnt_debug_inc(newsk); 657 sk_refcnt_debug_inc(newsk);
690 658
691 if (newsk->sk_prot->init(newsk)) { 659 if (newsk->sk_prot->init(newsk)) {
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 73639355157e..7d08f522ec84 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -49,13 +49,10 @@
49#include <linux/ipv6.h> 49#include <linux/ipv6.h>
50#include <linux/init.h> 50#include <linux/init.h>
51#include <net/inet_ecn.h> 51#include <net/inet_ecn.h>
52#include <net/ip.h>
52#include <net/icmp.h> 53#include <net/icmp.h>
53#include <net/net_namespace.h> 54#include <net/net_namespace.h>
54 55
55#ifndef TEST_FRAME
56#include <net/tcp.h>
57#endif /* TEST_FRAME (not defined) */
58
59#include <linux/socket.h> /* for sa_family_t */ 56#include <linux/socket.h> /* for sa_family_t */
60#include <net/sock.h> 57#include <net/sock.h>
61 58
@@ -367,7 +364,6 @@ int sctp_packet_transmit(struct sctp_packet *packet)
367 struct sctp_transport *tp = packet->transport; 364 struct sctp_transport *tp = packet->transport;
368 struct sctp_association *asoc = tp->asoc; 365 struct sctp_association *asoc = tp->asoc;
369 struct sctphdr *sh; 366 struct sctphdr *sh;
370 __be32 crc32 = __constant_cpu_to_be32(0);
371 struct sk_buff *nskb; 367 struct sk_buff *nskb;
372 struct sctp_chunk *chunk, *tmp; 368 struct sctp_chunk *chunk, *tmp;
373 struct sock *sk; 369 struct sock *sk;
@@ -531,17 +527,16 @@ int sctp_packet_transmit(struct sctp_packet *packet)
531 * Note: Adler-32 is no longer applicable, as has been replaced 527 * Note: Adler-32 is no longer applicable, as has been replaced
532 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 528 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
533 */ 529 */
534 if (!(dst->dev->features & NETIF_F_NO_CSUM)) { 530 if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
535 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 531 __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
536 crc32 = sctp_end_cksum(crc32); 532
533 /* 3) Put the resultant value into the checksum field in the
534 * common header, and leave the rest of the bits unchanged.
535 */
536 sh->checksum = sctp_end_cksum(crc32);
537 } else 537 } else
538 nskb->ip_summed = CHECKSUM_UNNECESSARY; 538 nskb->ip_summed = CHECKSUM_UNNECESSARY;
539 539
540 /* 3) Put the resultant value into the checksum field in the
541 * common header, and leave the rest of the bits unchanged.
542 */
543 sh->checksum = crc32;
544
545 /* IP layer ECN support 540 /* IP layer ECN support
546 * From RFC 2481 541 * From RFC 2481
547 * "The ECN-Capable Transport (ECT) bit would be set by the 542 * "The ECN-Capable Transport (ECT) bit would be set by the
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index bc411c896216..d765fc53e74d 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -428,7 +428,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
428 * retransmitting due to T3 timeout. 428 * retransmitting due to T3 timeout.
429 */ 429 */
430 if (reason == SCTP_RTXR_T3_RTX && 430 if (reason == SCTP_RTXR_T3_RTX &&
431 (jiffies - chunk->sent_at) < transport->last_rto) 431 time_before(jiffies, chunk->sent_at +
432 transport->last_rto))
432 continue; 433 continue;
433 434
434 /* RFC 2960 6.2.1 Processing a Received SACK 435 /* RFC 2960 6.2.1 Processing a Received SACK
@@ -1757,6 +1758,9 @@ static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
1757 struct sctp_chunk *chunk; 1758 struct sctp_chunk *chunk;
1758 struct list_head *lchunk, *temp; 1759 struct list_head *lchunk, *temp;
1759 1760
1761 if (!asoc->peer.prsctp_capable)
1762 return;
1763
1760 /* PR-SCTP C1) Let SackCumAck be the Cumulative TSN ACK carried in the 1764 /* PR-SCTP C1) Let SackCumAck be the Cumulative TSN ACK carried in the
1761 * received SACK. 1765 * received SACK.
1762 * 1766 *
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index c4986d0f7419..cb198af8887c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -589,46 +589,21 @@ static int sctp_v4_is_ce(const struct sk_buff *skb)
589static struct sock *sctp_v4_create_accept_sk(struct sock *sk, 589static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
590 struct sctp_association *asoc) 590 struct sctp_association *asoc)
591{ 591{
592 struct inet_sock *inet = inet_sk(sk);
593 struct inet_sock *newinet;
594 struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, 592 struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL,
595 sk->sk_prot); 593 sk->sk_prot);
594 struct inet_sock *newinet;
596 595
597 if (!newsk) 596 if (!newsk)
598 goto out; 597 goto out;
599 598
600 sock_init_data(NULL, newsk); 599 sock_init_data(NULL, newsk);
601 600
602 newsk->sk_type = SOCK_STREAM; 601 sctp_copy_sock(newsk, sk, asoc);
603
604 newsk->sk_no_check = sk->sk_no_check;
605 newsk->sk_reuse = sk->sk_reuse;
606 newsk->sk_shutdown = sk->sk_shutdown;
607
608 newsk->sk_destruct = inet_sock_destruct;
609 newsk->sk_family = PF_INET;
610 newsk->sk_protocol = IPPROTO_SCTP;
611 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
612 sock_reset_flag(newsk, SOCK_ZAPPED); 602 sock_reset_flag(newsk, SOCK_ZAPPED);
613 603
614 newinet = inet_sk(newsk); 604 newinet = inet_sk(newsk);
615 605
616 /* Initialize sk's sport, dport, rcv_saddr and daddr for
617 * getsockname() and getpeername()
618 */
619 newinet->sport = inet->sport;
620 newinet->saddr = inet->saddr;
621 newinet->rcv_saddr = inet->rcv_saddr;
622 newinet->dport = htons(asoc->peer.port);
623 newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; 606 newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
624 newinet->pmtudisc = inet->pmtudisc;
625 newinet->id = asoc->next_tsn ^ jiffies;
626
627 newinet->uc_ttl = -1;
628 newinet->mc_loop = 1;
629 newinet->mc_ttl = 1;
630 newinet->mc_index = 0;
631 newinet->mc_list = NULL;
632 607
633 sk_refcnt_debug_inc(newsk); 608 sk_refcnt_debug_inc(newsk);
634 609
@@ -1413,4 +1388,6 @@ MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132");
1413MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-132"); 1388MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-132");
1414MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>"); 1389MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");
1415MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)"); 1390MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");
1391module_param_named(no_checksums, sctp_checksum_disable, bool, 0644);
1392MODULE_PARM_DESC(no_checksums, "Disable checksums computing and verification");
1416MODULE_LICENSE("GPL"); 1393MODULE_LICENSE("GPL");
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index fd8acb48c3f2..6851ee94e974 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -100,11 +100,11 @@ int sctp_chunk_iif(const struct sctp_chunk *chunk)
100 */ 100 */
101static const struct sctp_paramhdr ecap_param = { 101static const struct sctp_paramhdr ecap_param = {
102 SCTP_PARAM_ECN_CAPABLE, 102 SCTP_PARAM_ECN_CAPABLE,
103 __constant_htons(sizeof(struct sctp_paramhdr)), 103 cpu_to_be16(sizeof(struct sctp_paramhdr)),
104}; 104};
105static const struct sctp_paramhdr prsctp_param = { 105static const struct sctp_paramhdr prsctp_param = {
106 SCTP_PARAM_FWD_TSN_SUPPORT, 106 SCTP_PARAM_FWD_TSN_SUPPORT,
107 __constant_htons(sizeof(struct sctp_paramhdr)), 107 cpu_to_be16(sizeof(struct sctp_paramhdr)),
108}; 108};
109 109
110/* A helper to initialize to initialize an op error inside a 110/* A helper to initialize to initialize an op error inside a
@@ -224,7 +224,9 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
224 num_ext += 2; 224 num_ext += 2;
225 } 225 }
226 226
227 chunksize += sizeof(aiparam); 227 if (sp->adaptation_ind)
228 chunksize += sizeof(aiparam);
229
228 chunksize += vparam_len; 230 chunksize += vparam_len;
229 231
230 /* Account for AUTH related parameters */ 232 /* Account for AUTH related parameters */
@@ -304,10 +306,12 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
304 if (sctp_prsctp_enable) 306 if (sctp_prsctp_enable)
305 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); 307 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
306 308
307 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND; 309 if (sp->adaptation_ind) {
308 aiparam.param_hdr.length = htons(sizeof(aiparam)); 310 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
309 aiparam.adaptation_ind = htonl(sp->adaptation_ind); 311 aiparam.param_hdr.length = htons(sizeof(aiparam));
310 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 312 aiparam.adaptation_ind = htonl(sp->adaptation_ind);
313 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
314 }
311 315
312 /* Add SCTP-AUTH chunks to the parameter list */ 316 /* Add SCTP-AUTH chunks to the parameter list */
313 if (sctp_auth_enable) { 317 if (sctp_auth_enable) {
@@ -332,6 +336,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
332 sctp_inithdr_t initack; 336 sctp_inithdr_t initack;
333 struct sctp_chunk *retval; 337 struct sctp_chunk *retval;
334 union sctp_params addrs; 338 union sctp_params addrs;
339 struct sctp_sock *sp;
335 int addrs_len; 340 int addrs_len;
336 sctp_cookie_param_t *cookie; 341 sctp_cookie_param_t *cookie;
337 int cookie_len; 342 int cookie_len;
@@ -366,22 +371,24 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
366 /* Calculate the total size of allocation, include the reserved 371 /* Calculate the total size of allocation, include the reserved
367 * space for reporting unknown parameters if it is specified. 372 * space for reporting unknown parameters if it is specified.
368 */ 373 */
374 sp = sctp_sk(asoc->base.sk);
369 chunksize = sizeof(initack) + addrs_len + cookie_len + unkparam_len; 375 chunksize = sizeof(initack) + addrs_len + cookie_len + unkparam_len;
370 376
371 /* Tell peer that we'll do ECN only if peer advertised such cap. */ 377 /* Tell peer that we'll do ECN only if peer advertised such cap. */
372 if (asoc->peer.ecn_capable) 378 if (asoc->peer.ecn_capable)
373 chunksize += sizeof(ecap_param); 379 chunksize += sizeof(ecap_param);
374 380
375 if (sctp_prsctp_enable) 381 if (asoc->peer.prsctp_capable)
376 chunksize += sizeof(prsctp_param); 382 chunksize += sizeof(prsctp_param);
377 383
378 if (sctp_addip_enable) { 384 if (asoc->peer.asconf_capable) {
379 extensions[num_ext] = SCTP_CID_ASCONF; 385 extensions[num_ext] = SCTP_CID_ASCONF;
380 extensions[num_ext+1] = SCTP_CID_ASCONF_ACK; 386 extensions[num_ext+1] = SCTP_CID_ASCONF_ACK;
381 num_ext += 2; 387 num_ext += 2;
382 } 388 }
383 389
384 chunksize += sizeof(aiparam); 390 if (sp->adaptation_ind)
391 chunksize += sizeof(aiparam);
385 392
386 if (asoc->peer.auth_capable) { 393 if (asoc->peer.auth_capable) {
387 auth_random = (sctp_paramhdr_t *)asoc->c.auth_random; 394 auth_random = (sctp_paramhdr_t *)asoc->c.auth_random;
@@ -432,10 +439,12 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
432 if (asoc->peer.prsctp_capable) 439 if (asoc->peer.prsctp_capable)
433 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); 440 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
434 441
435 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND; 442 if (sp->adaptation_ind) {
436 aiparam.param_hdr.length = htons(sizeof(aiparam)); 443 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
437 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind); 444 aiparam.param_hdr.length = htons(sizeof(aiparam));
438 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 445 aiparam.adaptation_ind = htonl(sp->adaptation_ind);
446 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
447 }
439 448
440 if (asoc->peer.auth_capable) { 449 if (asoc->peer.auth_capable) {
441 sctp_addto_chunk(retval, ntohs(auth_random->length), 450 sctp_addto_chunk(retval, ntohs(auth_random->length),
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index b5495aecab60..e2020eb2c8ca 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -434,7 +434,8 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
434 * 434 *
435 */ 435 */
436static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, 436static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
437 struct sctp_transport *transport) 437 struct sctp_transport *transport,
438 int is_hb)
438{ 439{
439 /* The check for association's overall error counter exceeding the 440 /* The check for association's overall error counter exceeding the
440 * threshold is done in the state function. 441 * threshold is done in the state function.
@@ -461,9 +462,15 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
461 * expires, set RTO <- RTO * 2 ("back off the timer"). The 462 * expires, set RTO <- RTO * 2 ("back off the timer"). The
462 * maximum value discussed in rule C7 above (RTO.max) may be 463 * maximum value discussed in rule C7 above (RTO.max) may be
463 * used to provide an upper bound to this doubling operation. 464 * used to provide an upper bound to this doubling operation.
465 *
466 * Special Case: the first HB doesn't trigger exponential backoff.
467 * The first unacknowleged HB triggers it. We do this with a flag
468 * that indicates that we have an outstanding HB.
464 */ 469 */
465 transport->last_rto = transport->rto; 470 if (!is_hb || transport->hb_sent) {
466 transport->rto = min((transport->rto * 2), transport->asoc->rto_max); 471 transport->last_rto = transport->rto;
472 transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
473 }
467} 474}
468 475
469/* Worker routine to handle INIT command failure. */ 476/* Worker routine to handle INIT command failure. */
@@ -621,6 +628,11 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
621 t->error_count = 0; 628 t->error_count = 0;
622 t->asoc->overall_error_count = 0; 629 t->asoc->overall_error_count = 0;
623 630
631 /* Clear the hb_sent flag to signal that we had a good
632 * acknowledgement.
633 */
634 t->hb_sent = 0;
635
624 /* Mark the destination transport address as active if it is not so 636 /* Mark the destination transport address as active if it is not so
625 * marked. 637 * marked.
626 */ 638 */
@@ -646,18 +658,6 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
646 sctp_transport_hold(t); 658 sctp_transport_hold(t);
647} 659}
648 660
649/* Helper function to do a transport reset at the expiry of the hearbeat
650 * timer.
651 */
652static void sctp_cmd_transport_reset(sctp_cmd_seq_t *cmds,
653 struct sctp_association *asoc,
654 struct sctp_transport *t)
655{
656 sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE);
657
658 /* Mark one strike against a transport. */
659 sctp_do_8_2_transport_strike(asoc, t);
660}
661 661
662/* Helper function to process the process SACK command. */ 662/* Helper function to process the process SACK command. */
663static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds, 663static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
@@ -1458,12 +1458,19 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1458 1458
1459 case SCTP_CMD_STRIKE: 1459 case SCTP_CMD_STRIKE:
1460 /* Mark one strike against a transport. */ 1460 /* Mark one strike against a transport. */
1461 sctp_do_8_2_transport_strike(asoc, cmd->obj.transport); 1461 sctp_do_8_2_transport_strike(asoc, cmd->obj.transport,
1462 0);
1463 break;
1464
1465 case SCTP_CMD_TRANSPORT_IDLE:
1466 t = cmd->obj.transport;
1467 sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE);
1462 break; 1468 break;
1463 1469
1464 case SCTP_CMD_TRANSPORT_RESET: 1470 case SCTP_CMD_TRANSPORT_HB_SENT:
1465 t = cmd->obj.transport; 1471 t = cmd->obj.transport;
1466 sctp_cmd_transport_reset(commands, asoc, t); 1472 sctp_do_8_2_transport_strike(asoc, t, 1);
1473 t->hb_sent = 1;
1467 break; 1474 break;
1468 1475
1469 case SCTP_CMD_TRANSPORT_ON: 1476 case SCTP_CMD_TRANSPORT_ON:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index f88dfded0e3a..55a61aa69662 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -988,7 +988,9 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
988 /* Set transport error counter and association error counter 988 /* Set transport error counter and association error counter
989 * when sending heartbeat. 989 * when sending heartbeat.
990 */ 990 */
991 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, 991 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_IDLE,
992 SCTP_TRANSPORT(transport));
993 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
992 SCTP_TRANSPORT(transport)); 994 SCTP_TRANSPORT(transport));
993 } 995 }
994 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE, 996 sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
@@ -4955,7 +4957,7 @@ sctp_disposition_t sctp_sf_do_prm_requestheartbeat(
4955 * to that address and not acknowledged within one RTO. 4957 * to that address and not acknowledged within one RTO.
4956 * 4958 *
4957 */ 4959 */
4958 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, 4960 sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_HB_SENT,
4959 SCTP_TRANSPORT(arg)); 4961 SCTP_TRANSPORT(arg));
4960 return SCTP_DISPOSITION_CONSUME; 4962 return SCTP_DISPOSITION_CONSUME;
4961} 4963}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff0a8f88de04..5fb3a8c9792e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3069,9 +3069,6 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
3069 int val; 3069 int val;
3070 int assoc_id = 0; 3070 int assoc_id = 0;
3071 3071
3072 if (optlen < sizeof(int))
3073 return -EINVAL;
3074
3075 if (optlen == sizeof(int)) { 3072 if (optlen == sizeof(int)) {
3076 printk(KERN_WARNING 3073 printk(KERN_WARNING
3077 "SCTP: Use of int in max_burst socket option deprecated\n"); 3074 "SCTP: Use of int in max_burst socket option deprecated\n");
@@ -3939,7 +3936,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3939{ 3936{
3940 struct sock *sk = asoc->base.sk; 3937 struct sock *sk = asoc->base.sk;
3941 struct socket *sock; 3938 struct socket *sock;
3942 struct inet_sock *inetsk;
3943 struct sctp_af *af; 3939 struct sctp_af *af;
3944 int err = 0; 3940 int err = 0;
3945 3941
@@ -3954,18 +3950,18 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3954 if (err < 0) 3950 if (err < 0)
3955 return err; 3951 return err;
3956 3952
3957 /* Populate the fields of the newsk from the oldsk and migrate the 3953 sctp_copy_sock(sock->sk, sk, asoc);
3958 * asoc to the newsk.
3959 */
3960 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3961 3954
3962 /* Make peeled-off sockets more like 1-1 accepted sockets. 3955 /* Make peeled-off sockets more like 1-1 accepted sockets.
3963 * Set the daddr and initialize id to something more random 3956 * Set the daddr and initialize id to something more random
3964 */ 3957 */
3965 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); 3958 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
3966 af->to_sk_daddr(&asoc->peer.primary_addr, sk); 3959 af->to_sk_daddr(&asoc->peer.primary_addr, sk);
3967 inetsk = inet_sk(sock->sk); 3960
3968 inetsk->id = asoc->next_tsn ^ jiffies; 3961 /* Populate the fields of the newsk from the oldsk and migrate the
3962 * asoc to the newsk.
3963 */
3964 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3969 3965
3970 *sockp = sock; 3966 *sockp = sock;
3971 3967
@@ -5284,16 +5280,14 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5284 struct sctp_sock *sp; 5280 struct sctp_sock *sp;
5285 struct sctp_association *asoc; 5281 struct sctp_association *asoc;
5286 5282
5287 if (len < sizeof(int))
5288 return -EINVAL;
5289
5290 if (len == sizeof(int)) { 5283 if (len == sizeof(int)) {
5291 printk(KERN_WARNING 5284 printk(KERN_WARNING
5292 "SCTP: Use of int in max_burst socket option deprecated\n"); 5285 "SCTP: Use of int in max_burst socket option deprecated\n");
5293 printk(KERN_WARNING 5286 printk(KERN_WARNING
5294 "SCTP: Use struct sctp_assoc_value instead\n"); 5287 "SCTP: Use struct sctp_assoc_value instead\n");
5295 params.assoc_id = 0; 5288 params.assoc_id = 0;
5296 } else if (len == sizeof (struct sctp_assoc_value)) { 5289 } else if (len >= sizeof(struct sctp_assoc_value)) {
5290 len = sizeof(struct sctp_assoc_value);
5297 if (copy_from_user(&params, optval, len)) 5291 if (copy_from_user(&params, optval, len))
5298 return -EFAULT; 5292 return -EFAULT;
5299 } else 5293 } else
@@ -5849,37 +5843,28 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
5849} 5843}
5850 5844
5851/* 5845/*
5852 * 3.1.3 listen() - UDP Style Syntax 5846 * Move a socket to LISTENING state.
5853 *
5854 * By default, new associations are not accepted for UDP style sockets.
5855 * An application uses listen() to mark a socket as being able to
5856 * accept new associations.
5857 */ 5847 */
5858SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) 5848SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
5859{ 5849{
5860 struct sctp_sock *sp = sctp_sk(sk); 5850 struct sctp_sock *sp = sctp_sk(sk);
5861 struct sctp_endpoint *ep = sp->ep; 5851 struct sctp_endpoint *ep = sp->ep;
5852 struct crypto_hash *tfm = NULL;
5862 5853
5863 /* Only UDP style sockets that are not peeled off are allowed to 5854 /* Allocate HMAC for generating cookie. */
5864 * listen(). 5855 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) {
5865 */ 5856 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
5866 if (!sctp_style(sk, UDP)) 5857 if (IS_ERR(tfm)) {
5867 return -EINVAL; 5858 if (net_ratelimit()) {
5868 5859 printk(KERN_INFO
5869 /* If backlog is zero, disable listening. */ 5860 "SCTP: failed to load transform for %s: %ld\n",
5870 if (!backlog) { 5861 sctp_hmac_alg, PTR_ERR(tfm));
5871 if (sctp_sstate(sk, CLOSED)) 5862 }
5872 return 0; 5863 return -ENOSYS;
5873 5864 }
5874 sctp_unhash_endpoint(ep); 5865 sctp_sk(sk)->hmac = tfm;
5875 sk->sk_state = SCTP_SS_CLOSED;
5876 return 0;
5877 } 5866 }
5878 5867
5879 /* Return if we are already listening. */
5880 if (sctp_sstate(sk, LISTENING))
5881 return 0;
5882
5883 /* 5868 /*
5884 * If a bind() or sctp_bindx() is not called prior to a listen() 5869 * If a bind() or sctp_bindx() is not called prior to a listen()
5885 * call that allows new associations to be accepted, the system 5870 * call that allows new associations to be accepted, the system
@@ -5890,7 +5875,6 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5890 * extensions draft, but follows the practice as seen in TCP 5875 * extensions draft, but follows the practice as seen in TCP
5891 * sockets. 5876 * sockets.
5892 * 5877 *
5893 * Additionally, turn off fastreuse flag since we are not listening
5894 */ 5878 */
5895 sk->sk_state = SCTP_SS_LISTENING; 5879 sk->sk_state = SCTP_SS_LISTENING;
5896 if (!ep->base.bind_addr.port) { 5880 if (!ep->base.bind_addr.port) {
@@ -5901,113 +5885,71 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5901 sk->sk_state = SCTP_SS_CLOSED; 5885 sk->sk_state = SCTP_SS_CLOSED;
5902 return -EADDRINUSE; 5886 return -EADDRINUSE;
5903 } 5887 }
5904 sctp_sk(sk)->bind_hash->fastreuse = 0;
5905 } 5888 }
5906 5889
5907 sctp_hash_endpoint(ep);
5908 return 0;
5909}
5910
5911/*
5912 * 4.1.3 listen() - TCP Style Syntax
5913 *
5914 * Applications uses listen() to ready the SCTP endpoint for accepting
5915 * inbound associations.
5916 */
5917SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
5918{
5919 struct sctp_sock *sp = sctp_sk(sk);
5920 struct sctp_endpoint *ep = sp->ep;
5921
5922 /* If backlog is zero, disable listening. */
5923 if (!backlog) {
5924 if (sctp_sstate(sk, CLOSED))
5925 return 0;
5926
5927 sctp_unhash_endpoint(ep);
5928 sk->sk_state = SCTP_SS_CLOSED;
5929 return 0;
5930 }
5931
5932 if (sctp_sstate(sk, LISTENING))
5933 return 0;
5934
5935 /*
5936 * If a bind() or sctp_bindx() is not called prior to a listen()
5937 * call that allows new associations to be accepted, the system
5938 * picks an ephemeral port and will choose an address set equivalent
5939 * to binding with a wildcard address.
5940 *
5941 * This is not currently spelled out in the SCTP sockets
5942 * extensions draft, but follows the practice as seen in TCP
5943 * sockets.
5944 */
5945 sk->sk_state = SCTP_SS_LISTENING;
5946 if (!ep->base.bind_addr.port) {
5947 if (sctp_autobind(sk))
5948 return -EAGAIN;
5949 } else
5950 sctp_sk(sk)->bind_hash->fastreuse = 0;
5951
5952 sk->sk_max_ack_backlog = backlog; 5890 sk->sk_max_ack_backlog = backlog;
5953 sctp_hash_endpoint(ep); 5891 sctp_hash_endpoint(ep);
5954 return 0; 5892 return 0;
5955} 5893}
5956 5894
5957/* 5895/*
5896 * 4.1.3 / 5.1.3 listen()
5897 *
5898 * By default, new associations are not accepted for UDP style sockets.
5899 * An application uses listen() to mark a socket as being able to
5900 * accept new associations.
5901 *
5902 * On TCP style sockets, applications use listen() to ready the SCTP
5903 * endpoint for accepting inbound associations.
5904 *
5905 * On both types of endpoints a backlog of '0' disables listening.
5906 *
5958 * Move a socket to LISTENING state. 5907 * Move a socket to LISTENING state.
5959 */ 5908 */
5960int sctp_inet_listen(struct socket *sock, int backlog) 5909int sctp_inet_listen(struct socket *sock, int backlog)
5961{ 5910{
5962 struct sock *sk = sock->sk; 5911 struct sock *sk = sock->sk;
5963 struct crypto_hash *tfm = NULL; 5912 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5964 int err = -EINVAL; 5913 int err = -EINVAL;
5965 5914
5966 if (unlikely(backlog < 0)) 5915 if (unlikely(backlog < 0))
5967 goto out; 5916 return err;
5968 5917
5969 sctp_lock_sock(sk); 5918 sctp_lock_sock(sk);
5970 5919
5920 /* Peeled-off sockets are not allowed to listen(). */
5921 if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
5922 goto out;
5923
5971 if (sock->state != SS_UNCONNECTED) 5924 if (sock->state != SS_UNCONNECTED)
5972 goto out; 5925 goto out;
5973 5926
5974 /* Allocate HMAC for generating cookie. */ 5927 /* If backlog is zero, disable listening. */
5975 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { 5928 if (!backlog) {
5976 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); 5929 if (sctp_sstate(sk, CLOSED))
5977 if (IS_ERR(tfm)) {
5978 if (net_ratelimit()) {
5979 printk(KERN_INFO
5980 "SCTP: failed to load transform for %s: %ld\n",
5981 sctp_hmac_alg, PTR_ERR(tfm));
5982 }
5983 err = -ENOSYS;
5984 goto out; 5930 goto out;
5985 }
5986 }
5987 5931
5988 switch (sock->type) { 5932 err = 0;
5989 case SOCK_SEQPACKET: 5933 sctp_unhash_endpoint(ep);
5990 err = sctp_seqpacket_listen(sk, backlog); 5934 sk->sk_state = SCTP_SS_CLOSED;
5991 break; 5935 if (sk->sk_reuse)
5992 case SOCK_STREAM: 5936 sctp_sk(sk)->bind_hash->fastreuse = 1;
5993 err = sctp_stream_listen(sk, backlog); 5937 goto out;
5994 break;
5995 default:
5996 break;
5997 } 5938 }
5998 5939
5999 if (err) 5940 /* If we are already listening, just update the backlog */
6000 goto cleanup; 5941 if (sctp_sstate(sk, LISTENING))
5942 sk->sk_max_ack_backlog = backlog;
5943 else {
5944 err = sctp_listen_start(sk, backlog);
5945 if (err)
5946 goto out;
5947 }
6001 5948
6002 /* Store away the transform reference. */ 5949 err = 0;
6003 if (!sctp_sk(sk)->hmac)
6004 sctp_sk(sk)->hmac = tfm;
6005out: 5950out:
6006 sctp_release_sock(sk); 5951 sctp_release_sock(sk);
6007 return err; 5952 return err;
6008cleanup:
6009 crypto_free_hash(tfm);
6010 goto out;
6011} 5953}
6012 5954
6013/* 5955/*
@@ -6700,6 +6642,48 @@ done:
6700 sctp_skb_set_owner_r(skb, sk); 6642 sctp_skb_set_owner_r(skb, sk);
6701} 6643}
6702 6644
6645void sctp_copy_sock(struct sock *newsk, struct sock *sk,
6646 struct sctp_association *asoc)
6647{
6648 struct inet_sock *inet = inet_sk(sk);
6649 struct inet_sock *newinet = inet_sk(newsk);
6650
6651 newsk->sk_type = sk->sk_type;
6652 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
6653 newsk->sk_flags = sk->sk_flags;
6654 newsk->sk_no_check = sk->sk_no_check;
6655 newsk->sk_reuse = sk->sk_reuse;
6656
6657 newsk->sk_shutdown = sk->sk_shutdown;
6658 newsk->sk_destruct = inet_sock_destruct;
6659 newsk->sk_family = sk->sk_family;
6660 newsk->sk_protocol = IPPROTO_SCTP;
6661 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
6662 newsk->sk_sndbuf = sk->sk_sndbuf;
6663 newsk->sk_rcvbuf = sk->sk_rcvbuf;
6664 newsk->sk_lingertime = sk->sk_lingertime;
6665 newsk->sk_rcvtimeo = sk->sk_rcvtimeo;
6666 newsk->sk_sndtimeo = sk->sk_sndtimeo;
6667
6668 newinet = inet_sk(newsk);
6669
6670 /* Initialize sk's sport, dport, rcv_saddr and daddr for
6671 * getsockname() and getpeername()
6672 */
6673 newinet->sport = inet->sport;
6674 newinet->saddr = inet->saddr;
6675 newinet->rcv_saddr = inet->rcv_saddr;
6676 newinet->dport = htons(asoc->peer.port);
6677 newinet->pmtudisc = inet->pmtudisc;
6678 newinet->id = asoc->next_tsn ^ jiffies;
6679
6680 newinet->uc_ttl = inet->uc_ttl;
6681 newinet->mc_loop = 1;
6682 newinet->mc_ttl = 1;
6683 newinet->mc_index = 0;
6684 newinet->mc_list = NULL;
6685}
6686
6703/* Populate the fields of the newsk from the oldsk and migrate the assoc 6687/* Populate the fields of the newsk from the oldsk and migrate the assoc
6704 * and its messages to the newsk. 6688 * and its messages to the newsk.
6705 */ 6689 */
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index e745c118f239..e5dde45c79d3 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -79,6 +79,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
79 peer->rttvar = 0; 79 peer->rttvar = 0;
80 peer->srtt = 0; 80 peer->srtt = 0;
81 peer->rto_pending = 0; 81 peer->rto_pending = 0;
82 peer->hb_sent = 0;
82 peer->fast_recovery = 0; 83 peer->fast_recovery = 0;
83 84
84 peer->last_time_heard = jiffies; 85 peer->last_time_heard = jiffies;
@@ -542,8 +543,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
542 * congestion indications more than once every window of 543 * congestion indications more than once every window of
543 * data (or more loosely more than once every round-trip time). 544 * data (or more loosely more than once every round-trip time).
544 */ 545 */
545 if ((jiffies - transport->last_time_ecne_reduced) > 546 if (time_after(jiffies, transport->last_time_ecne_reduced +
546 transport->rtt) { 547 transport->rtt)) {
547 transport->ssthresh = max(transport->cwnd/2, 548 transport->ssthresh = max(transport->cwnd/2,
548 4*transport->asoc->pathmtu); 549 4*transport->asoc->pathmtu);
549 transport->cwnd = transport->ssthresh; 550 transport->cwnd = transport->ssthresh;
@@ -560,7 +561,8 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
560 * to be done every RTO interval, we do it every hearbeat 561 * to be done every RTO interval, we do it every hearbeat
561 * interval. 562 * interval.
562 */ 563 */
563 if ((jiffies - transport->last_time_used) > transport->rto) 564 if (time_after(jiffies, transport->last_time_used +
565 transport->rto))
564 transport->cwnd = max(transport->cwnd/2, 566 transport->cwnd = max(transport->cwnd/2,
565 4*transport->asoc->pathmtu); 567 4*transport->asoc->pathmtu);
566 break; 568 break;
@@ -608,6 +610,7 @@ void sctp_transport_reset(struct sctp_transport *t)
608 t->flight_size = 0; 610 t->flight_size = 0;
609 t->error_count = 0; 611 t->error_count = 0;
610 t->rto_pending = 0; 612 t->rto_pending = 0;
613 t->hb_sent = 0;
611 t->fast_recovery = 0; 614 t->fast_recovery = 0;
612 615
613 /* Initialize the state information for SFR-CACC */ 616 /* Initialize the state information for SFR-CACC */