aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-08-31 01:11:31 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-08-31 01:11:31 -0400
commitb91ddd843751947e2f81dfc8a86c5c21cbe07158 (patch)
treeabeab3c0fa11e4295c889951bae407317b7e7eda
parent05bb1fad1cde025a864a90cfeb98dcbefe78a44a (diff)
parentcb243a1a9fef4aaff262a5dd14f987070d37229b (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/vxy/lksctp-dev
-rw-r--r--include/net/sctp/sm.h2
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--include/net/sctp/ulpqueue.h1
-rw-r--r--net/sctp/associola.c7
-rw-r--r--net/sctp/outqueue.c7
-rw-r--r--net/sctp/sm_make_chunk.c112
-rw-r--r--net/sctp/sm_sideeffect.c8
-rw-r--r--net/sctp/sm_statefuns.c51
-rw-r--r--net/sctp/socket.c3
-rw-r--r--net/sctp/ulpqueue.c75
10 files changed, 190 insertions, 77 deletions
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 73cb9943c8a8..991c85bb9e36 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -214,7 +214,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
214 const struct sctp_chunk *); 214 const struct sctp_chunk *);
215struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, 215struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *,
216 const struct sctp_chunk *); 216 const struct sctp_chunk *);
217void sctp_init_cause(struct sctp_chunk *, __be16 cause, const void *, size_t); 217void sctp_init_cause(struct sctp_chunk *, __be16 cause, size_t);
218struct sctp_chunk *sctp_make_abort(const struct sctp_association *, 218struct sctp_chunk *sctp_make_abort(const struct sctp_association *,
219 const struct sctp_chunk *, 219 const struct sctp_chunk *,
220 const size_t hint); 220 const size_t hint);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index ee4559b11302..c0d5848c33dc 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -726,6 +726,7 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
726 struct iovec *data); 726 struct iovec *data);
727void sctp_chunk_free(struct sctp_chunk *); 727void sctp_chunk_free(struct sctp_chunk *);
728void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data); 728void *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
729void *sctp_addto_param(struct sctp_chunk *, int len, const void *data);
729struct sctp_chunk *sctp_chunkify(struct sk_buff *, 730struct sctp_chunk *sctp_chunkify(struct sk_buff *,
730 const struct sctp_association *, 731 const struct sctp_association *,
731 struct sock *); 732 struct sock *);
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
index 39ea3f442b47..cd33270e86dd 100644
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -83,6 +83,7 @@ int sctp_clear_pd(struct sock *sk, struct sctp_association *asoc);
83/* Skip over an SSN. */ 83/* Skip over an SSN. */
84void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn); 84void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn);
85 85
86void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *, __u32);
86#endif /* __sctp_ulpqueue_h__ */ 87#endif /* __sctp_ulpqueue_h__ */
87 88
88 89
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 498edb0cd4e5..2ad1caf1ea42 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -727,7 +727,12 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
727 break; 727 break;
728 728
729 case SCTP_TRANSPORT_DOWN: 729 case SCTP_TRANSPORT_DOWN:
730 transport->state = SCTP_INACTIVE; 730 /* if the transort was never confirmed, do not transition it
731 * to inactive state.
732 */
733 if (transport->state != SCTP_UNCONFIRMED)
734 transport->state = SCTP_INACTIVE;
735
731 spc_state = SCTP_ADDR_UNREACHABLE; 736 spc_state = SCTP_ADDR_UNREACHABLE;
732 break; 737 break;
733 738
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 992f361084b7..28f4fe77ceee 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -421,6 +421,13 @@ void sctp_retransmit_mark(struct sctp_outq *q,
421 */ 421 */
422 if ((fast_retransmit && (chunk->fast_retransmit > 0)) || 422 if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
423 (!fast_retransmit && !chunk->tsn_gap_acked)) { 423 (!fast_retransmit && !chunk->tsn_gap_acked)) {
424 /* If this chunk was sent less then 1 rto ago, do not
425 * retransmit this chunk, but give the peer time
426 * to acknowlege it.
427 */
428 if ((jiffies - chunk->sent_at) < transport->rto)
429 continue;
430
424 /* RFC 2960 6.2.1 Processing a Received SACK 431 /* RFC 2960 6.2.1 Processing a Received SACK
425 * 432 *
426 * C) Any time a DATA chunk is marked for 433 * C) Any time a DATA chunk is marked for
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 51c4d7fef1d2..79856c924525 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -110,7 +110,7 @@ static const struct sctp_paramhdr prsctp_param = {
110 * abort chunk. 110 * abort chunk.
111 */ 111 */
112void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code, 112void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
113 const void *payload, size_t paylen) 113 size_t paylen)
114{ 114{
115 sctp_errhdr_t err; 115 sctp_errhdr_t err;
116 __u16 len; 116 __u16 len;
@@ -120,7 +120,6 @@ void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
120 len = sizeof(sctp_errhdr_t) + paylen; 120 len = sizeof(sctp_errhdr_t) + paylen;
121 err.length = htons(len); 121 err.length = htons(len);
122 chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); 122 chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err);
123 sctp_addto_chunk(chunk, paylen, payload);
124} 123}
125 124
126/* 3.3.2 Initiation (INIT) (1) 125/* 3.3.2 Initiation (INIT) (1)
@@ -780,8 +779,8 @@ struct sctp_chunk *sctp_make_abort_no_data(
780 779
781 /* Put the tsn back into network byte order. */ 780 /* Put the tsn back into network byte order. */
782 payload = htonl(tsn); 781 payload = htonl(tsn);
783 sctp_init_cause(retval, SCTP_ERROR_NO_DATA, (const void *)&payload, 782 sctp_init_cause(retval, SCTP_ERROR_NO_DATA, sizeof(payload));
784 sizeof(payload)); 783 sctp_addto_chunk(retval, sizeof(payload), (const void *)&payload);
785 784
786 /* RFC 2960 6.4 Multi-homed SCTP Endpoints 785 /* RFC 2960 6.4 Multi-homed SCTP Endpoints
787 * 786 *
@@ -823,7 +822,8 @@ struct sctp_chunk *sctp_make_abort_user(const struct sctp_association *asoc,
823 goto err_copy; 822 goto err_copy;
824 } 823 }
825 824
826 sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, payload, paylen); 825 sctp_init_cause(retval, SCTP_ERROR_USER_ABORT, paylen);
826 sctp_addto_chunk(retval, paylen, payload);
827 827
828 if (paylen) 828 if (paylen)
829 kfree(payload); 829 kfree(payload);
@@ -850,15 +850,17 @@ struct sctp_chunk *sctp_make_abort_violation(
850 struct sctp_paramhdr phdr; 850 struct sctp_paramhdr phdr;
851 851
852 retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen 852 retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) + paylen
853 + sizeof(sctp_chunkhdr_t)); 853 + sizeof(sctp_paramhdr_t));
854 if (!retval) 854 if (!retval)
855 goto end; 855 goto end;
856 856
857 sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, payload, paylen); 857 sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION, paylen
858 + sizeof(sctp_paramhdr_t));
858 859
859 phdr.type = htons(chunk->chunk_hdr->type); 860 phdr.type = htons(chunk->chunk_hdr->type);
860 phdr.length = chunk->chunk_hdr->length; 861 phdr.length = chunk->chunk_hdr->length;
861 sctp_addto_chunk(retval, sizeof(sctp_paramhdr_t), &phdr); 862 sctp_addto_chunk(retval, paylen, payload);
863 sctp_addto_param(retval, sizeof(sctp_paramhdr_t), &phdr);
862 864
863end: 865end:
864 return retval; 866 return retval;
@@ -955,7 +957,8 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
955 if (!retval) 957 if (!retval)
956 goto nodata; 958 goto nodata;
957 959
958 sctp_init_cause(retval, cause_code, payload, paylen); 960 sctp_init_cause(retval, cause_code, paylen);
961 sctp_addto_chunk(retval, paylen, payload);
959 962
960nodata: 963nodata:
961 return retval; 964 return retval;
@@ -1128,7 +1131,7 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
1128 void *target; 1131 void *target;
1129 void *padding; 1132 void *padding;
1130 int chunklen = ntohs(chunk->chunk_hdr->length); 1133 int chunklen = ntohs(chunk->chunk_hdr->length);
1131 int padlen = chunklen % 4; 1134 int padlen = WORD_ROUND(chunklen) - chunklen;
1132 1135
1133 padding = skb_put(chunk->skb, padlen); 1136 padding = skb_put(chunk->skb, padlen);
1134 target = skb_put(chunk->skb, len); 1137 target = skb_put(chunk->skb, len);
@@ -1143,6 +1146,25 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
1143 return target; 1146 return target;
1144} 1147}
1145 1148
1149/* Append bytes to the end of a parameter. Will panic if chunk is not big
1150 * enough.
1151 */
1152void *sctp_addto_param(struct sctp_chunk *chunk, int len, const void *data)
1153{
1154 void *target;
1155 int chunklen = ntohs(chunk->chunk_hdr->length);
1156
1157 target = skb_put(chunk->skb, len);
1158
1159 memcpy(target, data, len);
1160
1161 /* Adjust the chunk length field. */
1162 chunk->chunk_hdr->length = htons(chunklen + len);
1163 chunk->chunk_end = skb_tail_pointer(chunk->skb);
1164
1165 return target;
1166}
1167
1146/* Append bytes from user space to the end of a chunk. Will panic if 1168/* Append bytes from user space to the end of a chunk. Will panic if
1147 * chunk is not big enough. 1169 * chunk is not big enough.
1148 * Returns a kernel err value. 1170 * Returns a kernel err value.
@@ -1174,25 +1196,36 @@ out:
1174 */ 1196 */
1175void sctp_chunk_assign_ssn(struct sctp_chunk *chunk) 1197void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
1176{ 1198{
1199 struct sctp_datamsg *msg;
1200 struct sctp_chunk *lchunk;
1201 struct sctp_stream *stream;
1177 __u16 ssn; 1202 __u16 ssn;
1178 __u16 sid; 1203 __u16 sid;
1179 1204
1180 if (chunk->has_ssn) 1205 if (chunk->has_ssn)
1181 return; 1206 return;
1182 1207
1183 /* This is the last possible instant to assign a SSN. */ 1208 /* All fragments will be on the same stream */
1184 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { 1209 sid = ntohs(chunk->subh.data_hdr->stream);
1185 ssn = 0; 1210 stream = &chunk->asoc->ssnmap->out;
1186 } else {
1187 sid = ntohs(chunk->subh.data_hdr->stream);
1188 if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
1189 ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid);
1190 else
1191 ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid);
1192 }
1193 1211
1194 chunk->subh.data_hdr->ssn = htons(ssn); 1212 /* Now assign the sequence number to the entire message.
1195 chunk->has_ssn = 1; 1213 * All fragments must have the same stream sequence number.
1214 */
1215 msg = chunk->msg;
1216 list_for_each_entry(lchunk, &msg->chunks, frag_list) {
1217 if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
1218 ssn = 0;
1219 } else {
1220 if (lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
1221 ssn = sctp_ssn_next(stream, sid);
1222 else
1223 ssn = sctp_ssn_peek(stream, sid);
1224 }
1225
1226 lchunk->subh.data_hdr->ssn = htons(ssn);
1227 lchunk->has_ssn = 1;
1228 }
1196} 1229}
1197 1230
1198/* Helper function to assign a TSN if needed. This assumes that both 1231/* Helper function to assign a TSN if needed. This assumes that both
@@ -1466,7 +1499,8 @@ no_hmac:
1466 __be32 n = htonl(usecs); 1499 __be32 n = htonl(usecs);
1467 1500
1468 sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE, 1501 sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE,
1469 &n, sizeof(n)); 1502 sizeof(n));
1503 sctp_addto_chunk(*errp, sizeof(n), &n);
1470 *error = -SCTP_IERROR_STALE_COOKIE; 1504 *error = -SCTP_IERROR_STALE_COOKIE;
1471 } else 1505 } else
1472 *error = -SCTP_IERROR_NOMEM; 1506 *error = -SCTP_IERROR_NOMEM;
@@ -1556,7 +1590,8 @@ static int sctp_process_missing_param(const struct sctp_association *asoc,
1556 report.num_missing = htonl(1); 1590 report.num_missing = htonl(1);
1557 report.type = paramtype; 1591 report.type = paramtype;
1558 sctp_init_cause(*errp, SCTP_ERROR_MISS_PARAM, 1592 sctp_init_cause(*errp, SCTP_ERROR_MISS_PARAM,
1559 &report, sizeof(report)); 1593 sizeof(report));
1594 sctp_addto_chunk(*errp, sizeof(report), &report);
1560 } 1595 }
1561 1596
1562 /* Stop processing this chunk. */ 1597 /* Stop processing this chunk. */
@@ -1574,7 +1609,7 @@ static int sctp_process_inv_mandatory(const struct sctp_association *asoc,
1574 *errp = sctp_make_op_error_space(asoc, chunk, 0); 1609 *errp = sctp_make_op_error_space(asoc, chunk, 0);
1575 1610
1576 if (*errp) 1611 if (*errp)
1577 sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, NULL, 0); 1612 sctp_init_cause(*errp, SCTP_ERROR_INV_PARAM, 0);
1578 1613
1579 /* Stop processing this chunk. */ 1614 /* Stop processing this chunk. */
1580 return 0; 1615 return 0;
@@ -1595,9 +1630,10 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
1595 *errp = sctp_make_op_error_space(asoc, chunk, payload_len); 1630 *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
1596 1631
1597 if (*errp) { 1632 if (*errp) {
1598 sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION, error, 1633 sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
1599 sizeof(error)); 1634 sizeof(error) + sizeof(sctp_paramhdr_t));
1600 sctp_addto_chunk(*errp, sizeof(sctp_paramhdr_t), param); 1635 sctp_addto_chunk(*errp, sizeof(error), error);
1636 sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
1601 } 1637 }
1602 1638
1603 return 0; 1639 return 0;
@@ -1618,9 +1654,10 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
1618 if (!*errp) 1654 if (!*errp)
1619 *errp = sctp_make_op_error_space(asoc, chunk, len); 1655 *errp = sctp_make_op_error_space(asoc, chunk, len);
1620 1656
1621 if (*errp) 1657 if (*errp) {
1622 sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, 1658 sctp_init_cause(*errp, SCTP_ERROR_DNS_FAILED, len);
1623 param.v, len); 1659 sctp_addto_chunk(*errp, len, param.v);
1660 }
1624 1661
1625 /* Stop processing this chunk. */ 1662 /* Stop processing this chunk. */
1626 return 0; 1663 return 0;
@@ -1672,10 +1709,13 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
1672 *errp = sctp_make_op_error_space(asoc, chunk, 1709 *errp = sctp_make_op_error_space(asoc, chunk,
1673 ntohs(chunk->chunk_hdr->length)); 1710 ntohs(chunk->chunk_hdr->length));
1674 1711
1675 if (*errp) 1712 if (*errp) {
1676 sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, 1713 sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
1677 param.v,
1678 WORD_ROUND(ntohs(param.p->length))); 1714 WORD_ROUND(ntohs(param.p->length)));
1715 sctp_addto_chunk(*errp,
1716 WORD_ROUND(ntohs(param.p->length)),
1717 param.v);
1718 }
1679 1719
1680 break; 1720 break;
1681 case SCTP_PARAM_ACTION_SKIP: 1721 case SCTP_PARAM_ACTION_SKIP:
@@ -1690,8 +1730,10 @@ static int sctp_process_unk_param(const struct sctp_association *asoc,
1690 1730
1691 if (*errp) { 1731 if (*errp) {
1692 sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM, 1732 sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
1693 param.v,
1694 WORD_ROUND(ntohs(param.p->length))); 1733 WORD_ROUND(ntohs(param.p->length)));
1734 sctp_addto_chunk(*errp,
1735 WORD_ROUND(ntohs(param.p->length)),
1736 param.v);
1695 } else { 1737 } else {
1696 /* If there is no memory for generating the ERROR 1738 /* If there is no memory for generating the ERROR
1697 * report as specified, an ABORT will be triggered 1739 * report as specified, an ABORT will be triggered
@@ -1791,7 +1833,7 @@ int sctp_verify_init(const struct sctp_association *asoc,
1791 * VIOLATION error. We build the ERROR chunk here and let the normal 1833 * VIOLATION error. We build the ERROR chunk here and let the normal
1792 * error handling code build and send the packet. 1834 * error handling code build and send the packet.
1793 */ 1835 */
1794 if (param.v < (void*)chunk->chunk_end - sizeof(sctp_paramhdr_t)) { 1836 if (param.v != (void*)chunk->chunk_end) {
1795 sctp_process_inv_paramlength(asoc, param.p, chunk, errp); 1837 sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
1796 return 0; 1838 return 0;
1797 } 1839 }
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index d9fad4f6ffc3..8d7890083493 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1013,8 +1013,9 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
1013 break; 1013 break;
1014 1014
1015 case SCTP_DISPOSITION_VIOLATION: 1015 case SCTP_DISPOSITION_VIOLATION:
1016 printk(KERN_ERR "sctp protocol violation state %d " 1016 if (net_ratelimit())
1017 "chunkid %d\n", state, subtype.chunk); 1017 printk(KERN_ERR "sctp protocol violation state %d "
1018 "chunkid %d\n", state, subtype.chunk);
1018 break; 1019 break;
1019 1020
1020 case SCTP_DISPOSITION_NOT_IMPL: 1021 case SCTP_DISPOSITION_NOT_IMPL:
@@ -1130,6 +1131,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1130 /* Move the Cumulattive TSN Ack ahead. */ 1131 /* Move the Cumulattive TSN Ack ahead. */
1131 sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32); 1132 sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32);
1132 1133
1134 /* purge the fragmentation queue */
1135 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, cmd->obj.u32);
1136
1133 /* Abort any in progress partial delivery. */ 1137 /* Abort any in progress partial delivery. */
1134 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); 1138 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
1135 break; 1139 break;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 71cad56dd73f..177528ed3e1b 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -264,7 +264,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
264 struct sctp_chunk *err_chunk; 264 struct sctp_chunk *err_chunk;
265 struct sctp_packet *packet; 265 struct sctp_packet *packet;
266 sctp_unrecognized_param_t *unk_param; 266 sctp_unrecognized_param_t *unk_param;
267 struct sock *sk;
268 int len; 267 int len;
269 268
270 /* 6.10 Bundling 269 /* 6.10 Bundling
@@ -285,16 +284,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
285 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) 284 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
286 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 285 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
287 286
288 sk = ep->base.sk;
289 /* If the endpoint is not listening or if the number of associations
290 * on the TCP-style socket exceed the max backlog, respond with an
291 * ABORT.
292 */
293 if (!sctp_sstate(sk, LISTENING) ||
294 (sctp_style(sk, TCP) &&
295 sk_acceptq_is_full(sk)))
296 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
297
298 /* 3.1 A packet containing an INIT chunk MUST have a zero Verification 287 /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
299 * Tag. 288 * Tag.
300 */ 289 */
@@ -590,6 +579,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
590 struct sctp_ulpevent *ev, *ai_ev = NULL; 579 struct sctp_ulpevent *ev, *ai_ev = NULL;
591 int error = 0; 580 int error = 0;
592 struct sctp_chunk *err_chk_p; 581 struct sctp_chunk *err_chk_p;
582 struct sock *sk;
593 583
594 /* If the packet is an OOTB packet which is temporarily on the 584 /* If the packet is an OOTB packet which is temporarily on the
595 * control endpoint, respond with an ABORT. 585 * control endpoint, respond with an ABORT.
@@ -605,6 +595,15 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
605 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t))) 595 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
606 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 596 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
607 597
598 /* If the endpoint is not listening or if the number of associations
599 * on the TCP-style socket exceed the max backlog, respond with an
600 * ABORT.
601 */
602 sk = ep->base.sk;
603 if (!sctp_sstate(sk, LISTENING) ||
604 (sctp_style(sk, TCP) && sk_acceptq_is_full(sk)))
605 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
606
608 /* "Decode" the chunk. We have no optional parameters so we 607 /* "Decode" the chunk. We have no optional parameters so we
609 * are in good shape. 608 * are in good shape.
610 */ 609 */
@@ -1032,19 +1031,21 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
1032 /* This should never happen, but lets log it if so. */ 1031 /* This should never happen, but lets log it if so. */
1033 if (unlikely(!link)) { 1032 if (unlikely(!link)) {
1034 if (from_addr.sa.sa_family == AF_INET6) { 1033 if (from_addr.sa.sa_family == AF_INET6) {
1035 printk(KERN_WARNING 1034 if (net_ratelimit())
1036 "%s association %p could not find address " 1035 printk(KERN_WARNING
1037 NIP6_FMT "\n", 1036 "%s association %p could not find address "
1038 __FUNCTION__, 1037 NIP6_FMT "\n",
1039 asoc, 1038 __FUNCTION__,
1040 NIP6(from_addr.v6.sin6_addr)); 1039 asoc,
1040 NIP6(from_addr.v6.sin6_addr));
1041 } else { 1041 } else {
1042 printk(KERN_WARNING 1042 if (net_ratelimit())
1043 "%s association %p could not find address " 1043 printk(KERN_WARNING
1044 NIPQUAD_FMT "\n", 1044 "%s association %p could not find address "
1045 __FUNCTION__, 1045 NIPQUAD_FMT "\n",
1046 asoc, 1046 __FUNCTION__,
1047 NIPQUAD(from_addr.v4.sin_addr.s_addr)); 1047 asoc,
1048 NIPQUAD(from_addr.v4.sin_addr.s_addr));
1048 } 1049 }
1049 return SCTP_DISPOSITION_DISCARD; 1050 return SCTP_DISPOSITION_DISCARD;
1050 } 1051 }
@@ -3362,7 +3363,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3362 abort = sctp_make_abort(asoc, asconf_ack, 3363 abort = sctp_make_abort(asoc, asconf_ack,
3363 sizeof(sctp_errhdr_t)); 3364 sizeof(sctp_errhdr_t));
3364 if (abort) { 3365 if (abort) {
3365 sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, NULL, 0); 3366 sctp_init_cause(abort, SCTP_ERROR_ASCONF_ACK, 0);
3366 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 3367 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3367 SCTP_CHUNK(abort)); 3368 SCTP_CHUNK(abort));
3368 } 3369 }
@@ -3392,7 +3393,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3392 abort = sctp_make_abort(asoc, asconf_ack, 3393 abort = sctp_make_abort(asoc, asconf_ack,
3393 sizeof(sctp_errhdr_t)); 3394 sizeof(sctp_errhdr_t));
3394 if (abort) { 3395 if (abort) {
3395 sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, NULL, 0); 3396 sctp_init_cause(abort, SCTP_ERROR_RSRC_LOW, 0);
3396 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 3397 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3397 SCTP_CHUNK(abort)); 3398 SCTP_CHUNK(abort));
3398 } 3399 }
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 01c6364245b7..33354602ae86 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -353,6 +353,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
353 * The function sctp_get_port_local() does duplicate address 353 * The function sctp_get_port_local() does duplicate address
354 * detection. 354 * detection.
355 */ 355 */
356 addr->v4.sin_port = htons(snum);
356 if ((ret = sctp_get_port_local(sk, addr))) { 357 if ((ret = sctp_get_port_local(sk, addr))) {
357 if (ret == (long) sk) { 358 if (ret == (long) sk) {
358 /* This endpoint has a conflicting address. */ 359 /* This endpoint has a conflicting address. */
@@ -5202,6 +5203,7 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5202 5203
5203 sctp_unhash_endpoint(ep); 5204 sctp_unhash_endpoint(ep);
5204 sk->sk_state = SCTP_SS_CLOSED; 5205 sk->sk_state = SCTP_SS_CLOSED;
5206 return 0;
5205 } 5207 }
5206 5208
5207 /* Return if we are already listening. */ 5209 /* Return if we are already listening. */
@@ -5249,6 +5251,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
5249 5251
5250 sctp_unhash_endpoint(ep); 5252 sctp_unhash_endpoint(ep);
5251 sk->sk_state = SCTP_SS_CLOSED; 5253 sk->sk_state = SCTP_SS_CLOSED;
5254 return 0;
5252 } 5255 }
5253 5256
5254 if (sctp_sstate(sk, LISTENING)) 5257 if (sctp_sstate(sk, LISTENING))
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 34eb977a204d..fa0ba2a5564e 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -659,6 +659,46 @@ done:
659 return retval; 659 return retval;
660} 660}
661 661
662/*
663 * Flush out stale fragments from the reassembly queue when processing
664 * a Forward TSN.
665 *
666 * RFC 3758, Section 3.6
667 *
668 * After receiving and processing a FORWARD TSN, the data receiver MUST
669 * take cautions in updating its re-assembly queue. The receiver MUST
670 * remove any partially reassembled message, which is still missing one
671 * or more TSNs earlier than or equal to the new cumulative TSN point.
672 * In the event that the receiver has invoked the partial delivery API,
673 * a notification SHOULD also be generated to inform the upper layer API
674 * that the message being partially delivered will NOT be completed.
675 */
676void sctp_ulpq_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 fwd_tsn)
677{
678 struct sk_buff *pos, *tmp;
679 struct sctp_ulpevent *event;
680 __u32 tsn;
681
682 if (skb_queue_empty(&ulpq->reasm))
683 return;
684
685 skb_queue_walk_safe(&ulpq->reasm, pos, tmp) {
686 event = sctp_skb2event(pos);
687 tsn = event->tsn;
688
689 /* Since the entire message must be abandoned by the
690 * sender (item A3 in Section 3.5, RFC 3758), we can
691 * free all fragments on the list that are less then
692 * or equal to ctsn_point
693 */
694 if (TSN_lte(tsn, fwd_tsn)) {
695 __skb_unlink(pos, &ulpq->reasm);
696 sctp_ulpevent_free(event);
697 } else
698 break;
699 }
700}
701
662/* Helper function to gather skbs that have possibly become 702/* Helper function to gather skbs that have possibly become
663 * ordered by an an incoming chunk. 703 * ordered by an an incoming chunk.
664 */ 704 */
@@ -794,7 +834,7 @@ static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
794/* Helper function to gather skbs that have possibly become 834/* Helper function to gather skbs that have possibly become
795 * ordered by forward tsn skipping their dependencies. 835 * ordered by forward tsn skipping their dependencies.
796 */ 836 */
797static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq) 837static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid)
798{ 838{
799 struct sk_buff *pos, *tmp; 839 struct sk_buff *pos, *tmp;
800 struct sctp_ulpevent *cevent; 840 struct sctp_ulpevent *cevent;
@@ -813,31 +853,40 @@ static inline void sctp_ulpq_reap_ordered(struct sctp_ulpq *ulpq)
813 csid = cevent->stream; 853 csid = cevent->stream;
814 cssn = cevent->ssn; 854 cssn = cevent->ssn;
815 855
816 if (cssn != sctp_ssn_peek(in, csid)) 856 /* Have we gone too far? */
857 if (csid > sid)
817 break; 858 break;
818 859
819 /* Found it, so mark in the ssnmap. */ 860 /* Have we not gone far enough? */
820 sctp_ssn_next(in, csid); 861 if (csid < sid)
862 continue;
863
864 /* see if this ssn has been marked by skipping */
865 if (!SSN_lt(cssn, sctp_ssn_peek(in, csid)))
866 break;
821 867
822 __skb_unlink(pos, &ulpq->lobby); 868 __skb_unlink(pos, &ulpq->lobby);
823 if (!event) { 869 if (!event)
824 /* Create a temporary list to collect chunks on. */ 870 /* Create a temporary list to collect chunks on. */
825 event = sctp_skb2event(pos); 871 event = sctp_skb2event(pos);
826 __skb_queue_tail(&temp, sctp_event2skb(event)); 872
827 } else { 873 /* Attach all gathered skbs to the event. */
828 /* Attach all gathered skbs to the event. */ 874 __skb_queue_tail(&temp, pos);
829 __skb_queue_tail(&temp, pos);
830 }
831 } 875 }
832 876
833 /* Send event to the ULP. 'event' is the sctp_ulpevent for 877 /* Send event to the ULP. 'event' is the sctp_ulpevent for
834 * very first SKB on the 'temp' list. 878 * very first SKB on the 'temp' list.
835 */ 879 */
836 if (event) 880 if (event) {
881 /* see if we have more ordered that we can deliver */
882 sctp_ulpq_retrieve_ordered(ulpq, event);
837 sctp_ulpq_tail_event(ulpq, event); 883 sctp_ulpq_tail_event(ulpq, event);
884 }
838} 885}
839 886
840/* Skip over an SSN. */ 887/* Skip over an SSN. This is used during the processing of
888 * Forwared TSN chunk to skip over the abandoned ordered data
889 */
841void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn) 890void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
842{ 891{
843 struct sctp_stream *in; 892 struct sctp_stream *in;
@@ -855,7 +904,7 @@ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
855 /* Go find any other chunks that were waiting for 904 /* Go find any other chunks that were waiting for
856 * ordering and deliver them if needed. 905 * ordering and deliver them if needed.
857 */ 906 */
858 sctp_ulpq_reap_ordered(ulpq); 907 sctp_ulpq_reap_ordered(ulpq, sid);
859 return; 908 return;
860} 909}
861 910