1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* SCTP kernel implementation 3 * (C) Copyright Red Hat Inc. 2017 4 * 5 * This file is part of the SCTP kernel implementation 6 * 7 * These functions implement sctp stream message interleaving, mostly 8 * including I-DATA and I-FORWARD-TSN chunks process. 9 * 10 * Please send any bug reports or fixes you make to the 11 * email addresched(es): 12 * lksctp developers <linux-sctp@vger.kernel.org> 13 * 14 * Written or modified by: 15 * Xin Long <lucien.xin@gmail.com> 16 */ 17 18 #include <net/busy_poll.h> 19 #include <net/sctp/sctp.h> 20 #include <net/sctp/sm.h> 21 #include <net/sctp/ulpevent.h> 22 #include <linux/sctp.h> 23 24 static struct sctp_chunk *sctp_make_idatafrag_empty( 25 const struct sctp_association *asoc, 26 const struct sctp_sndrcvinfo *sinfo, 27 int len, __u8 flags, gfp_t gfp) 28 { 29 struct sctp_chunk *retval; 30 struct sctp_idatahdr dp; 31 32 memset(&dp, 0, sizeof(dp)); 33 dp.stream = htons(sinfo->sinfo_stream); 34 35 if (sinfo->sinfo_flags & SCTP_UNORDERED) 36 flags |= SCTP_DATA_UNORDERED; 37 38 retval = sctp_make_idata(asoc, flags, sizeof(dp) + len, gfp); 39 if (!retval) 40 return NULL; 41 42 retval->subh.idata_hdr = sctp_addto_chunk(retval, sizeof(dp), &dp); 43 memcpy(&retval->sinfo, sinfo, sizeof(struct sctp_sndrcvinfo)); 44 45 return retval; 46 } 47 48 static void sctp_chunk_assign_mid(struct sctp_chunk *chunk) 49 { 50 struct sctp_stream *stream; 51 struct sctp_chunk *lchunk; 52 __u32 cfsn = 0; 53 __u16 sid; 54 55 if (chunk->has_mid) 56 return; 57 58 sid = sctp_chunk_stream_no(chunk); 59 stream = &chunk->asoc->stream; 60 61 list_for_each_entry(lchunk, &chunk->msg->chunks, frag_list) { 62 struct sctp_idatahdr *hdr; 63 __u32 mid; 64 65 lchunk->has_mid = 1; 66 67 hdr = lchunk->subh.idata_hdr; 68 69 if (lchunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) 70 hdr->ppid = lchunk->sinfo.sinfo_ppid; 71 else 72 hdr->fsn = htonl(cfsn++); 73 74 if (lchunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { 75 mid = lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG ? 76 sctp_mid_uo_next(stream, out, sid) : 77 sctp_mid_uo_peek(stream, out, sid); 78 } else { 79 mid = lchunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG ? 80 sctp_mid_next(stream, out, sid) : 81 sctp_mid_peek(stream, out, sid); 82 } 83 hdr->mid = htonl(mid); 84 } 85 } 86 87 static bool sctp_validate_data(struct sctp_chunk *chunk) 88 { 89 struct sctp_stream *stream; 90 __u16 sid, ssn; 91 92 if (chunk->chunk_hdr->type != SCTP_CID_DATA) 93 return false; 94 95 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 96 return true; 97 98 stream = &chunk->asoc->stream; 99 sid = sctp_chunk_stream_no(chunk); 100 ssn = ntohs(chunk->subh.data_hdr->ssn); 101 102 return !SSN_lt(ssn, sctp_ssn_peek(stream, in, sid)); 103 } 104 105 static bool sctp_validate_idata(struct sctp_chunk *chunk) 106 { 107 struct sctp_stream *stream; 108 __u32 mid; 109 __u16 sid; 110 111 if (chunk->chunk_hdr->type != SCTP_CID_I_DATA) 112 return false; 113 114 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 115 return true; 116 117 stream = &chunk->asoc->stream; 118 sid = sctp_chunk_stream_no(chunk); 119 mid = ntohl(chunk->subh.idata_hdr->mid); 120 121 return !MID_lt(mid, sctp_mid_peek(stream, in, sid)); 122 } 123 124 static void sctp_intl_store_reasm(struct sctp_ulpq *ulpq, 125 struct sctp_ulpevent *event) 126 { 127 struct sctp_ulpevent *cevent; 128 struct sk_buff *pos, *loc; 129 130 pos = skb_peek_tail(&ulpq->reasm); 131 if (!pos) { 132 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); 133 return; 134 } 135 136 cevent = sctp_skb2event(pos); 137 138 if (event->stream == cevent->stream && 139 event->mid == cevent->mid && 140 (cevent->msg_flags & SCTP_DATA_FIRST_FRAG || 141 (!(event->msg_flags & SCTP_DATA_FIRST_FRAG) && 142 event->fsn > cevent->fsn))) { 143 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); 144 return; 145 } 146 147 if ((event->stream == cevent->stream && 148 MID_lt(cevent->mid, event->mid)) || 149 event->stream > cevent->stream) { 150 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); 151 return; 152 } 153 154 loc = NULL; 155 skb_queue_walk(&ulpq->reasm, pos) { 156 cevent = sctp_skb2event(pos); 157 158 if (event->stream < cevent->stream || 159 (event->stream == cevent->stream && 160 MID_lt(event->mid, cevent->mid))) { 161 loc = pos; 162 break; 163 } 164 if (event->stream == cevent->stream && 165 event->mid == cevent->mid && 166 !(cevent->msg_flags & SCTP_DATA_FIRST_FRAG) && 167 (event->msg_flags & SCTP_DATA_FIRST_FRAG || 168 event->fsn < cevent->fsn)) { 169 loc = pos; 170 break; 171 } 172 } 173 174 if (!loc) 175 __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); 176 else 177 __skb_queue_before(&ulpq->reasm, loc, sctp_event2skb(event)); 178 } 179 180 static struct sctp_ulpevent *sctp_intl_retrieve_partial( 181 struct sctp_ulpq *ulpq, 182 struct sctp_ulpevent *event) 183 { 184 struct sk_buff *first_frag = NULL; 185 struct sk_buff *last_frag = NULL; 186 struct sctp_ulpevent *retval; 187 struct sctp_stream_in *sin; 188 struct sk_buff *pos; 189 __u32 next_fsn = 0; 190 int is_last = 0; 191 192 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 193 194 skb_queue_walk(&ulpq->reasm, pos) { 195 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 196 197 if (cevent->stream < event->stream) 198 continue; 199 200 if (cevent->stream > event->stream || 201 cevent->mid != sin->mid) 202 break; 203 204 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 205 case SCTP_DATA_FIRST_FRAG: 206 goto out; 207 case SCTP_DATA_MIDDLE_FRAG: 208 if (!first_frag) { 209 if (cevent->fsn == sin->fsn) { 210 first_frag = pos; 211 last_frag = pos; 212 next_fsn = cevent->fsn + 1; 213 } 214 } else if (cevent->fsn == next_fsn) { 215 last_frag = pos; 216 next_fsn++; 217 } else { 218 goto out; 219 } 220 break; 221 case SCTP_DATA_LAST_FRAG: 222 if (!first_frag) { 223 if (cevent->fsn == sin->fsn) { 224 first_frag = pos; 225 last_frag = pos; 226 next_fsn = 0; 227 is_last = 1; 228 } 229 } else if (cevent->fsn == next_fsn) { 230 last_frag = pos; 231 next_fsn = 0; 232 is_last = 1; 233 } 234 goto out; 235 default: 236 goto out; 237 } 238 } 239 240 out: 241 if (!first_frag) 242 return NULL; 243 244 retval = sctp_make_reassembled_event(ulpq->asoc->base.net, &ulpq->reasm, 245 first_frag, last_frag); 246 if (retval) { 247 sin->fsn = next_fsn; 248 if (is_last) { 249 retval->msg_flags |= MSG_EOR; 250 sin->pd_mode = 0; 251 } 252 } 253 254 return retval; 255 } 256 257 static struct sctp_ulpevent *sctp_intl_retrieve_reassembled( 258 struct sctp_ulpq *ulpq, 259 struct sctp_ulpevent *event) 260 { 261 struct sctp_association *asoc = ulpq->asoc; 262 struct sk_buff *pos, *first_frag = NULL; 263 struct sctp_ulpevent *retval = NULL; 264 struct sk_buff *pd_first = NULL; 265 struct sk_buff *pd_last = NULL; 266 struct sctp_stream_in *sin; 267 __u32 next_fsn = 0; 268 __u32 pd_point = 0; 269 __u32 pd_len = 0; 270 __u32 mid = 0; 271 272 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 273 274 skb_queue_walk(&ulpq->reasm, pos) { 275 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 276 277 if (cevent->stream < event->stream) 278 continue; 279 if (cevent->stream > event->stream) 280 break; 281 282 if (MID_lt(cevent->mid, event->mid)) 283 continue; 284 if (MID_lt(event->mid, cevent->mid)) 285 break; 286 287 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 288 case SCTP_DATA_FIRST_FRAG: 289 if (cevent->mid == sin->mid) { 290 pd_first = pos; 291 pd_last = pos; 292 pd_len = pos->len; 293 } 294 295 first_frag = pos; 296 next_fsn = 0; 297 mid = cevent->mid; 298 break; 299 300 case SCTP_DATA_MIDDLE_FRAG: 301 if (first_frag && cevent->mid == mid && 302 cevent->fsn == next_fsn) { 303 next_fsn++; 304 if (pd_first) { 305 pd_last = pos; 306 pd_len += pos->len; 307 } 308 } else { 309 first_frag = NULL; 310 } 311 break; 312 313 case SCTP_DATA_LAST_FRAG: 314 if (first_frag && cevent->mid == mid && 315 cevent->fsn == next_fsn) 316 goto found; 317 else 318 first_frag = NULL; 319 break; 320 } 321 } 322 323 if (!pd_first) 324 goto out; 325 326 pd_point = sctp_sk(asoc->base.sk)->pd_point; 327 if (pd_point && pd_point <= pd_len) { 328 retval = sctp_make_reassembled_event(asoc->base.net, 329 &ulpq->reasm, 330 pd_first, pd_last); 331 if (retval) { 332 sin->fsn = next_fsn; 333 sin->pd_mode = 1; 334 } 335 } 336 goto out; 337 338 found: 339 retval = sctp_make_reassembled_event(asoc->base.net, &ulpq->reasm, 340 first_frag, pos); 341 if (retval) 342 retval->msg_flags |= MSG_EOR; 343 344 out: 345 return retval; 346 } 347 348 static struct sctp_ulpevent *sctp_intl_reasm(struct sctp_ulpq *ulpq, 349 struct sctp_ulpevent *event) 350 { 351 struct sctp_ulpevent *retval = NULL; 352 struct sctp_stream_in *sin; 353 354 if (SCTP_DATA_NOT_FRAG == (event->msg_flags & SCTP_DATA_FRAG_MASK)) { 355 event->msg_flags |= MSG_EOR; 356 return event; 357 } 358 359 sctp_intl_store_reasm(ulpq, event); 360 361 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 362 if (sin->pd_mode && event->mid == sin->mid && 363 event->fsn == sin->fsn) 364 retval = sctp_intl_retrieve_partial(ulpq, event); 365 366 if (!retval) 367 retval = sctp_intl_retrieve_reassembled(ulpq, event); 368 369 return retval; 370 } 371 372 static void sctp_intl_store_ordered(struct sctp_ulpq *ulpq, 373 struct sctp_ulpevent *event) 374 { 375 struct sctp_ulpevent *cevent; 376 struct sk_buff *pos, *loc; 377 378 pos = skb_peek_tail(&ulpq->lobby); 379 if (!pos) { 380 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); 381 return; 382 } 383 384 cevent = (struct sctp_ulpevent *)pos->cb; 385 if (event->stream == cevent->stream && 386 MID_lt(cevent->mid, event->mid)) { 387 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); 388 return; 389 } 390 391 if (event->stream > cevent->stream) { 392 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); 393 return; 394 } 395 396 loc = NULL; 397 skb_queue_walk(&ulpq->lobby, pos) { 398 cevent = (struct sctp_ulpevent *)pos->cb; 399 400 if (cevent->stream > event->stream) { 401 loc = pos; 402 break; 403 } 404 if (cevent->stream == event->stream && 405 MID_lt(event->mid, cevent->mid)) { 406 loc = pos; 407 break; 408 } 409 } 410 411 if (!loc) 412 __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); 413 else 414 __skb_queue_before(&ulpq->lobby, loc, sctp_event2skb(event)); 415 } 416 417 static void sctp_intl_retrieve_ordered(struct sctp_ulpq *ulpq, 418 struct sctp_ulpevent *event) 419 { 420 struct sk_buff_head *event_list; 421 struct sctp_stream *stream; 422 struct sk_buff *pos, *tmp; 423 __u16 sid = event->stream; 424 425 stream = &ulpq->asoc->stream; 426 event_list = (struct sk_buff_head *)sctp_event2skb(event)->prev; 427 428 sctp_skb_for_each(pos, &ulpq->lobby, tmp) { 429 struct sctp_ulpevent *cevent = (struct sctp_ulpevent *)pos->cb; 430 431 if (cevent->stream > sid) 432 break; 433 434 if (cevent->stream < sid) 435 continue; 436 437 if (cevent->mid != sctp_mid_peek(stream, in, sid)) 438 break; 439 440 sctp_mid_next(stream, in, sid); 441 442 __skb_unlink(pos, &ulpq->lobby); 443 444 __skb_queue_tail(event_list, pos); 445 } 446 } 447 448 static struct sctp_ulpevent *sctp_intl_order(struct sctp_ulpq *ulpq, 449 struct sctp_ulpevent *event) 450 { 451 struct sctp_stream *stream; 452 __u16 sid; 453 454 stream = &ulpq->asoc->stream; 455 sid = event->stream; 456 457 if (event->mid != sctp_mid_peek(stream, in, sid)) { 458 sctp_intl_store_ordered(ulpq, event); 459 return NULL; 460 } 461 462 sctp_mid_next(stream, in, sid); 463 464 sctp_intl_retrieve_ordered(ulpq, event); 465 466 return event; 467 } 468 469 static int sctp_enqueue_event(struct sctp_ulpq *ulpq, 470 struct sk_buff_head *skb_list) 471 { 472 struct sock *sk = ulpq->asoc->base.sk; 473 struct sctp_sock *sp = sctp_sk(sk); 474 struct sctp_ulpevent *event; 475 struct sk_buff *skb; 476 477 skb = __skb_peek(skb_list); 478 event = sctp_skb2event(skb); 479 480 if (sk->sk_shutdown & RCV_SHUTDOWN && 481 (sk->sk_shutdown & SEND_SHUTDOWN || 482 !sctp_ulpevent_is_notification(event))) 483 goto out_free; 484 485 if (!sctp_ulpevent_is_notification(event)) { 486 sk_mark_napi_id(sk, skb); 487 sk_incoming_cpu_update(sk); 488 } 489 490 if (!sctp_ulpevent_is_enabled(event, ulpq->asoc->subscribe)) 491 goto out_free; 492 493 if (skb_list) 494 skb_queue_splice_tail_init(skb_list, 495 &sk->sk_receive_queue); 496 else 497 __skb_queue_tail(&sk->sk_receive_queue, skb); 498 499 if (!sp->data_ready_signalled) { 500 sp->data_ready_signalled = 1; 501 sk->sk_data_ready(sk); 502 } 503 504 return 1; 505 506 out_free: 507 if (skb_list) 508 sctp_queue_purge_ulpevents(skb_list); 509 else 510 sctp_ulpevent_free(event); 511 512 return 0; 513 } 514 515 static void sctp_intl_store_reasm_uo(struct sctp_ulpq *ulpq, 516 struct sctp_ulpevent *event) 517 { 518 struct sctp_ulpevent *cevent; 519 struct sk_buff *pos; 520 521 pos = skb_peek_tail(&ulpq->reasm_uo); 522 if (!pos) { 523 __skb_queue_tail(&ulpq->reasm_uo, sctp_event2skb(event)); 524 return; 525 } 526 527 cevent = sctp_skb2event(pos); 528 529 if (event->stream == cevent->stream && 530 event->mid == cevent->mid && 531 (cevent->msg_flags & SCTP_DATA_FIRST_FRAG || 532 (!(event->msg_flags & SCTP_DATA_FIRST_FRAG) && 533 event->fsn > cevent->fsn))) { 534 __skb_queue_tail(&ulpq->reasm_uo, sctp_event2skb(event)); 535 return; 536 } 537 538 if ((event->stream == cevent->stream && 539 MID_lt(cevent->mid, event->mid)) || 540 event->stream > cevent->stream) { 541 __skb_queue_tail(&ulpq->reasm_uo, sctp_event2skb(event)); 542 return; 543 } 544 545 skb_queue_walk(&ulpq->reasm_uo, pos) { 546 cevent = sctp_skb2event(pos); 547 548 if (event->stream < cevent->stream || 549 (event->stream == cevent->stream && 550 MID_lt(event->mid, cevent->mid))) 551 break; 552 553 if (event->stream == cevent->stream && 554 event->mid == cevent->mid && 555 !(cevent->msg_flags & SCTP_DATA_FIRST_FRAG) && 556 (event->msg_flags & SCTP_DATA_FIRST_FRAG || 557 event->fsn < cevent->fsn)) 558 break; 559 } 560 561 __skb_queue_before(&ulpq->reasm_uo, pos, sctp_event2skb(event)); 562 } 563 564 static struct sctp_ulpevent *sctp_intl_retrieve_partial_uo( 565 struct sctp_ulpq *ulpq, 566 struct sctp_ulpevent *event) 567 { 568 struct sk_buff *first_frag = NULL; 569 struct sk_buff *last_frag = NULL; 570 struct sctp_ulpevent *retval; 571 struct sctp_stream_in *sin; 572 struct sk_buff *pos; 573 __u32 next_fsn = 0; 574 int is_last = 0; 575 576 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 577 578 skb_queue_walk(&ulpq->reasm_uo, pos) { 579 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 580 581 if (cevent->stream < event->stream) 582 continue; 583 if (cevent->stream > event->stream) 584 break; 585 586 if (MID_lt(cevent->mid, sin->mid_uo)) 587 continue; 588 if (MID_lt(sin->mid_uo, cevent->mid)) 589 break; 590 591 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 592 case SCTP_DATA_FIRST_FRAG: 593 goto out; 594 case SCTP_DATA_MIDDLE_FRAG: 595 if (!first_frag) { 596 if (cevent->fsn == sin->fsn_uo) { 597 first_frag = pos; 598 last_frag = pos; 599 next_fsn = cevent->fsn + 1; 600 } 601 } else if (cevent->fsn == next_fsn) { 602 last_frag = pos; 603 next_fsn++; 604 } else { 605 goto out; 606 } 607 break; 608 case SCTP_DATA_LAST_FRAG: 609 if (!first_frag) { 610 if (cevent->fsn == sin->fsn_uo) { 611 first_frag = pos; 612 last_frag = pos; 613 next_fsn = 0; 614 is_last = 1; 615 } 616 } else if (cevent->fsn == next_fsn) { 617 last_frag = pos; 618 next_fsn = 0; 619 is_last = 1; 620 } 621 goto out; 622 default: 623 goto out; 624 } 625 } 626 627 out: 628 if (!first_frag) 629 return NULL; 630 631 retval = sctp_make_reassembled_event(ulpq->asoc->base.net, 632 &ulpq->reasm_uo, first_frag, 633 last_frag); 634 if (retval) { 635 sin->fsn_uo = next_fsn; 636 if (is_last) { 637 retval->msg_flags |= MSG_EOR; 638 sin->pd_mode_uo = 0; 639 } 640 } 641 642 return retval; 643 } 644 645 static struct sctp_ulpevent *sctp_intl_retrieve_reassembled_uo( 646 struct sctp_ulpq *ulpq, 647 struct sctp_ulpevent *event) 648 { 649 struct sctp_association *asoc = ulpq->asoc; 650 struct sk_buff *pos, *first_frag = NULL; 651 struct sctp_ulpevent *retval = NULL; 652 struct sk_buff *pd_first = NULL; 653 struct sk_buff *pd_last = NULL; 654 struct sctp_stream_in *sin; 655 __u32 next_fsn = 0; 656 __u32 pd_point = 0; 657 __u32 pd_len = 0; 658 __u32 mid = 0; 659 660 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 661 662 skb_queue_walk(&ulpq->reasm_uo, pos) { 663 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 664 665 if (cevent->stream < event->stream) 666 continue; 667 if (cevent->stream > event->stream) 668 break; 669 670 if (MID_lt(cevent->mid, event->mid)) 671 continue; 672 if (MID_lt(event->mid, cevent->mid)) 673 break; 674 675 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 676 case SCTP_DATA_FIRST_FRAG: 677 if (!sin->pd_mode_uo) { 678 sin->mid_uo = cevent->mid; 679 pd_first = pos; 680 pd_last = pos; 681 pd_len = pos->len; 682 } 683 684 first_frag = pos; 685 next_fsn = 0; 686 mid = cevent->mid; 687 break; 688 689 case SCTP_DATA_MIDDLE_FRAG: 690 if (first_frag && cevent->mid == mid && 691 cevent->fsn == next_fsn) { 692 next_fsn++; 693 if (pd_first) { 694 pd_last = pos; 695 pd_len += pos->len; 696 } 697 } else { 698 first_frag = NULL; 699 } 700 break; 701 702 case SCTP_DATA_LAST_FRAG: 703 if (first_frag && cevent->mid == mid && 704 cevent->fsn == next_fsn) 705 goto found; 706 else 707 first_frag = NULL; 708 break; 709 } 710 } 711 712 if (!pd_first) 713 goto out; 714 715 pd_point = sctp_sk(asoc->base.sk)->pd_point; 716 if (pd_point && pd_point <= pd_len) { 717 retval = sctp_make_reassembled_event(asoc->base.net, 718 &ulpq->reasm_uo, 719 pd_first, pd_last); 720 if (retval) { 721 sin->fsn_uo = next_fsn; 722 sin->pd_mode_uo = 1; 723 } 724 } 725 goto out; 726 727 found: 728 retval = sctp_make_reassembled_event(asoc->base.net, &ulpq->reasm_uo, 729 first_frag, pos); 730 if (retval) 731 retval->msg_flags |= MSG_EOR; 732 733 out: 734 return retval; 735 } 736 737 static struct sctp_ulpevent *sctp_intl_reasm_uo(struct sctp_ulpq *ulpq, 738 struct sctp_ulpevent *event) 739 { 740 struct sctp_ulpevent *retval = NULL; 741 struct sctp_stream_in *sin; 742 743 if (SCTP_DATA_NOT_FRAG == (event->msg_flags & SCTP_DATA_FRAG_MASK)) { 744 event->msg_flags |= MSG_EOR; 745 return event; 746 } 747 748 sctp_intl_store_reasm_uo(ulpq, event); 749 750 sin = sctp_stream_in(&ulpq->asoc->stream, event->stream); 751 if (sin->pd_mode_uo && event->mid == sin->mid_uo && 752 event->fsn == sin->fsn_uo) 753 retval = sctp_intl_retrieve_partial_uo(ulpq, event); 754 755 if (!retval) 756 retval = sctp_intl_retrieve_reassembled_uo(ulpq, event); 757 758 return retval; 759 } 760 761 static struct sctp_ulpevent *sctp_intl_retrieve_first_uo(struct sctp_ulpq *ulpq) 762 { 763 struct sctp_stream_in *csin, *sin = NULL; 764 struct sk_buff *first_frag = NULL; 765 struct sk_buff *last_frag = NULL; 766 struct sctp_ulpevent *retval; 767 struct sk_buff *pos; 768 __u32 next_fsn = 0; 769 __u16 sid = 0; 770 771 skb_queue_walk(&ulpq->reasm_uo, pos) { 772 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 773 774 csin = sctp_stream_in(&ulpq->asoc->stream, cevent->stream); 775 if (csin->pd_mode_uo) 776 continue; 777 778 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 779 case SCTP_DATA_FIRST_FRAG: 780 if (first_frag) 781 goto out; 782 first_frag = pos; 783 last_frag = pos; 784 next_fsn = 0; 785 sin = csin; 786 sid = cevent->stream; 787 sin->mid_uo = cevent->mid; 788 break; 789 case SCTP_DATA_MIDDLE_FRAG: 790 if (!first_frag) 791 break; 792 if (cevent->stream == sid && 793 cevent->mid == sin->mid_uo && 794 cevent->fsn == next_fsn) { 795 next_fsn++; 796 last_frag = pos; 797 } else { 798 goto out; 799 } 800 break; 801 case SCTP_DATA_LAST_FRAG: 802 if (first_frag) 803 goto out; 804 break; 805 default: 806 break; 807 } 808 } 809 810 if (!first_frag) 811 return NULL; 812 813 out: 814 retval = sctp_make_reassembled_event(ulpq->asoc->base.net, 815 &ulpq->reasm_uo, first_frag, 816 last_frag); 817 if (retval) { 818 sin->fsn_uo = next_fsn; 819 sin->pd_mode_uo = 1; 820 } 821 822 return retval; 823 } 824 825 static int sctp_ulpevent_idata(struct sctp_ulpq *ulpq, 826 struct sctp_chunk *chunk, gfp_t gfp) 827 { 828 struct sctp_ulpevent *event; 829 struct sk_buff_head temp; 830 int event_eor = 0; 831 832 event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp); 833 if (!event) 834 return -ENOMEM; 835 836 event->mid = ntohl(chunk->subh.idata_hdr->mid); 837 if (event->msg_flags & SCTP_DATA_FIRST_FRAG) 838 event->ppid = chunk->subh.idata_hdr->ppid; 839 else 840 event->fsn = ntohl(chunk->subh.idata_hdr->fsn); 841 842 if (!(event->msg_flags & SCTP_DATA_UNORDERED)) { 843 event = sctp_intl_reasm(ulpq, event); 844 if (event) { 845 skb_queue_head_init(&temp); 846 __skb_queue_tail(&temp, sctp_event2skb(event)); 847 848 if (event->msg_flags & MSG_EOR) 849 event = sctp_intl_order(ulpq, event); 850 } 851 } else { 852 event = sctp_intl_reasm_uo(ulpq, event); 853 if (event) { 854 skb_queue_head_init(&temp); 855 __skb_queue_tail(&temp, sctp_event2skb(event)); 856 } 857 } 858 859 if (event) { 860 event_eor = (event->msg_flags & MSG_EOR) ? 1 : 0; 861 sctp_enqueue_event(ulpq, &temp); 862 } 863 864 return event_eor; 865 } 866 867 static struct sctp_ulpevent *sctp_intl_retrieve_first(struct sctp_ulpq *ulpq) 868 { 869 struct sctp_stream_in *csin, *sin = NULL; 870 struct sk_buff *first_frag = NULL; 871 struct sk_buff *last_frag = NULL; 872 struct sctp_ulpevent *retval; 873 struct sk_buff *pos; 874 __u32 next_fsn = 0; 875 __u16 sid = 0; 876 877 skb_queue_walk(&ulpq->reasm, pos) { 878 struct sctp_ulpevent *cevent = sctp_skb2event(pos); 879 880 csin = sctp_stream_in(&ulpq->asoc->stream, cevent->stream); 881 if (csin->pd_mode) 882 continue; 883 884 switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { 885 case SCTP_DATA_FIRST_FRAG: 886 if (first_frag) 887 goto out; 888 if (cevent->mid == csin->mid) { 889 first_frag = pos; 890 last_frag = pos; 891 next_fsn = 0; 892 sin = csin; 893 sid = cevent->stream; 894 } 895 break; 896 case SCTP_DATA_MIDDLE_FRAG: 897 if (!first_frag) 898 break; 899 if (cevent->stream == sid && 900 cevent->mid == sin->mid && 901 cevent->fsn == next_fsn) { 902 next_fsn++; 903 last_frag = pos; 904 } else { 905 goto out; 906 } 907 break; 908 case SCTP_DATA_LAST_FRAG: 909 if (first_frag) 910 goto out; 911 break; 912 default: 913 break; 914 } 915 } 916 917 if (!first_frag) 918 return NULL; 919 920 out: 921 retval = sctp_make_reassembled_event(ulpq->asoc->base.net, 922 &ulpq->reasm, first_frag, 923 last_frag); 924 if (retval) { 925 sin->fsn = next_fsn; 926 sin->pd_mode = 1; 927 } 928 929 return retval; 930 } 931 932 static void sctp_intl_start_pd(struct sctp_ulpq *ulpq, gfp_t gfp) 933 { 934 struct sctp_ulpevent *event; 935 struct sk_buff_head temp; 936 937 if (!skb_queue_empty(&ulpq->reasm)) { 938 do { 939 event = sctp_intl_retrieve_first(ulpq); 940 if (event) { 941 skb_queue_head_init(&temp); 942 __skb_queue_tail(&temp, sctp_event2skb(event)); 943 sctp_enqueue_event(ulpq, &temp); 944 } 945 } while (event); 946 } 947 948 if (!skb_queue_empty(&ulpq->reasm_uo)) { 949 do { 950 event = sctp_intl_retrieve_first_uo(ulpq); 951 if (event) { 952 skb_queue_head_init(&temp); 953 __skb_queue_tail(&temp, sctp_event2skb(event)); 954 sctp_enqueue_event(ulpq, &temp); 955 } 956 } while (event); 957 } 958 } 959 960 static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, 961 gfp_t gfp) 962 { 963 struct sctp_association *asoc = ulpq->asoc; 964 __u32 freed = 0; 965 __u16 needed; 966 967 needed = ntohs(chunk->chunk_hdr->length) - 968 sizeof(struct sctp_idata_chunk); 969 970 if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { 971 freed = sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed); 972 if (freed < needed) 973 freed += sctp_ulpq_renege_list(ulpq, &ulpq->reasm, 974 needed); 975 if (freed < needed) 976 freed += sctp_ulpq_renege_list(ulpq, &ulpq->reasm_uo, 977 needed); 978 } 979 980 if (freed >= needed && sctp_ulpevent_idata(ulpq, chunk, gfp) <= 0) 981 sctp_intl_start_pd(ulpq, gfp); 982 } 983 984 static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid, 985 __u32 mid, __u16 flags, gfp_t gfp) 986 { 987 struct sock *sk = ulpq->asoc->base.sk; 988 struct sctp_ulpevent *ev = NULL; 989 990 if (!sctp_ulpevent_type_enabled(ulpq->asoc->subscribe, 991 SCTP_PARTIAL_DELIVERY_EVENT)) 992 return; 993 994 ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED, 995 sid, mid, flags, gfp); 996 if (ev) { 997 struct sctp_sock *sp = sctp_sk(sk); 998 999 __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev)); 1000 1001 if (!sp->data_ready_signalled) { 1002 sp->data_ready_signalled = 1; 1003 sk->sk_data_ready(sk); 1004 } 1005 } 1006 } 1007 1008 static void sctp_intl_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid) 1009 { 1010 struct sctp_stream *stream = &ulpq->asoc->stream; 1011 struct sctp_ulpevent *cevent, *event = NULL; 1012 struct sk_buff_head *lobby = &ulpq->lobby; 1013 struct sk_buff *pos, *tmp; 1014 struct sk_buff_head temp; 1015 __u16 csid; 1016 __u32 cmid; 1017 1018 skb_queue_head_init(&temp); 1019 sctp_skb_for_each(pos, lobby, tmp) { 1020 cevent = (struct sctp_ulpevent *)pos->cb; 1021 csid = cevent->stream; 1022 cmid = cevent->mid; 1023 1024 if (csid > sid) 1025 break; 1026 1027 if (csid < sid) 1028 continue; 1029 1030 if (!MID_lt(cmid, sctp_mid_peek(stream, in, csid))) 1031 break; 1032 1033 __skb_unlink(pos, lobby); 1034 if (!event) 1035 event = sctp_skb2event(pos); 1036 1037 __skb_queue_tail(&temp, pos); 1038 } 1039 1040 if (!event && pos != (struct sk_buff *)lobby) { 1041 cevent = (struct sctp_ulpevent *)pos->cb; 1042 csid = cevent->stream; 1043 cmid = cevent->mid; 1044 1045 if (csid == sid && cmid == sctp_mid_peek(stream, in, csid)) { 1046 sctp_mid_next(stream, in, csid); 1047 __skb_unlink(pos, lobby); 1048 __skb_queue_tail(&temp, pos); 1049 event = sctp_skb2event(pos); 1050 } 1051 } 1052 1053 if (event) { 1054 sctp_intl_retrieve_ordered(ulpq, event); 1055 sctp_enqueue_event(ulpq, &temp); 1056 } 1057 } 1058 1059 static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp) 1060 { 1061 struct sctp_stream *stream = &ulpq->asoc->stream; 1062 __u16 sid; 1063 1064 for (sid = 0; sid < stream->incnt; sid++) { 1065 struct sctp_stream_in *sin = SCTP_SI(stream, sid); 1066 __u32 mid; 1067 1068 if (sin->pd_mode_uo) { 1069 sin->pd_mode_uo = 0; 1070 1071 mid = sin->mid_uo; 1072 sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x1, gfp); 1073 } 1074 1075 if (sin->pd_mode) { 1076 sin->pd_mode = 0; 1077 1078 mid = sin->mid; 1079 sctp_intl_stream_abort_pd(ulpq, sid, mid, 0, gfp); 1080 sctp_mid_skip(stream, in, sid, mid); 1081 1082 sctp_intl_reap_ordered(ulpq, sid); 1083 } 1084 } 1085 1086 /* intl abort pd happens only when all data needs to be cleaned */ 1087 sctp_ulpq_flush(ulpq); 1088 } 1089 1090 static inline int sctp_get_skip_pos(struct sctp_ifwdtsn_skip *skiplist, 1091 int nskips, __be16 stream, __u8 flags) 1092 { 1093 int i; 1094 1095 for (i = 0; i < nskips; i++) 1096 if (skiplist[i].stream == stream && 1097 skiplist[i].flags == flags) 1098 return i; 1099 1100 return i; 1101 } 1102 1103 #define SCTP_FTSN_U_BIT 0x1 1104 static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn) 1105 { 1106 struct sctp_ifwdtsn_skip ftsn_skip_arr[10]; 1107 struct sctp_association *asoc = q->asoc; 1108 struct sctp_chunk *ftsn_chunk = NULL; 1109 struct list_head *lchunk, *temp; 1110 int nskips = 0, skip_pos; 1111 struct sctp_chunk *chunk; 1112 __u32 tsn; 1113 1114 if (!asoc->peer.prsctp_capable) 1115 return; 1116 1117 if (TSN_lt(asoc->adv_peer_ack_point, ctsn)) 1118 asoc->adv_peer_ack_point = ctsn; 1119 1120 list_for_each_safe(lchunk, temp, &q->abandoned) { 1121 chunk = list_entry(lchunk, struct sctp_chunk, transmitted_list); 1122 tsn = ntohl(chunk->subh.data_hdr->tsn); 1123 1124 if (TSN_lte(tsn, ctsn)) { 1125 list_del_init(lchunk); 1126 sctp_chunk_free(chunk); 1127 } else if (TSN_lte(tsn, asoc->adv_peer_ack_point + 1)) { 1128 __be16 sid = chunk->subh.idata_hdr->stream; 1129 __be32 mid = chunk->subh.idata_hdr->mid; 1130 __u8 flags = 0; 1131 1132 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) 1133 flags |= SCTP_FTSN_U_BIT; 1134 1135 asoc->adv_peer_ack_point = tsn; 1136 skip_pos = sctp_get_skip_pos(&ftsn_skip_arr[0], nskips, 1137 sid, flags); 1138 ftsn_skip_arr[skip_pos].stream = sid; 1139 ftsn_skip_arr[skip_pos].reserved = 0; 1140 ftsn_skip_arr[skip_pos].flags = flags; 1141 ftsn_skip_arr[skip_pos].mid = mid; 1142 if (skip_pos == nskips) 1143 nskips++; 1144 if (nskips == 10) 1145 break; 1146 } else { 1147 break; 1148 } 1149 } 1150 1151 if (asoc->adv_peer_ack_point > ctsn) 1152 ftsn_chunk = sctp_make_ifwdtsn(asoc, asoc->adv_peer_ack_point, 1153 nskips, &ftsn_skip_arr[0]); 1154 1155 if (ftsn_chunk) { 1156 list_add_tail(&ftsn_chunk->list, &q->control_chunk_list); 1157 SCTP_INC_STATS(asoc->base.net, SCTP_MIB_OUTCTRLCHUNKS); 1158 } 1159 } 1160 1161 #define _sctp_walk_ifwdtsn(pos, chunk, end) \ 1162 for (pos = chunk->subh.ifwdtsn_hdr->skip; \ 1163 (void *)pos < (void *)chunk->subh.ifwdtsn_hdr->skip + (end); pos++) 1164 1165 #define sctp_walk_ifwdtsn(pos, ch) \ 1166 _sctp_walk_ifwdtsn((pos), (ch), ntohs((ch)->chunk_hdr->length) - \ 1167 sizeof(struct sctp_ifwdtsn_chunk)) 1168 1169 static bool sctp_validate_fwdtsn(struct sctp_chunk *chunk) 1170 { 1171 struct sctp_fwdtsn_skip *skip; 1172 __u16 incnt; 1173 1174 if (chunk->chunk_hdr->type != SCTP_CID_FWD_TSN) 1175 return false; 1176 1177 incnt = chunk->asoc->stream.incnt; 1178 sctp_walk_fwdtsn(skip, chunk) 1179 if (ntohs(skip->stream) >= incnt) 1180 return false; 1181 1182 return true; 1183 } 1184 1185 static bool sctp_validate_iftsn(struct sctp_chunk *chunk) 1186 { 1187 struct sctp_ifwdtsn_skip *skip; 1188 __u16 incnt; 1189 1190 if (chunk->chunk_hdr->type != SCTP_CID_I_FWD_TSN) 1191 return false; 1192 1193 incnt = chunk->asoc->stream.incnt; 1194 sctp_walk_ifwdtsn(skip, chunk) 1195 if (ntohs(skip->stream) >= incnt) 1196 return false; 1197 1198 return true; 1199 } 1200 1201 static void sctp_report_fwdtsn(struct sctp_ulpq *ulpq, __u32 ftsn) 1202 { 1203 /* Move the Cumulattive TSN Ack ahead. */ 1204 sctp_tsnmap_skip(&ulpq->asoc->peer.tsn_map, ftsn); 1205 /* purge the fragmentation queue */ 1206 sctp_ulpq_reasm_flushtsn(ulpq, ftsn); 1207 /* Abort any in progress partial delivery. */ 1208 sctp_ulpq_abort_pd(ulpq, GFP_ATOMIC); 1209 } 1210 1211 static void sctp_intl_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 ftsn) 1212 { 1213 struct sk_buff *pos, *tmp; 1214 1215 skb_queue_walk_safe(&ulpq->reasm, pos, tmp) { 1216 struct sctp_ulpevent *event = sctp_skb2event(pos); 1217 __u32 tsn = event->tsn; 1218 1219 if (TSN_lte(tsn, ftsn)) { 1220 __skb_unlink(pos, &ulpq->reasm); 1221 sctp_ulpevent_free(event); 1222 } 1223 } 1224 1225 skb_queue_walk_safe(&ulpq->reasm_uo, pos, tmp) { 1226 struct sctp_ulpevent *event = sctp_skb2event(pos); 1227 __u32 tsn = event->tsn; 1228 1229 if (TSN_lte(tsn, ftsn)) { 1230 __skb_unlink(pos, &ulpq->reasm_uo); 1231 sctp_ulpevent_free(event); 1232 } 1233 } 1234 } 1235 1236 static void sctp_report_iftsn(struct sctp_ulpq *ulpq, __u32 ftsn) 1237 { 1238 /* Move the Cumulattive TSN Ack ahead. */ 1239 sctp_tsnmap_skip(&ulpq->asoc->peer.tsn_map, ftsn); 1240 /* purge the fragmentation queue */ 1241 sctp_intl_reasm_flushtsn(ulpq, ftsn); 1242 /* abort only when it's for all data */ 1243 if (ftsn == sctp_tsnmap_get_max_tsn_seen(&ulpq->asoc->peer.tsn_map)) 1244 sctp_intl_abort_pd(ulpq, GFP_ATOMIC); 1245 } 1246 1247 static void sctp_handle_fwdtsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk) 1248 { 1249 struct sctp_fwdtsn_skip *skip; 1250 1251 /* Walk through all the skipped SSNs */ 1252 sctp_walk_fwdtsn(skip, chunk) 1253 sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn)); 1254 } 1255 1256 static void sctp_intl_skip(struct sctp_ulpq *ulpq, __u16 sid, __u32 mid, 1257 __u8 flags) 1258 { 1259 struct sctp_stream_in *sin = sctp_stream_in(&ulpq->asoc->stream, sid); 1260 struct sctp_stream *stream = &ulpq->asoc->stream; 1261 1262 if (flags & SCTP_FTSN_U_BIT) { 1263 if (sin->pd_mode_uo && MID_lt(sin->mid_uo, mid)) { 1264 sin->pd_mode_uo = 0; 1265 sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x1, 1266 GFP_ATOMIC); 1267 } 1268 return; 1269 } 1270 1271 if (MID_lt(mid, sctp_mid_peek(stream, in, sid))) 1272 return; 1273 1274 if (sin->pd_mode) { 1275 sin->pd_mode = 0; 1276 sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x0, GFP_ATOMIC); 1277 } 1278 1279 sctp_mid_skip(stream, in, sid, mid); 1280 1281 sctp_intl_reap_ordered(ulpq, sid); 1282 } 1283 1284 static void sctp_handle_iftsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk) 1285 { 1286 struct sctp_ifwdtsn_skip *skip; 1287 1288 /* Walk through all the skipped MIDs and abort stream pd if possible */ 1289 sctp_walk_ifwdtsn(skip, chunk) 1290 sctp_intl_skip(ulpq, ntohs(skip->stream), 1291 ntohl(skip->mid), skip->flags); 1292 } 1293 1294 static int do_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event) 1295 { 1296 struct sk_buff_head temp; 1297 1298 skb_queue_head_init(&temp); 1299 __skb_queue_tail(&temp, sctp_event2skb(event)); 1300 return sctp_ulpq_tail_event(ulpq, &temp); 1301 } 1302 1303 static struct sctp_stream_interleave sctp_stream_interleave_0 = { 1304 .data_chunk_len = sizeof(struct sctp_data_chunk), 1305 .ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk), 1306 /* DATA process functions */ 1307 .make_datafrag = sctp_make_datafrag_empty, 1308 .assign_number = sctp_chunk_assign_ssn, 1309 .validate_data = sctp_validate_data, 1310 .ulpevent_data = sctp_ulpq_tail_data, 1311 .enqueue_event = do_ulpq_tail_event, 1312 .renege_events = sctp_ulpq_renege, 1313 .start_pd = sctp_ulpq_partial_delivery, 1314 .abort_pd = sctp_ulpq_abort_pd, 1315 /* FORWARD-TSN process functions */ 1316 .generate_ftsn = sctp_generate_fwdtsn, 1317 .validate_ftsn = sctp_validate_fwdtsn, 1318 .report_ftsn = sctp_report_fwdtsn, 1319 .handle_ftsn = sctp_handle_fwdtsn, 1320 }; 1321 1322 static int do_sctp_enqueue_event(struct sctp_ulpq *ulpq, 1323 struct sctp_ulpevent *event) 1324 { 1325 struct sk_buff_head temp; 1326 1327 skb_queue_head_init(&temp); 1328 __skb_queue_tail(&temp, sctp_event2skb(event)); 1329 return sctp_enqueue_event(ulpq, &temp); 1330 } 1331 1332 static struct sctp_stream_interleave sctp_stream_interleave_1 = { 1333 .data_chunk_len = sizeof(struct sctp_idata_chunk), 1334 .ftsn_chunk_len = sizeof(struct sctp_ifwdtsn_chunk), 1335 /* I-DATA process functions */ 1336 .make_datafrag = sctp_make_idatafrag_empty, 1337 .assign_number = sctp_chunk_assign_mid, 1338 .validate_data = sctp_validate_idata, 1339 .ulpevent_data = sctp_ulpevent_idata, 1340 .enqueue_event = do_sctp_enqueue_event, 1341 .renege_events = sctp_renege_events, 1342 .start_pd = sctp_intl_start_pd, 1343 .abort_pd = sctp_intl_abort_pd, 1344 /* I-FORWARD-TSN process functions */ 1345 .generate_ftsn = sctp_generate_iftsn, 1346 .validate_ftsn = sctp_validate_iftsn, 1347 .report_ftsn = sctp_report_iftsn, 1348 .handle_ftsn = sctp_handle_iftsn, 1349 }; 1350 1351 void sctp_stream_interleave_init(struct sctp_stream *stream) 1352 { 1353 struct sctp_association *asoc; 1354 1355 asoc = container_of(stream, struct sctp_association, stream); 1356 stream->si = asoc->peer.intl_capable ? &sctp_stream_interleave_1 1357 : &sctp_stream_interleave_0; 1358 } 1359