| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* SCTP kernel implementation |
|---|
| 2 | 3 | * (C) Copyright IBM Corp. 2001, 2004 |
|---|
| 3 | 4 | * Copyright (c) 1999-2000 Cisco, Inc. |
|---|
| .. | .. |
|---|
| 8 | 9 | * This file is part of the SCTP kernel implementation |
|---|
| 9 | 10 | * |
|---|
| 10 | 11 | * This module provides the abstraction for an SCTP association. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This SCTP implementation is free software; |
|---|
| 13 | | - * you can redistribute it and/or modify it under the terms of |
|---|
| 14 | | - * the GNU General Public License as published by |
|---|
| 15 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 16 | | - * any later version. |
|---|
| 17 | | - * |
|---|
| 18 | | - * This SCTP implementation is distributed in the hope that it |
|---|
| 19 | | - * will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|---|
| 20 | | - * ************************ |
|---|
| 21 | | - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 22 | | - * See the GNU General Public License for more details. |
|---|
| 23 | | - * |
|---|
| 24 | | - * You should have received a copy of the GNU General Public License |
|---|
| 25 | | - * along with GNU CC; see the file COPYING. If not, see |
|---|
| 26 | | - * <http://www.gnu.org/licenses/>. |
|---|
| 27 | 12 | * |
|---|
| 28 | 13 | * Please send any bug reports or fixes you make to the |
|---|
| 29 | 14 | * email address(es): |
|---|
| .. | .. |
|---|
| 69 | 54 | const struct sock *sk, |
|---|
| 70 | 55 | enum sctp_scope scope, gfp_t gfp) |
|---|
| 71 | 56 | { |
|---|
| 72 | | - struct net *net = sock_net(sk); |
|---|
| 73 | 57 | struct sctp_sock *sp; |
|---|
| 74 | 58 | struct sctp_paramhdr *p; |
|---|
| 75 | 59 | int i; |
|---|
| .. | .. |
|---|
| 102 | 86 | * socket values. |
|---|
| 103 | 87 | */ |
|---|
| 104 | 88 | asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt; |
|---|
| 105 | | - asoc->pf_retrans = net->sctp.pf_retrans; |
|---|
| 89 | + asoc->pf_retrans = sp->pf_retrans; |
|---|
| 90 | + asoc->ps_retrans = sp->ps_retrans; |
|---|
| 91 | + asoc->pf_expose = sp->pf_expose; |
|---|
| 106 | 92 | |
|---|
| 107 | 93 | asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial); |
|---|
| 108 | 94 | asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max); |
|---|
| .. | .. |
|---|
| 132 | 118 | * in a burst. |
|---|
| 133 | 119 | */ |
|---|
| 134 | 120 | asoc->max_burst = sp->max_burst; |
|---|
| 121 | + |
|---|
| 122 | + asoc->subscribe = sp->subscribe; |
|---|
| 135 | 123 | |
|---|
| 136 | 124 | /* initialize association timers */ |
|---|
| 137 | 125 | asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = asoc->rto_initial; |
|---|
| .. | .. |
|---|
| 228 | 216 | asoc->peer.sack_needed = 1; |
|---|
| 229 | 217 | asoc->peer.sack_generation = 1; |
|---|
| 230 | 218 | |
|---|
| 231 | | - /* Assume that the peer will tell us if he recognizes ASCONF |
|---|
| 232 | | - * as part of INIT exchange. |
|---|
| 233 | | - * The sctp_addip_noauth option is there for backward compatibility |
|---|
| 234 | | - * and will revert old behavior. |
|---|
| 235 | | - */ |
|---|
| 236 | | - if (net->sctp.addip_noauth) |
|---|
| 237 | | - asoc->peer.asconf_capable = 1; |
|---|
| 238 | | - |
|---|
| 239 | 219 | /* Create an input queue. */ |
|---|
| 240 | 220 | sctp_inq_init(&asoc->base.inqueue); |
|---|
| 241 | 221 | sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv); |
|---|
| .. | .. |
|---|
| 246 | 226 | if (!sctp_ulpq_init(&asoc->ulpq, asoc)) |
|---|
| 247 | 227 | goto fail_init; |
|---|
| 248 | 228 | |
|---|
| 249 | | - if (sctp_stream_init(&asoc->stream, asoc->c.sinit_num_ostreams, |
|---|
| 250 | | - 0, gfp)) |
|---|
| 251 | | - goto fail_init; |
|---|
| 229 | + if (sctp_stream_init(&asoc->stream, asoc->c.sinit_num_ostreams, 0, gfp)) |
|---|
| 230 | + goto stream_free; |
|---|
| 252 | 231 | |
|---|
| 253 | 232 | /* Initialize default path MTU. */ |
|---|
| 254 | 233 | asoc->pathmtu = sp->pathmtu; |
|---|
| .. | .. |
|---|
| 275 | 254 | goto stream_free; |
|---|
| 276 | 255 | |
|---|
| 277 | 256 | asoc->active_key_id = ep->active_key_id; |
|---|
| 278 | | - asoc->prsctp_enable = ep->prsctp_enable; |
|---|
| 279 | | - asoc->reconf_enable = ep->reconf_enable; |
|---|
| 280 | 257 | asoc->strreset_enable = ep->strreset_enable; |
|---|
| 281 | 258 | |
|---|
| 282 | 259 | /* Save the hmacs and chunks list into this association */ |
|---|
| .. | .. |
|---|
| 349 | 326 | * socket. |
|---|
| 350 | 327 | */ |
|---|
| 351 | 328 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) |
|---|
| 352 | | - sk->sk_ack_backlog--; |
|---|
| 329 | + sk_acceptq_removed(sk); |
|---|
| 353 | 330 | } |
|---|
| 354 | 331 | |
|---|
| 355 | 332 | /* Mark as dead, so other users can know this structure is |
|---|
| .. | .. |
|---|
| 454 | 431 | changeover = 1 ; |
|---|
| 455 | 432 | |
|---|
| 456 | 433 | asoc->peer.primary_path = transport; |
|---|
| 434 | + sctp_ulpevent_notify_peer_addr_change(transport, |
|---|
| 435 | + SCTP_ADDR_MADE_PRIM, 0); |
|---|
| 457 | 436 | |
|---|
| 458 | 437 | /* Set a default msg_name for events. */ |
|---|
| 459 | 438 | memcpy(&asoc->peer.primary_addr, &transport->ipaddr, |
|---|
| .. | .. |
|---|
| 594 | 573 | |
|---|
| 595 | 574 | asoc->peer.transport_count--; |
|---|
| 596 | 575 | |
|---|
| 576 | + sctp_ulpevent_notify_peer_addr_change(peer, SCTP_ADDR_REMOVED, 0); |
|---|
| 597 | 577 | sctp_transport_free(peer); |
|---|
| 598 | 578 | } |
|---|
| 599 | 579 | |
|---|
| .. | .. |
|---|
| 603 | 583 | const gfp_t gfp, |
|---|
| 604 | 584 | const int peer_state) |
|---|
| 605 | 585 | { |
|---|
| 606 | | - struct net *net = sock_net(asoc->base.sk); |
|---|
| 607 | 586 | struct sctp_transport *peer; |
|---|
| 608 | 587 | struct sctp_sock *sp; |
|---|
| 609 | 588 | unsigned short port; |
|---|
| .. | .. |
|---|
| 633 | 612 | return peer; |
|---|
| 634 | 613 | } |
|---|
| 635 | 614 | |
|---|
| 636 | | - peer = sctp_transport_new(net, addr, gfp); |
|---|
| 615 | + peer = sctp_transport_new(asoc->base.net, addr, gfp); |
|---|
| 637 | 616 | if (!peer) |
|---|
| 638 | 617 | return NULL; |
|---|
| 639 | 618 | |
|---|
| .. | .. |
|---|
| 649 | 628 | |
|---|
| 650 | 629 | /* And the partial failure retrans threshold */ |
|---|
| 651 | 630 | peer->pf_retrans = asoc->pf_retrans; |
|---|
| 631 | + /* And the primary path switchover retrans threshold */ |
|---|
| 632 | + peer->ps_retrans = asoc->ps_retrans; |
|---|
| 652 | 633 | |
|---|
| 653 | 634 | /* Initialize the peer's SACK delay timeout based on the |
|---|
| 654 | 635 | * association configured value. |
|---|
| .. | .. |
|---|
| 732 | 713 | list_add_tail_rcu(&peer->transports, &asoc->peer.transport_addr_list); |
|---|
| 733 | 714 | asoc->peer.transport_count++; |
|---|
| 734 | 715 | |
|---|
| 716 | + sctp_ulpevent_notify_peer_addr_change(peer, SCTP_ADDR_ADDED, 0); |
|---|
| 717 | + |
|---|
| 735 | 718 | /* If we do not yet have a primary path, set one. */ |
|---|
| 736 | 719 | if (!asoc->peer.primary_path) { |
|---|
| 737 | 720 | sctp_assoc_set_primary(asoc, peer); |
|---|
| .. | .. |
|---|
| 806 | 789 | enum sctp_transport_cmd command, |
|---|
| 807 | 790 | sctp_sn_error_t error) |
|---|
| 808 | 791 | { |
|---|
| 809 | | - struct sctp_ulpevent *event; |
|---|
| 810 | | - struct sockaddr_storage addr; |
|---|
| 811 | | - int spc_state = 0; |
|---|
| 792 | + int spc_state = SCTP_ADDR_AVAILABLE; |
|---|
| 812 | 793 | bool ulp_notify = true; |
|---|
| 813 | 794 | |
|---|
| 814 | 795 | /* Record the transition on the transport. */ |
|---|
| .. | .. |
|---|
| 818 | 799 | * to heartbeat success, report the SCTP_ADDR_CONFIRMED |
|---|
| 819 | 800 | * state to the user, otherwise report SCTP_ADDR_AVAILABLE. |
|---|
| 820 | 801 | */ |
|---|
| 821 | | - if (SCTP_UNCONFIRMED == transport->state && |
|---|
| 822 | | - SCTP_HEARTBEAT_SUCCESS == error) |
|---|
| 823 | | - spc_state = SCTP_ADDR_CONFIRMED; |
|---|
| 824 | | - else |
|---|
| 825 | | - spc_state = SCTP_ADDR_AVAILABLE; |
|---|
| 826 | | - /* Don't inform ULP about transition from PF to |
|---|
| 827 | | - * active state and set cwnd to 1 MTU, see SCTP |
|---|
| 828 | | - * Quick failover draft section 5.1, point 5 |
|---|
| 829 | | - */ |
|---|
| 830 | | - if (transport->state == SCTP_PF) { |
|---|
| 802 | + if (transport->state == SCTP_PF && |
|---|
| 803 | + asoc->pf_expose != SCTP_PF_EXPOSE_ENABLE) |
|---|
| 831 | 804 | ulp_notify = false; |
|---|
| 832 | | - transport->cwnd = asoc->pathmtu; |
|---|
| 833 | | - } |
|---|
| 805 | + else if (transport->state == SCTP_UNCONFIRMED && |
|---|
| 806 | + error == SCTP_HEARTBEAT_SUCCESS) |
|---|
| 807 | + spc_state = SCTP_ADDR_CONFIRMED; |
|---|
| 808 | + |
|---|
| 834 | 809 | transport->state = SCTP_ACTIVE; |
|---|
| 835 | 810 | break; |
|---|
| 836 | 811 | |
|---|
| .. | .. |
|---|
| 839 | 814 | * to inactive state. Also, release the cached route since |
|---|
| 840 | 815 | * there may be a better route next time. |
|---|
| 841 | 816 | */ |
|---|
| 842 | | - if (transport->state != SCTP_UNCONFIRMED) |
|---|
| 817 | + if (transport->state != SCTP_UNCONFIRMED) { |
|---|
| 843 | 818 | transport->state = SCTP_INACTIVE; |
|---|
| 844 | | - else { |
|---|
| 819 | + spc_state = SCTP_ADDR_UNREACHABLE; |
|---|
| 820 | + } else { |
|---|
| 845 | 821 | sctp_transport_dst_release(transport); |
|---|
| 846 | 822 | ulp_notify = false; |
|---|
| 847 | 823 | } |
|---|
| 848 | | - |
|---|
| 849 | | - spc_state = SCTP_ADDR_UNREACHABLE; |
|---|
| 850 | 824 | break; |
|---|
| 851 | 825 | |
|---|
| 852 | 826 | case SCTP_TRANSPORT_PF: |
|---|
| 853 | 827 | transport->state = SCTP_PF; |
|---|
| 854 | | - ulp_notify = false; |
|---|
| 828 | + if (asoc->pf_expose != SCTP_PF_EXPOSE_ENABLE) |
|---|
| 829 | + ulp_notify = false; |
|---|
| 830 | + else |
|---|
| 831 | + spc_state = SCTP_ADDR_POTENTIALLY_FAILED; |
|---|
| 855 | 832 | break; |
|---|
| 856 | 833 | |
|---|
| 857 | 834 | default: |
|---|
| .. | .. |
|---|
| 861 | 838 | /* Generate and send a SCTP_PEER_ADDR_CHANGE notification |
|---|
| 862 | 839 | * to the user. |
|---|
| 863 | 840 | */ |
|---|
| 864 | | - if (ulp_notify) { |
|---|
| 865 | | - memset(&addr, 0, sizeof(struct sockaddr_storage)); |
|---|
| 866 | | - memcpy(&addr, &transport->ipaddr, |
|---|
| 867 | | - transport->af_specific->sockaddr_len); |
|---|
| 868 | | - |
|---|
| 869 | | - event = sctp_ulpevent_make_peer_addr_change(asoc, &addr, |
|---|
| 870 | | - 0, spc_state, error, GFP_ATOMIC); |
|---|
| 871 | | - if (event) |
|---|
| 872 | | - asoc->stream.si->enqueue_event(&asoc->ulpq, event); |
|---|
| 873 | | - } |
|---|
| 841 | + if (ulp_notify) |
|---|
| 842 | + sctp_ulpevent_notify_peer_addr_change(transport, |
|---|
| 843 | + spc_state, error); |
|---|
| 874 | 844 | |
|---|
| 875 | 845 | /* Select new active and retran paths. */ |
|---|
| 876 | 846 | sctp_select_active_and_retran_path(asoc); |
|---|
| .. | .. |
|---|
| 1002 | 972 | struct sctp_association *asoc = |
|---|
| 1003 | 973 | container_of(work, struct sctp_association, |
|---|
| 1004 | 974 | base.inqueue.immediate); |
|---|
| 1005 | | - struct net *net = sock_net(asoc->base.sk); |
|---|
| 975 | + struct net *net = asoc->base.net; |
|---|
| 1006 | 976 | union sctp_subtype subtype; |
|---|
| 1007 | 977 | struct sctp_endpoint *ep; |
|---|
| 1008 | 978 | struct sctp_chunk *chunk; |
|---|
| .. | .. |
|---|
| 1102 | 1072 | |
|---|
| 1103 | 1073 | /* Decrement the backlog value for a TCP-style socket. */ |
|---|
| 1104 | 1074 | if (sctp_style(oldsk, TCP)) |
|---|
| 1105 | | - oldsk->sk_ack_backlog--; |
|---|
| 1075 | + sk_acceptq_removed(oldsk); |
|---|
| 1106 | 1076 | |
|---|
| 1107 | 1077 | /* Release references to the old endpoint and the sock. */ |
|---|
| 1108 | 1078 | sctp_endpoint_put(assoc->ep); |
|---|
| .. | .. |
|---|
| 1181 | 1151 | /* Add any peer addresses from the new association. */ |
|---|
| 1182 | 1152 | list_for_each_entry(trans, &new->peer.transport_addr_list, |
|---|
| 1183 | 1153 | transports) |
|---|
| 1184 | | - if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) && |
|---|
| 1185 | | - !sctp_assoc_add_peer(asoc, &trans->ipaddr, |
|---|
| 1154 | + if (!sctp_assoc_add_peer(asoc, &trans->ipaddr, |
|---|
| 1186 | 1155 | GFP_ATOMIC, trans->state)) |
|---|
| 1187 | 1156 | return -ENOMEM; |
|---|
| 1188 | 1157 | |
|---|
| .. | .. |
|---|
| 1380 | 1349 | } |
|---|
| 1381 | 1350 | |
|---|
| 1382 | 1351 | /* We did not find anything useful for a possible retransmission |
|---|
| 1383 | | - * path; either primary path that we found is the the same as |
|---|
| 1352 | + * path; either primary path that we found is the same as |
|---|
| 1384 | 1353 | * the current one, or we didn't generally find an active one. |
|---|
| 1385 | 1354 | */ |
|---|
| 1386 | 1355 | if (trans_sec == NULL) |
|---|
| .. | .. |
|---|
| 1470 | 1439 | /* Should we send a SACK to update our peer? */ |
|---|
| 1471 | 1440 | static inline bool sctp_peer_needs_update(struct sctp_association *asoc) |
|---|
| 1472 | 1441 | { |
|---|
| 1473 | | - struct net *net = sock_net(asoc->base.sk); |
|---|
| 1442 | + struct net *net = asoc->base.net; |
|---|
| 1443 | + |
|---|
| 1474 | 1444 | switch (asoc->state) { |
|---|
| 1475 | 1445 | case SCTP_STATE_ESTABLISHED: |
|---|
| 1476 | 1446 | case SCTP_STATE_SHUTDOWN_PENDING: |
|---|
| .. | .. |
|---|
| 1565 | 1535 | |
|---|
| 1566 | 1536 | /* If we've reached or overflowed our receive buffer, announce |
|---|
| 1567 | 1537 | * a 0 rwnd if rwnd would still be positive. Store the |
|---|
| 1568 | | - * the potential pressure overflow so that the window can be restored |
|---|
| 1538 | + * potential pressure overflow so that the window can be restored |
|---|
| 1569 | 1539 | * back to original value. |
|---|
| 1570 | 1540 | */ |
|---|
| 1571 | 1541 | if (rx_count >= asoc->base.sk->sk_rcvbuf) |
|---|
| .. | .. |
|---|
| 1607 | 1577 | if (asoc->peer.ipv6_address) |
|---|
| 1608 | 1578 | flags |= SCTP_ADDR6_PEERSUPP; |
|---|
| 1609 | 1579 | |
|---|
| 1610 | | - return sctp_bind_addr_copy(sock_net(asoc->base.sk), |
|---|
| 1580 | + return sctp_bind_addr_copy(asoc->base.net, |
|---|
| 1611 | 1581 | &asoc->base.bind_addr, |
|---|
| 1612 | 1582 | &asoc->ep->base.bind_addr, |
|---|
| 1613 | 1583 | scope, gfp, flags); |
|---|
| .. | .. |
|---|
| 1653 | 1623 | if (preload) |
|---|
| 1654 | 1624 | idr_preload(gfp); |
|---|
| 1655 | 1625 | spin_lock_bh(&sctp_assocs_id_lock); |
|---|
| 1656 | | - /* 0 is not a valid assoc_id, must be >= 1 */ |
|---|
| 1657 | | - ret = idr_alloc_cyclic(&sctp_assocs_id, asoc, 1, 0, GFP_NOWAIT); |
|---|
| 1626 | + /* 0, 1, 2 are used as SCTP_FUTURE_ASSOC, SCTP_CURRENT_ASSOC and |
|---|
| 1627 | + * SCTP_ALL_ASSOC, so an available id must be > SCTP_ALL_ASSOC. |
|---|
| 1628 | + */ |
|---|
| 1629 | + ret = idr_alloc_cyclic(&sctp_assocs_id, asoc, SCTP_ALL_ASSOC + 1, 0, |
|---|
| 1630 | + GFP_NOWAIT); |
|---|
| 1658 | 1631 | spin_unlock_bh(&sctp_assocs_id_lock); |
|---|
| 1659 | 1632 | if (preload) |
|---|
| 1660 | 1633 | idr_preload_end(); |
|---|