This is the same as the sctp_abort() could be made common */
| 464 | |
| 465 | /* This is the same as the sctp_abort() could be made common */ |
| 466 | static void |
| 467 | sctp6_abort(struct socket *so) |
| 468 | { |
| 469 | struct epoch_tracker et; |
| 470 | struct sctp_inpcb *inp; |
| 471 | uint32_t flags; |
| 472 | |
| 473 | inp = (struct sctp_inpcb *)so->so_pcb; |
| 474 | if (inp == NULL) { |
| 475 | SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); |
| 476 | return; |
| 477 | } |
| 478 | NET_EPOCH_ENTER(et); |
| 479 | sctp_must_try_again: |
| 480 | flags = inp->sctp_flags; |
| 481 | #ifdef SCTP_LOG_CLOSING |
| 482 | sctp_log_closing(inp, NULL, 17); |
| 483 | #endif |
| 484 | if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && |
| 485 | (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { |
| 486 | #ifdef SCTP_LOG_CLOSING |
| 487 | sctp_log_closing(inp, NULL, 16); |
| 488 | #endif |
| 489 | sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, |
| 490 | SCTP_CALLED_AFTER_CMPSET_OFCLOSE); |
| 491 | SOCK_LOCK(so); |
| 492 | SCTP_SB_CLEAR(so->so_snd); |
| 493 | /* |
| 494 | * same for the rcv ones, they are only here for the |
| 495 | * accounting/select. |
| 496 | */ |
| 497 | SCTP_SB_CLEAR(so->so_rcv); |
| 498 | /* Now null out the reference, we are completely detached. */ |
| 499 | so->so_pcb = NULL; |
| 500 | SOCK_UNLOCK(so); |
| 501 | } else { |
| 502 | flags = inp->sctp_flags; |
| 503 | if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { |
| 504 | goto sctp_must_try_again; |
| 505 | } |
| 506 | } |
| 507 | NET_EPOCH_EXIT(et); |
| 508 | return; |
| 509 | } |
| 510 | |
| 511 | static int |
| 512 | sctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED) |
nothing calls this directly
no test coverage detected