1 /* SCTP kernel implementation 2 * (C) Copyright IBM Corp. 2001, 2004 3 * Copyright (c) 1999-2000 Cisco, Inc. 4 * Copyright (c) 1999-2001 Motorola, Inc. 5 * Copyright (c) 2001 Intel Corp. 6 * 7 * This file is part of the SCTP kernel implementation 8 * 9 * These functions manipulate sctp tsn mapping array. 10 * 11 * This SCTP implementation is free software; 12 * you can redistribute it and/or modify it under the terms of 13 * the GNU General Public License as published by 14 * the Free Software Foundation; either version 2, or (at your option) 15 * any later version. 16 * 17 * This SCTP implementation is distributed in the hope that it 18 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 19 * ************************ 20 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 * See the GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with GNU CC; see the file COPYING. If not, see 25 * <http://www.gnu.org/licenses/>. 26 * 27 * Please send any bug reports or fixes you make to the 28 * email address(es): 29 * lksctp developers <linux-sctp@vger.kernel.org> 30 * 31 * Written or modified by: 32 * Xin Long <lucien.xin@gmail.com> 33 */ 34 35 #include <linux/list.h> 36 #include <net/sctp/sctp.h> 37 #include <net/sctp/sm.h> 38 #include <net/sctp/stream_sched.h> 39 40 /* Migrates chunks from stream queues to new stream queues if needed, 41 * but not across associations. Also, removes those chunks to streams 42 * higher than the new max. 43 */ 44 static void sctp_stream_outq_migrate(struct sctp_stream *stream, 45 struct sctp_stream *new, __u16 outcnt) 46 { 47 struct sctp_association *asoc; 48 struct sctp_chunk *ch, *temp; 49 struct sctp_outq *outq; 50 int i; 51 52 asoc = container_of(stream, struct sctp_association, stream); 53 outq = &asoc->outqueue; 54 55 list_for_each_entry_safe(ch, temp, &outq->out_chunk_list, list) { 56 __u16 sid = sctp_chunk_stream_no(ch); 57 58 if (sid < outcnt) 59 continue; 60 61 sctp_sched_dequeue_common(outq, ch); 62 /* No need to call dequeue_done here because 63 * the chunks are not scheduled by now. 64 */ 65 66 /* Mark as failed send. */ 67 sctp_chunk_fail(ch, (__force __u32)SCTP_ERROR_INV_STRM); 68 if (asoc->peer.prsctp_capable && 69 SCTP_PR_PRIO_ENABLED(ch->sinfo.sinfo_flags)) 70 asoc->sent_cnt_removable--; 71 72 sctp_chunk_free(ch); 73 } 74 75 if (new) { 76 /* Here we actually move the old ext stuff into the new 77 * buffer, because we want to keep it. Then 78 * sctp_stream_update will swap ->out pointers. 79 */ 80 for (i = 0; i < outcnt; i++) { 81 kfree(new->out[i].ext); 82 new->out[i].ext = stream->out[i].ext; 83 stream->out[i].ext = NULL; 84 } 85 } 86 87 for (i = outcnt; i < stream->outcnt; i++) 88 kfree(stream->out[i].ext); 89 } 90 91 static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, 92 gfp_t gfp) 93 { 94 struct sctp_stream_out *out; 95 96 out = kmalloc_array(outcnt, sizeof(*out), gfp); 97 if (!out) 98 return -ENOMEM; 99 100 if (stream->out) { 101 memcpy(out, stream->out, min(outcnt, stream->outcnt) * 102 sizeof(*out)); 103 kfree(stream->out); 104 } 105 106 if (outcnt > stream->outcnt) 107 memset(out + stream->outcnt, 0, 108 (outcnt - stream->outcnt) * sizeof(*out)); 109 110 stream->out = out; 111 112 return 0; 113 } 114 115 static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, 116 gfp_t gfp) 117 { 118 struct sctp_stream_in *in; 119 120 in = kmalloc_array(incnt, sizeof(*stream->in), gfp); 121 122 if (!in) 123 return -ENOMEM; 124 125 if (stream->in) { 126 memcpy(in, stream->in, min(incnt, stream->incnt) * 127 sizeof(*in)); 128 kfree(stream->in); 129 } 130 131 if (incnt > stream->incnt) 132 memset(in + stream->incnt, 0, 133 (incnt - stream->incnt) * sizeof(*in)); 134 135 stream->in = in; 136 137 return 0; 138 } 139 140 int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, 141 gfp_t gfp) 142 { 143 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); 144 int i, ret = 0; 145 146 gfp |= __GFP_NOWARN; 147 148 /* Initial stream->out size may be very big, so free it and alloc 149 * a new one with new outcnt to save memory if needed. 150 */ 151 if (outcnt == stream->outcnt) 152 goto in; 153 154 /* Filter out chunks queued on streams that won't exist anymore */ 155 sched->unsched_all(stream); 156 sctp_stream_outq_migrate(stream, NULL, outcnt); 157 sched->sched_all(stream); 158 159 i = sctp_stream_alloc_out(stream, outcnt, gfp); 160 if (i) 161 return i; 162 163 stream->outcnt = outcnt; 164 for (i = 0; i < stream->outcnt; i++) 165 stream->out[i].state = SCTP_STREAM_OPEN; 166 167 sched->init(stream); 168 169 in: 170 if (!incnt) 171 goto out; 172 173 i = sctp_stream_alloc_in(stream, incnt, gfp); 174 if (i) { 175 ret = -ENOMEM; 176 goto free; 177 } 178 179 stream->incnt = incnt; 180 goto out; 181 182 free: 183 sched->free(stream); 184 kfree(stream->out); 185 stream->out = NULL; 186 out: 187 return ret; 188 } 189 190 int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid) 191 { 192 struct sctp_stream_out_ext *soute; 193 194 soute = kzalloc(sizeof(*soute), GFP_KERNEL); 195 if (!soute) 196 return -ENOMEM; 197 stream->out[sid].ext = soute; 198 199 return sctp_sched_init_sid(stream, sid, GFP_KERNEL); 200 } 201 202 void sctp_stream_free(struct sctp_stream *stream) 203 { 204 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); 205 int i; 206 207 sched->free(stream); 208 for (i = 0; i < stream->outcnt; i++) 209 kfree(stream->out[i].ext); 210 kfree(stream->out); 211 kfree(stream->in); 212 } 213 214 void sctp_stream_clear(struct sctp_stream *stream) 215 { 216 int i; 217 218 for (i = 0; i < stream->outcnt; i++) 219 stream->out[i].ssn = 0; 220 221 for (i = 0; i < stream->incnt; i++) 222 stream->in[i].ssn = 0; 223 } 224 225 void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new) 226 { 227 struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); 228 229 sched->unsched_all(stream); 230 sctp_stream_outq_migrate(stream, new, new->outcnt); 231 sctp_stream_free(stream); 232 233 stream->out = new->out; 234 stream->in = new->in; 235 stream->outcnt = new->outcnt; 236 stream->incnt = new->incnt; 237 238 sched->sched_all(stream); 239 240 new->out = NULL; 241 new->in = NULL; 242 } 243 244 static int sctp_send_reconf(struct sctp_association *asoc, 245 struct sctp_chunk *chunk) 246 { 247 struct net *net = sock_net(asoc->base.sk); 248 int retval = 0; 249 250 retval = sctp_primitive_RECONF(net, asoc, chunk); 251 if (retval) 252 sctp_chunk_free(chunk); 253 254 return retval; 255 } 256 257 static bool sctp_stream_outq_is_empty(struct sctp_stream *stream, 258 __u16 str_nums, __be16 *str_list) 259 { 260 struct sctp_association *asoc; 261 __u16 i; 262 263 asoc = container_of(stream, struct sctp_association, stream); 264 if (!asoc->outqueue.out_qlen) 265 return true; 266 267 if (!str_nums) 268 return false; 269 270 for (i = 0; i < str_nums; i++) { 271 __u16 sid = ntohs(str_list[i]); 272 273 if (stream->out[sid].ext && 274 !list_empty(&stream->out[sid].ext->outq)) 275 return false; 276 } 277 278 return true; 279 } 280 281 int sctp_send_reset_streams(struct sctp_association *asoc, 282 struct sctp_reset_streams *params) 283 { 284 struct sctp_stream *stream = &asoc->stream; 285 __u16 i, str_nums, *str_list; 286 struct sctp_chunk *chunk; 287 int retval = -EINVAL; 288 __be16 *nstr_list; 289 bool out, in; 290 291 if (!asoc->peer.reconf_capable || 292 !(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) { 293 retval = -ENOPROTOOPT; 294 goto out; 295 } 296 297 if (asoc->strreset_outstanding) { 298 retval = -EINPROGRESS; 299 goto out; 300 } 301 302 out = params->srs_flags & SCTP_STREAM_RESET_OUTGOING; 303 in = params->srs_flags & SCTP_STREAM_RESET_INCOMING; 304 if (!out && !in) 305 goto out; 306 307 str_nums = params->srs_number_streams; 308 str_list = params->srs_stream_list; 309 if (str_nums) { 310 int param_len = 0; 311 312 if (out) { 313 for (i = 0; i < str_nums; i++) 314 if (str_list[i] >= stream->outcnt) 315 goto out; 316 317 param_len = str_nums * sizeof(__u16) + 318 sizeof(struct sctp_strreset_outreq); 319 } 320 321 if (in) { 322 for (i = 0; i < str_nums; i++) 323 if (str_list[i] >= stream->incnt) 324 goto out; 325 326 param_len += str_nums * sizeof(__u16) + 327 sizeof(struct sctp_strreset_inreq); 328 } 329 330 if (param_len > SCTP_MAX_CHUNK_LEN - 331 sizeof(struct sctp_reconf_chunk)) 332 goto out; 333 } 334 335 nstr_list = kcalloc(str_nums, sizeof(__be16), GFP_KERNEL); 336 if (!nstr_list) { 337 retval = -ENOMEM; 338 goto out; 339 } 340 341 for (i = 0; i < str_nums; i++) 342 nstr_list[i] = htons(str_list[i]); 343 344 if (out && !sctp_stream_outq_is_empty(stream, str_nums, nstr_list)) { 345 retval = -EAGAIN; 346 goto out; 347 } 348 349 chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in); 350 351 kfree(nstr_list); 352 353 if (!chunk) { 354 retval = -ENOMEM; 355 goto out; 356 } 357 358 if (out) { 359 if (str_nums) 360 for (i = 0; i < str_nums; i++) 361 stream->out[str_list[i]].state = 362 SCTP_STREAM_CLOSED; 363 else 364 for (i = 0; i < stream->outcnt; i++) 365 stream->out[i].state = SCTP_STREAM_CLOSED; 366 } 367 368 asoc->strreset_chunk = chunk; 369 sctp_chunk_hold(asoc->strreset_chunk); 370 371 retval = sctp_send_reconf(asoc, chunk); 372 if (retval) { 373 sctp_chunk_put(asoc->strreset_chunk); 374 asoc->strreset_chunk = NULL; 375 if (!out) 376 goto out; 377 378 if (str_nums) 379 for (i = 0; i < str_nums; i++) 380 stream->out[str_list[i]].state = 381 SCTP_STREAM_OPEN; 382 else 383 for (i = 0; i < stream->outcnt; i++) 384 stream->out[i].state = SCTP_STREAM_OPEN; 385 386 goto out; 387 } 388 389 asoc->strreset_outstanding = out + in; 390 391 out: 392 return retval; 393 } 394 395 int sctp_send_reset_assoc(struct sctp_association *asoc) 396 { 397 struct sctp_stream *stream = &asoc->stream; 398 struct sctp_chunk *chunk = NULL; 399 int retval; 400 __u16 i; 401 402 if (!asoc->peer.reconf_capable || 403 !(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ)) 404 return -ENOPROTOOPT; 405 406 if (asoc->strreset_outstanding) 407 return -EINPROGRESS; 408 409 if (!sctp_outq_is_empty(&asoc->outqueue)) 410 return -EAGAIN; 411 412 chunk = sctp_make_strreset_tsnreq(asoc); 413 if (!chunk) 414 return -ENOMEM; 415 416 /* Block further xmit of data until this request is completed */ 417 for (i = 0; i < stream->outcnt; i++) 418 stream->out[i].state = SCTP_STREAM_CLOSED; 419 420 asoc->strreset_chunk = chunk; 421 sctp_chunk_hold(asoc->strreset_chunk); 422 423 retval = sctp_send_reconf(asoc, chunk); 424 if (retval) { 425 sctp_chunk_put(asoc->strreset_chunk); 426 asoc->strreset_chunk = NULL; 427 428 for (i = 0; i < stream->outcnt; i++) 429 stream->out[i].state = SCTP_STREAM_OPEN; 430 431 return retval; 432 } 433 434 asoc->strreset_outstanding = 1; 435 436 return 0; 437 } 438 439 int sctp_send_add_streams(struct sctp_association *asoc, 440 struct sctp_add_streams *params) 441 { 442 struct sctp_stream *stream = &asoc->stream; 443 struct sctp_chunk *chunk = NULL; 444 int retval; 445 __u32 outcnt, incnt; 446 __u16 out, in; 447 448 if (!asoc->peer.reconf_capable || 449 !(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) { 450 retval = -ENOPROTOOPT; 451 goto out; 452 } 453 454 if (asoc->strreset_outstanding) { 455 retval = -EINPROGRESS; 456 goto out; 457 } 458 459 out = params->sas_outstrms; 460 in = params->sas_instrms; 461 outcnt = stream->outcnt + out; 462 incnt = stream->incnt + in; 463 if (outcnt > SCTP_MAX_STREAM || incnt > SCTP_MAX_STREAM || 464 (!out && !in)) { 465 retval = -EINVAL; 466 goto out; 467 } 468 469 if (out) { 470 retval = sctp_stream_alloc_out(stream, outcnt, GFP_KERNEL); 471 if (retval) 472 goto out; 473 } 474 475 chunk = sctp_make_strreset_addstrm(asoc, out, in); 476 if (!chunk) { 477 retval = -ENOMEM; 478 goto out; 479 } 480 481 asoc->strreset_chunk = chunk; 482 sctp_chunk_hold(asoc->strreset_chunk); 483 484 retval = sctp_send_reconf(asoc, chunk); 485 if (retval) { 486 sctp_chunk_put(asoc->strreset_chunk); 487 asoc->strreset_chunk = NULL; 488 goto out; 489 } 490 491 stream->incnt = incnt; 492 stream->outcnt = outcnt; 493 494 asoc->strreset_outstanding = !!out + !!in; 495 496 out: 497 return retval; 498 } 499 500 static struct sctp_paramhdr *sctp_chunk_lookup_strreset_param( 501 struct sctp_association *asoc, __be32 resp_seq, 502 __be16 type) 503 { 504 struct sctp_chunk *chunk = asoc->strreset_chunk; 505 struct sctp_reconf_chunk *hdr; 506 union sctp_params param; 507 508 if (!chunk) 509 return NULL; 510 511 hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr; 512 sctp_walk_params(param, hdr, params) { 513 /* sctp_strreset_tsnreq is actually the basic structure 514 * of all stream reconf params, so it's safe to use it 515 * to access request_seq. 516 */ 517 struct sctp_strreset_tsnreq *req = param.v; 518 519 if ((!resp_seq || req->request_seq == resp_seq) && 520 (!type || type == req->param_hdr.type)) 521 return param.v; 522 } 523 524 return NULL; 525 } 526 527 static void sctp_update_strreset_result(struct sctp_association *asoc, 528 __u32 result) 529 { 530 asoc->strreset_result[1] = asoc->strreset_result[0]; 531 asoc->strreset_result[0] = result; 532 } 533 534 struct sctp_chunk *sctp_process_strreset_outreq( 535 struct sctp_association *asoc, 536 union sctp_params param, 537 struct sctp_ulpevent **evp) 538 { 539 struct sctp_strreset_outreq *outreq = param.v; 540 struct sctp_stream *stream = &asoc->stream; 541 __u32 result = SCTP_STRRESET_DENIED; 542 __u16 i, nums, flags = 0; 543 __be16 *str_p = NULL; 544 __u32 request_seq; 545 546 request_seq = ntohl(outreq->request_seq); 547 548 if (ntohl(outreq->send_reset_at_tsn) > 549 sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)) { 550 result = SCTP_STRRESET_IN_PROGRESS; 551 goto err; 552 } 553 554 if (TSN_lt(asoc->strreset_inseq, request_seq) || 555 TSN_lt(request_seq, asoc->strreset_inseq - 2)) { 556 result = SCTP_STRRESET_ERR_BAD_SEQNO; 557 goto err; 558 } else if (TSN_lt(request_seq, asoc->strreset_inseq)) { 559 i = asoc->strreset_inseq - request_seq - 1; 560 result = asoc->strreset_result[i]; 561 goto err; 562 } 563 asoc->strreset_inseq++; 564 565 /* Check strreset_enable after inseq inc, as sender cannot tell 566 * the peer doesn't enable strreset after receiving response with 567 * result denied, as well as to keep consistent with bsd. 568 */ 569 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) 570 goto out; 571 572 if (asoc->strreset_chunk) { 573 if (!sctp_chunk_lookup_strreset_param( 574 asoc, outreq->response_seq, 575 SCTP_PARAM_RESET_IN_REQUEST)) { 576 /* same process with outstanding isn't 0 */ 577 result = SCTP_STRRESET_ERR_IN_PROGRESS; 578 goto out; 579 } 580 581 asoc->strreset_outstanding--; 582 asoc->strreset_outseq++; 583 584 if (!asoc->strreset_outstanding) { 585 struct sctp_transport *t; 586 587 t = asoc->strreset_chunk->transport; 588 if (del_timer(&t->reconf_timer)) 589 sctp_transport_put(t); 590 591 sctp_chunk_put(asoc->strreset_chunk); 592 asoc->strreset_chunk = NULL; 593 } 594 595 flags = SCTP_STREAM_RESET_INCOMING_SSN; 596 } 597 598 nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16); 599 if (nums) { 600 str_p = outreq->list_of_streams; 601 for (i = 0; i < nums; i++) { 602 if (ntohs(str_p[i]) >= stream->incnt) { 603 result = SCTP_STRRESET_ERR_WRONG_SSN; 604 goto out; 605 } 606 } 607 608 for (i = 0; i < nums; i++) 609 stream->in[ntohs(str_p[i])].ssn = 0; 610 } else { 611 for (i = 0; i < stream->incnt; i++) 612 stream->in[i].ssn = 0; 613 } 614 615 result = SCTP_STRRESET_PERFORMED; 616 617 *evp = sctp_ulpevent_make_stream_reset_event(asoc, 618 flags | SCTP_STREAM_RESET_OUTGOING_SSN, nums, str_p, 619 GFP_ATOMIC); 620 621 out: 622 sctp_update_strreset_result(asoc, result); 623 err: 624 return sctp_make_strreset_resp(asoc, result, request_seq); 625 } 626 627 struct sctp_chunk *sctp_process_strreset_inreq( 628 struct sctp_association *asoc, 629 union sctp_params param, 630 struct sctp_ulpevent **evp) 631 { 632 struct sctp_strreset_inreq *inreq = param.v; 633 struct sctp_stream *stream = &asoc->stream; 634 __u32 result = SCTP_STRRESET_DENIED; 635 struct sctp_chunk *chunk = NULL; 636 __u32 request_seq; 637 __u16 i, nums; 638 __be16 *str_p; 639 640 request_seq = ntohl(inreq->request_seq); 641 if (TSN_lt(asoc->strreset_inseq, request_seq) || 642 TSN_lt(request_seq, asoc->strreset_inseq - 2)) { 643 result = SCTP_STRRESET_ERR_BAD_SEQNO; 644 goto err; 645 } else if (TSN_lt(request_seq, asoc->strreset_inseq)) { 646 i = asoc->strreset_inseq - request_seq - 1; 647 result = asoc->strreset_result[i]; 648 if (result == SCTP_STRRESET_PERFORMED) 649 return NULL; 650 goto err; 651 } 652 asoc->strreset_inseq++; 653 654 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) 655 goto out; 656 657 if (asoc->strreset_outstanding) { 658 result = SCTP_STRRESET_ERR_IN_PROGRESS; 659 goto out; 660 } 661 662 nums = (ntohs(param.p->length) - sizeof(*inreq)) / sizeof(__u16); 663 str_p = inreq->list_of_streams; 664 for (i = 0; i < nums; i++) { 665 if (ntohs(str_p[i]) >= stream->outcnt) { 666 result = SCTP_STRRESET_ERR_WRONG_SSN; 667 goto out; 668 } 669 } 670 671 if (!sctp_stream_outq_is_empty(stream, nums, str_p)) { 672 result = SCTP_STRRESET_IN_PROGRESS; 673 asoc->strreset_inseq--; 674 goto err; 675 } 676 677 chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0); 678 if (!chunk) 679 goto out; 680 681 if (nums) 682 for (i = 0; i < nums; i++) 683 stream->out[ntohs(str_p[i])].state = 684 SCTP_STREAM_CLOSED; 685 else 686 for (i = 0; i < stream->outcnt; i++) 687 stream->out[i].state = SCTP_STREAM_CLOSED; 688 689 asoc->strreset_chunk = chunk; 690 asoc->strreset_outstanding = 1; 691 sctp_chunk_hold(asoc->strreset_chunk); 692 693 result = SCTP_STRRESET_PERFORMED; 694 695 *evp = sctp_ulpevent_make_stream_reset_event(asoc, 696 SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC); 697 698 out: 699 sctp_update_strreset_result(asoc, result); 700 err: 701 if (!chunk) 702 chunk = sctp_make_strreset_resp(asoc, result, request_seq); 703 704 return chunk; 705 } 706 707 struct sctp_chunk *sctp_process_strreset_tsnreq( 708 struct sctp_association *asoc, 709 union sctp_params param, 710 struct sctp_ulpevent **evp) 711 { 712 __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen; 713 struct sctp_strreset_tsnreq *tsnreq = param.v; 714 struct sctp_stream *stream = &asoc->stream; 715 __u32 result = SCTP_STRRESET_DENIED; 716 __u32 request_seq; 717 __u16 i; 718 719 request_seq = ntohl(tsnreq->request_seq); 720 if (TSN_lt(asoc->strreset_inseq, request_seq) || 721 TSN_lt(request_seq, asoc->strreset_inseq - 2)) { 722 result = SCTP_STRRESET_ERR_BAD_SEQNO; 723 goto err; 724 } else if (TSN_lt(request_seq, asoc->strreset_inseq)) { 725 i = asoc->strreset_inseq - request_seq - 1; 726 result = asoc->strreset_result[i]; 727 if (result == SCTP_STRRESET_PERFORMED) { 728 next_tsn = asoc->ctsn_ack_point + 1; 729 init_tsn = 730 sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1; 731 } 732 goto err; 733 } 734 735 if (!sctp_outq_is_empty(&asoc->outqueue)) { 736 result = SCTP_STRRESET_IN_PROGRESS; 737 goto err; 738 } 739 740 asoc->strreset_inseq++; 741 742 if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ)) 743 goto out; 744 745 if (asoc->strreset_outstanding) { 746 result = SCTP_STRRESET_ERR_IN_PROGRESS; 747 goto out; 748 } 749 750 /* G4: The same processing as though a FWD-TSN chunk (as defined in 751 * [RFC3758]) with all streams affected and a new cumulative TSN 752 * ACK of the Receiver's Next TSN minus 1 were received MUST be 753 * performed. 754 */ 755 max_tsn_seen = sctp_tsnmap_get_max_tsn_seen(&asoc->peer.tsn_map); 756 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, max_tsn_seen); 757 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); 758 759 /* G1: Compute an appropriate value for the Receiver's Next TSN -- the 760 * TSN that the peer should use to send the next DATA chunk. The 761 * value SHOULD be the smallest TSN not acknowledged by the 762 * receiver of the request plus 2^31. 763 */ 764 init_tsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + (1 << 31); 765 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL, 766 init_tsn, GFP_ATOMIC); 767 768 /* G3: The same processing as though a SACK chunk with no gap report 769 * and a cumulative TSN ACK of the Sender's Next TSN minus 1 were 770 * received MUST be performed. 771 */ 772 sctp_outq_free(&asoc->outqueue); 773 774 /* G2: Compute an appropriate value for the local endpoint's next TSN, 775 * i.e., the next TSN assigned by the receiver of the SSN/TSN reset 776 * chunk. The value SHOULD be the highest TSN sent by the receiver 777 * of the request plus 1. 778 */ 779 next_tsn = asoc->next_tsn; 780 asoc->ctsn_ack_point = next_tsn - 1; 781 asoc->adv_peer_ack_point = asoc->ctsn_ack_point; 782 783 /* G5: The next expected and outgoing SSNs MUST be reset to 0 for all 784 * incoming and outgoing streams. 785 */ 786 for (i = 0; i < stream->outcnt; i++) 787 stream->out[i].ssn = 0; 788 for (i = 0; i < stream->incnt; i++) 789 stream->in[i].ssn = 0; 790 791 result = SCTP_STRRESET_PERFORMED; 792 793 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, 0, init_tsn, 794 next_tsn, GFP_ATOMIC); 795 796 out: 797 sctp_update_strreset_result(asoc, result); 798 err: 799 return sctp_make_strreset_tsnresp(asoc, result, request_seq, 800 next_tsn, init_tsn); 801 } 802 803 struct sctp_chunk *sctp_process_strreset_addstrm_out( 804 struct sctp_association *asoc, 805 union sctp_params param, 806 struct sctp_ulpevent **evp) 807 { 808 struct sctp_strreset_addstrm *addstrm = param.v; 809 struct sctp_stream *stream = &asoc->stream; 810 __u32 result = SCTP_STRRESET_DENIED; 811 __u32 request_seq, incnt; 812 __u16 in, i; 813 814 request_seq = ntohl(addstrm->request_seq); 815 if (TSN_lt(asoc->strreset_inseq, request_seq) || 816 TSN_lt(request_seq, asoc->strreset_inseq - 2)) { 817 result = SCTP_STRRESET_ERR_BAD_SEQNO; 818 goto err; 819 } else if (TSN_lt(request_seq, asoc->strreset_inseq)) { 820 i = asoc->strreset_inseq - request_seq - 1; 821 result = asoc->strreset_result[i]; 822 goto err; 823 } 824 asoc->strreset_inseq++; 825 826 if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) 827 goto out; 828 829 if (asoc->strreset_chunk) { 830 if (!sctp_chunk_lookup_strreset_param( 831 asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) { 832 /* same process with outstanding isn't 0 */ 833 result = SCTP_STRRESET_ERR_IN_PROGRESS; 834 goto out; 835 } 836 837 asoc->strreset_outstanding--; 838 asoc->strreset_outseq++; 839 840 if (!asoc->strreset_outstanding) { 841 struct sctp_transport *t; 842 843 t = asoc->strreset_chunk->transport; 844 if (del_timer(&t->reconf_timer)) 845 sctp_transport_put(t); 846 847 sctp_chunk_put(asoc->strreset_chunk); 848 asoc->strreset_chunk = NULL; 849 } 850 } 851 852 in = ntohs(addstrm->number_of_streams); 853 incnt = stream->incnt + in; 854 if (!in || incnt > SCTP_MAX_STREAM) 855 goto out; 856 857 if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC)) 858 goto out; 859 860 stream->incnt = incnt; 861 862 result = SCTP_STRRESET_PERFORMED; 863 864 *evp = sctp_ulpevent_make_stream_change_event(asoc, 865 0, ntohs(addstrm->number_of_streams), 0, GFP_ATOMIC); 866 867 out: 868 sctp_update_strreset_result(asoc, result); 869 err: 870 return sctp_make_strreset_resp(asoc, result, request_seq); 871 } 872 873 struct sctp_chunk *sctp_process_strreset_addstrm_in( 874 struct sctp_association *asoc, 875 union sctp_params param, 876 struct sctp_ulpevent **evp) 877 { 878 struct sctp_strreset_addstrm *addstrm = param.v; 879 struct sctp_stream *stream = &asoc->stream; 880 __u32 result = SCTP_STRRESET_DENIED; 881 struct sctp_chunk *chunk = NULL; 882 __u32 request_seq, outcnt; 883 __u16 out, i; 884 int ret; 885 886 request_seq = ntohl(addstrm->request_seq); 887 if (TSN_lt(asoc->strreset_inseq, request_seq) || 888 TSN_lt(request_seq, asoc->strreset_inseq - 2)) { 889 result = SCTP_STRRESET_ERR_BAD_SEQNO; 890 goto err; 891 } else if (TSN_lt(request_seq, asoc->strreset_inseq)) { 892 i = asoc->strreset_inseq - request_seq - 1; 893 result = asoc->strreset_result[i]; 894 if (result == SCTP_STRRESET_PERFORMED) 895 return NULL; 896 goto err; 897 } 898 asoc->strreset_inseq++; 899 900 if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) 901 goto out; 902 903 if (asoc->strreset_outstanding) { 904 result = SCTP_STRRESET_ERR_IN_PROGRESS; 905 goto out; 906 } 907 908 out = ntohs(addstrm->number_of_streams); 909 outcnt = stream->outcnt + out; 910 if (!out || outcnt > SCTP_MAX_STREAM) 911 goto out; 912 913 ret = sctp_stream_alloc_out(stream, outcnt, GFP_ATOMIC); 914 if (ret) 915 goto out; 916 917 chunk = sctp_make_strreset_addstrm(asoc, out, 0); 918 if (!chunk) 919 goto out; 920 921 asoc->strreset_chunk = chunk; 922 asoc->strreset_outstanding = 1; 923 sctp_chunk_hold(asoc->strreset_chunk); 924 925 stream->outcnt = outcnt; 926 927 result = SCTP_STRRESET_PERFORMED; 928 929 *evp = sctp_ulpevent_make_stream_change_event(asoc, 930 0, 0, ntohs(addstrm->number_of_streams), GFP_ATOMIC); 931 932 out: 933 sctp_update_strreset_result(asoc, result); 934 err: 935 if (!chunk) 936 chunk = sctp_make_strreset_resp(asoc, result, request_seq); 937 938 return chunk; 939 } 940 941 struct sctp_chunk *sctp_process_strreset_resp( 942 struct sctp_association *asoc, 943 union sctp_params param, 944 struct sctp_ulpevent **evp) 945 { 946 struct sctp_stream *stream = &asoc->stream; 947 struct sctp_strreset_resp *resp = param.v; 948 struct sctp_transport *t; 949 __u16 i, nums, flags = 0; 950 struct sctp_paramhdr *req; 951 __u32 result; 952 953 req = sctp_chunk_lookup_strreset_param(asoc, resp->response_seq, 0); 954 if (!req) 955 return NULL; 956 957 result = ntohl(resp->result); 958 if (result != SCTP_STRRESET_PERFORMED) { 959 /* if in progress, do nothing but retransmit */ 960 if (result == SCTP_STRRESET_IN_PROGRESS) 961 return NULL; 962 else if (result == SCTP_STRRESET_DENIED) 963 flags = SCTP_STREAM_RESET_DENIED; 964 else 965 flags = SCTP_STREAM_RESET_FAILED; 966 } 967 968 if (req->type == SCTP_PARAM_RESET_OUT_REQUEST) { 969 struct sctp_strreset_outreq *outreq; 970 __be16 *str_p; 971 972 outreq = (struct sctp_strreset_outreq *)req; 973 str_p = outreq->list_of_streams; 974 nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) / 975 sizeof(__u16); 976 977 if (result == SCTP_STRRESET_PERFORMED) { 978 if (nums) { 979 for (i = 0; i < nums; i++) 980 stream->out[ntohs(str_p[i])].ssn = 0; 981 } else { 982 for (i = 0; i < stream->outcnt; i++) 983 stream->out[i].ssn = 0; 984 } 985 986 flags = SCTP_STREAM_RESET_OUTGOING_SSN; 987 } 988 989 for (i = 0; i < stream->outcnt; i++) 990 stream->out[i].state = SCTP_STREAM_OPEN; 991 992 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, 993 nums, str_p, GFP_ATOMIC); 994 } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) { 995 struct sctp_strreset_inreq *inreq; 996 __be16 *str_p; 997 998 /* if the result is performed, it's impossible for inreq */ 999 if (result == SCTP_STRRESET_PERFORMED) 1000 return NULL; 1001 1002 inreq = (struct sctp_strreset_inreq *)req; 1003 str_p = inreq->list_of_streams; 1004 nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) / 1005 sizeof(__u16); 1006 1007 *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, 1008 nums, str_p, GFP_ATOMIC); 1009 } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) { 1010 struct sctp_strreset_resptsn *resptsn; 1011 __u32 stsn, rtsn; 1012 1013 /* check for resptsn, as sctp_verify_reconf didn't do it*/ 1014 if (ntohs(param.p->length) != sizeof(*resptsn)) 1015 return NULL; 1016 1017 resptsn = (struct sctp_strreset_resptsn *)resp; 1018 stsn = ntohl(resptsn->senders_next_tsn); 1019 rtsn = ntohl(resptsn->receivers_next_tsn); 1020 1021 if (result == SCTP_STRRESET_PERFORMED) { 1022 __u32 mtsn = sctp_tsnmap_get_max_tsn_seen( 1023 &asoc->peer.tsn_map); 1024 LIST_HEAD(temp); 1025 1026 sctp_ulpq_reasm_flushtsn(&asoc->ulpq, mtsn); 1027 sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); 1028 1029 sctp_tsnmap_init(&asoc->peer.tsn_map, 1030 SCTP_TSN_MAP_INITIAL, 1031 stsn, GFP_ATOMIC); 1032 1033 /* Clean up sacked and abandoned queues only. As the 1034 * out_chunk_list may not be empty, splice it to temp, 1035 * then get it back after sctp_outq_free is done. 1036 */ 1037 list_splice_init(&asoc->outqueue.out_chunk_list, &temp); 1038 sctp_outq_free(&asoc->outqueue); 1039 list_splice_init(&temp, &asoc->outqueue.out_chunk_list); 1040 1041 asoc->next_tsn = rtsn; 1042 asoc->ctsn_ack_point = asoc->next_tsn - 1; 1043 asoc->adv_peer_ack_point = asoc->ctsn_ack_point; 1044 1045 for (i = 0; i < stream->outcnt; i++) 1046 stream->out[i].ssn = 0; 1047 for (i = 0; i < stream->incnt; i++) 1048 stream->in[i].ssn = 0; 1049 } 1050 1051 for (i = 0; i < stream->outcnt; i++) 1052 stream->out[i].state = SCTP_STREAM_OPEN; 1053 1054 *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags, 1055 stsn, rtsn, GFP_ATOMIC); 1056 } else if (req->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS) { 1057 struct sctp_strreset_addstrm *addstrm; 1058 __u16 number; 1059 1060 addstrm = (struct sctp_strreset_addstrm *)req; 1061 nums = ntohs(addstrm->number_of_streams); 1062 number = stream->outcnt - nums; 1063 1064 if (result == SCTP_STRRESET_PERFORMED) 1065 for (i = number; i < stream->outcnt; i++) 1066 stream->out[i].state = SCTP_STREAM_OPEN; 1067 else 1068 stream->outcnt = number; 1069 1070 *evp = sctp_ulpevent_make_stream_change_event(asoc, flags, 1071 0, nums, GFP_ATOMIC); 1072 } else if (req->type == SCTP_PARAM_RESET_ADD_IN_STREAMS) { 1073 struct sctp_strreset_addstrm *addstrm; 1074 1075 /* if the result is performed, it's impossible for addstrm in 1076 * request. 1077 */ 1078 if (result == SCTP_STRRESET_PERFORMED) 1079 return NULL; 1080 1081 addstrm = (struct sctp_strreset_addstrm *)req; 1082 nums = ntohs(addstrm->number_of_streams); 1083 1084 *evp = sctp_ulpevent_make_stream_change_event(asoc, flags, 1085 nums, 0, GFP_ATOMIC); 1086 } 1087 1088 asoc->strreset_outstanding--; 1089 asoc->strreset_outseq++; 1090 1091 /* remove everything for this reconf request */ 1092 if (!asoc->strreset_outstanding) { 1093 t = asoc->strreset_chunk->transport; 1094 if (del_timer(&t->reconf_timer)) 1095 sctp_transport_put(t); 1096 1097 sctp_chunk_put(asoc->strreset_chunk); 1098 asoc->strreset_chunk = NULL; 1099 } 1100 1101 return NULL; 1102 } 1103