aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_make_chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_make_chunk.c')
-rw-r--r--net/sctp/sm_make_chunk.c67
1 files changed, 42 insertions, 25 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index e8ca4e54981f..fd8acb48c3f2 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -702,12 +702,14 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
702 __u32 ctsn; 702 __u32 ctsn;
703 __u16 num_gabs, num_dup_tsns; 703 __u16 num_gabs, num_dup_tsns;
704 struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; 704 struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
705 struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
705 706
707 memset(gabs, 0, sizeof(gabs));
706 ctsn = sctp_tsnmap_get_ctsn(map); 708 ctsn = sctp_tsnmap_get_ctsn(map);
707 SCTP_DEBUG_PRINTK("sackCTSNAck sent: 0x%x.\n", ctsn); 709 SCTP_DEBUG_PRINTK("sackCTSNAck sent: 0x%x.\n", ctsn);
708 710
709 /* How much room is needed in the chunk? */ 711 /* How much room is needed in the chunk? */
710 num_gabs = sctp_tsnmap_num_gabs(map); 712 num_gabs = sctp_tsnmap_num_gabs(map, gabs);
711 num_dup_tsns = sctp_tsnmap_num_dups(map); 713 num_dup_tsns = sctp_tsnmap_num_dups(map);
712 714
713 /* Initialize the SACK header. */ 715 /* Initialize the SACK header. */
@@ -763,7 +765,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
763 /* Add the gap ack block information. */ 765 /* Add the gap ack block information. */
764 if (num_gabs) 766 if (num_gabs)
765 sctp_addto_chunk(retval, sizeof(__u32) * num_gabs, 767 sctp_addto_chunk(retval, sizeof(__u32) * num_gabs,
766 sctp_tsnmap_get_gabs(map)); 768 gabs);
767 769
768 /* Add the duplicate TSN information. */ 770 /* Add the duplicate TSN information. */
769 if (num_dup_tsns) 771 if (num_dup_tsns)
@@ -1012,6 +1014,29 @@ end:
1012 return retval; 1014 return retval;
1013} 1015}
1014 1016
1017struct sctp_chunk *sctp_make_violation_paramlen(
1018 const struct sctp_association *asoc,
1019 const struct sctp_chunk *chunk,
1020 struct sctp_paramhdr *param)
1021{
1022 struct sctp_chunk *retval;
1023 static const char error[] = "The following parameter had invalid length:";
1024 size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
1025 sizeof(sctp_paramhdr_t);
1026
1027 retval = sctp_make_abort(asoc, chunk, payload_len);
1028 if (!retval)
1029 goto nodata;
1030
1031 sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
1032 sizeof(error) + sizeof(sctp_paramhdr_t));
1033 sctp_addto_chunk(retval, sizeof(error), error);
1034 sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
1035
1036nodata:
1037 return retval;
1038}
1039
1015/* Make a HEARTBEAT chunk. */ 1040/* Make a HEARTBEAT chunk. */
1016struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, 1041struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
1017 const struct sctp_transport *transport, 1042 const struct sctp_transport *transport,
@@ -1188,7 +1213,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
1188 */ 1213 */
1189 retval->tsn_missing_report = 0; 1214 retval->tsn_missing_report = 0;
1190 retval->tsn_gap_acked = 0; 1215 retval->tsn_gap_acked = 0;
1191 retval->fast_retransmit = 0; 1216 retval->fast_retransmit = SCTP_CAN_FRTX;
1192 1217
1193 /* If this is a fragmented message, track all fragments 1218 /* If this is a fragmented message, track all fragments
1194 * of the message (for SEND_FAILED). 1219 * of the message (for SEND_FAILED).
@@ -1782,11 +1807,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
1782 const struct sctp_chunk *chunk, 1807 const struct sctp_chunk *chunk,
1783 struct sctp_chunk **errp) 1808 struct sctp_chunk **errp)
1784{ 1809{
1785 static const char error[] = "The following parameter had invalid length:";
1786 size_t payload_len = WORD_ROUND(sizeof(error)) +
1787 sizeof(sctp_paramhdr_t);
1788
1789
1790 /* This is a fatal error. Any accumulated non-fatal errors are 1810 /* This is a fatal error. Any accumulated non-fatal errors are
1791 * not reported. 1811 * not reported.
1792 */ 1812 */
@@ -1794,14 +1814,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
1794 sctp_chunk_free(*errp); 1814 sctp_chunk_free(*errp);
1795 1815
1796 /* Create an error chunk and fill it in with our payload. */ 1816 /* Create an error chunk and fill it in with our payload. */
1797 *errp = sctp_make_op_error_space(asoc, chunk, payload_len); 1817 *errp = sctp_make_violation_paramlen(asoc, chunk, param);
1798
1799 if (*errp) {
1800 sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
1801 sizeof(error) + sizeof(sctp_paramhdr_t));
1802 sctp_addto_chunk(*errp, sizeof(error), error);
1803 sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
1804 }
1805 1818
1806 return 0; 1819 return 0;
1807} 1820}
@@ -1886,11 +1899,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1886 /* if the peer reports AUTH, assume that he 1899 /* if the peer reports AUTH, assume that he
1887 * supports AUTH. 1900 * supports AUTH.
1888 */ 1901 */
1889 asoc->peer.auth_capable = 1; 1902 if (sctp_auth_enable)
1903 asoc->peer.auth_capable = 1;
1890 break; 1904 break;
1891 case SCTP_CID_ASCONF: 1905 case SCTP_CID_ASCONF:
1892 case SCTP_CID_ASCONF_ACK: 1906 case SCTP_CID_ASCONF_ACK:
1893 asoc->peer.asconf_capable = 1; 1907 if (sctp_addip_enable)
1908 asoc->peer.asconf_capable = 1;
1894 break; 1909 break;
1895 default: 1910 default:
1896 break; 1911 break;
@@ -2275,8 +2290,9 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
2275 } 2290 }
2276 2291
2277 /* Set up the TSN tracking pieces. */ 2292 /* Set up the TSN tracking pieces. */
2278 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 2293 if (!sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
2279 asoc->peer.i.initial_tsn); 2294 asoc->peer.i.initial_tsn, gfp))
2295 goto clean_up;
2280 2296
2281 /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number 2297 /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
2282 * 2298 *
@@ -2319,12 +2335,10 @@ clean_up:
2319 /* Release the transport structures. */ 2335 /* Release the transport structures. */
2320 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 2336 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
2321 transport = list_entry(pos, struct sctp_transport, transports); 2337 transport = list_entry(pos, struct sctp_transport, transports);
2322 list_del_init(pos); 2338 if (transport->state != SCTP_ACTIVE)
2323 sctp_transport_free(transport); 2339 sctp_assoc_rm_peer(asoc, transport);
2324 } 2340 }
2325 2341
2326 asoc->peer.transport_count = 0;
2327
2328nomem: 2342nomem:
2329 return 0; 2343 return 0;
2330} 2344}
@@ -2456,10 +2470,13 @@ do_addr_param:
2456 break; 2470 break;
2457 2471
2458 case SCTP_PARAM_ADAPTATION_LAYER_IND: 2472 case SCTP_PARAM_ADAPTATION_LAYER_IND:
2459 asoc->peer.adaptation_ind = param.aind->adaptation_ind; 2473 asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind);
2460 break; 2474 break;
2461 2475
2462 case SCTP_PARAM_SET_PRIMARY: 2476 case SCTP_PARAM_SET_PRIMARY:
2477 if (!sctp_addip_enable)
2478 goto fall_through;
2479
2463 addr_param = param.v + sizeof(sctp_addip_param_t); 2480 addr_param = param.v + sizeof(sctp_addip_param_t);
2464 2481
2465 af = sctp_get_af_specific(param_type2af(param.p->type)); 2482 af = sctp_get_af_specific(param_type2af(param.p->type));