| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* SCTP kernel implementation |
|---|
| 2 | 3 | * Copyright (c) 1999-2000 Cisco, Inc. |
|---|
| 3 | 4 | * Copyright (c) 1999-2001 Motorola, Inc. |
|---|
| .. | .. |
|---|
| 9 | 10 | * This file is part of the SCTP kernel implementation |
|---|
| 10 | 11 | * |
|---|
| 11 | 12 | * This abstraction represents an SCTP endpoint. |
|---|
| 12 | | - * |
|---|
| 13 | | - * The SCTP implementation is free software; |
|---|
| 14 | | - * you can redistribute it and/or modify it under the terms of |
|---|
| 15 | | - * the GNU General Public License as published by |
|---|
| 16 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 17 | | - * any later version. |
|---|
| 18 | | - * |
|---|
| 19 | | - * The SCTP implementation is distributed in the hope that it |
|---|
| 20 | | - * will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|---|
| 21 | | - * ************************ |
|---|
| 22 | | - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 23 | | - * See the GNU General Public License for more details. |
|---|
| 24 | | - * |
|---|
| 25 | | - * You should have received a copy of the GNU General Public License |
|---|
| 26 | | - * along with GNU CC; see the file COPYING. If not, see |
|---|
| 27 | | - * <http://www.gnu.org/licenses/>. |
|---|
| 28 | 13 | * |
|---|
| 29 | 14 | * Please send any bug reports or fixes you make to the |
|---|
| 30 | 15 | * email address(es): |
|---|
| .. | .. |
|---|
| 58 | 43 | gfp_t gfp) |
|---|
| 59 | 44 | { |
|---|
| 60 | 45 | struct net *net = sock_net(sk); |
|---|
| 61 | | - struct sctp_hmac_algo_param *auth_hmacs = NULL; |
|---|
| 62 | | - struct sctp_chunks_param *auth_chunks = NULL; |
|---|
| 63 | 46 | struct sctp_shared_key *null_key; |
|---|
| 64 | | - int err; |
|---|
| 65 | 47 | |
|---|
| 66 | 48 | ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp); |
|---|
| 67 | 49 | if (!ep->digest) |
|---|
| 68 | 50 | return NULL; |
|---|
| 69 | 51 | |
|---|
| 52 | + ep->asconf_enable = net->sctp.addip_enable; |
|---|
| 70 | 53 | ep->auth_enable = net->sctp.auth_enable; |
|---|
| 71 | 54 | if (ep->auth_enable) { |
|---|
| 72 | | - /* Allocate space for HMACS and CHUNKS authentication |
|---|
| 73 | | - * variables. There are arrays that we encode directly |
|---|
| 74 | | - * into parameters to make the rest of the operations easier. |
|---|
| 75 | | - */ |
|---|
| 76 | | - auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids, |
|---|
| 77 | | - SCTP_AUTH_NUM_HMACS), gfp); |
|---|
| 78 | | - if (!auth_hmacs) |
|---|
| 55 | + if (sctp_auth_init(ep, gfp)) |
|---|
| 79 | 56 | goto nomem; |
|---|
| 80 | | - |
|---|
| 81 | | - auth_chunks = kzalloc(sizeof(*auth_chunks) + |
|---|
| 82 | | - SCTP_NUM_CHUNK_TYPES, gfp); |
|---|
| 83 | | - if (!auth_chunks) |
|---|
| 84 | | - goto nomem; |
|---|
| 85 | | - |
|---|
| 86 | | - /* Initialize the HMACS parameter. |
|---|
| 87 | | - * SCTP-AUTH: Section 3.3 |
|---|
| 88 | | - * Every endpoint supporting SCTP chunk authentication MUST |
|---|
| 89 | | - * support the HMAC based on the SHA-1 algorithm. |
|---|
| 90 | | - */ |
|---|
| 91 | | - auth_hmacs->param_hdr.type = SCTP_PARAM_HMAC_ALGO; |
|---|
| 92 | | - auth_hmacs->param_hdr.length = |
|---|
| 93 | | - htons(sizeof(struct sctp_paramhdr) + 2); |
|---|
| 94 | | - auth_hmacs->hmac_ids[0] = htons(SCTP_AUTH_HMAC_ID_SHA1); |
|---|
| 95 | | - |
|---|
| 96 | | - /* Initialize the CHUNKS parameter */ |
|---|
| 97 | | - auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS; |
|---|
| 98 | | - auth_chunks->param_hdr.length = |
|---|
| 99 | | - htons(sizeof(struct sctp_paramhdr)); |
|---|
| 100 | | - |
|---|
| 101 | | - /* If the Add-IP functionality is enabled, we must |
|---|
| 102 | | - * authenticate, ASCONF and ASCONF-ACK chunks |
|---|
| 103 | | - */ |
|---|
| 104 | | - if (net->sctp.addip_enable) { |
|---|
| 105 | | - auth_chunks->chunks[0] = SCTP_CID_ASCONF; |
|---|
| 106 | | - auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK; |
|---|
| 107 | | - auth_chunks->param_hdr.length = |
|---|
| 108 | | - htons(sizeof(struct sctp_paramhdr) + 2); |
|---|
| 57 | + if (ep->asconf_enable) { |
|---|
| 58 | + sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF); |
|---|
| 59 | + sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF_ACK); |
|---|
| 109 | 60 | } |
|---|
| 110 | 61 | } |
|---|
| 111 | 62 | |
|---|
| .. | .. |
|---|
| 146 | 97 | INIT_LIST_HEAD(&ep->endpoint_shared_keys); |
|---|
| 147 | 98 | null_key = sctp_auth_shkey_create(0, gfp); |
|---|
| 148 | 99 | if (!null_key) |
|---|
| 149 | | - goto nomem; |
|---|
| 100 | + goto nomem_shkey; |
|---|
| 150 | 101 | |
|---|
| 151 | 102 | list_add(&null_key->key_list, &ep->endpoint_shared_keys); |
|---|
| 152 | | - |
|---|
| 153 | | - /* Allocate and initialize transorms arrays for supported HMACs. */ |
|---|
| 154 | | - err = sctp_auth_init_hmacs(ep, gfp); |
|---|
| 155 | | - if (err) |
|---|
| 156 | | - goto nomem_hmacs; |
|---|
| 157 | 103 | |
|---|
| 158 | 104 | /* Add the null key to the endpoint shared keys list and |
|---|
| 159 | 105 | * set the hmcas and chunks pointers. |
|---|
| 160 | 106 | */ |
|---|
| 161 | | - ep->auth_hmacs_list = auth_hmacs; |
|---|
| 162 | | - ep->auth_chunk_list = auth_chunks; |
|---|
| 163 | 107 | ep->prsctp_enable = net->sctp.prsctp_enable; |
|---|
| 164 | 108 | ep->reconf_enable = net->sctp.reconf_enable; |
|---|
| 109 | + ep->ecn_enable = net->sctp.ecn_enable; |
|---|
| 165 | 110 | |
|---|
| 166 | 111 | /* Remember who we are attached to. */ |
|---|
| 167 | 112 | ep->base.sk = sk; |
|---|
| .. | .. |
|---|
| 170 | 115 | |
|---|
| 171 | 116 | return ep; |
|---|
| 172 | 117 | |
|---|
| 173 | | -nomem_hmacs: |
|---|
| 174 | | - sctp_auth_destroy_keys(&ep->endpoint_shared_keys); |
|---|
| 118 | +nomem_shkey: |
|---|
| 119 | + sctp_auth_free(ep); |
|---|
| 175 | 120 | nomem: |
|---|
| 176 | | - /* Free all allocations */ |
|---|
| 177 | | - kfree(auth_hmacs); |
|---|
| 178 | | - kfree(auth_chunks); |
|---|
| 179 | 121 | kfree(ep->digest); |
|---|
| 180 | 122 | return NULL; |
|---|
| 181 | 123 | |
|---|
| .. | .. |
|---|
| 223 | 165 | |
|---|
| 224 | 166 | /* Increment the backlog value for a TCP-style listening socket. */ |
|---|
| 225 | 167 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) |
|---|
| 226 | | - sk->sk_ack_backlog++; |
|---|
| 168 | + sk_acceptq_added(sk); |
|---|
| 227 | 169 | } |
|---|
| 228 | 170 | |
|---|
| 229 | 171 | /* Free the endpoint structure. Delay cleanup until |
|---|
| .. | .. |
|---|
| 270 | 212 | * chunks and hmacs arrays that were allocated |
|---|
| 271 | 213 | */ |
|---|
| 272 | 214 | sctp_auth_destroy_keys(&ep->endpoint_shared_keys); |
|---|
| 273 | | - kfree(ep->auth_hmacs_list); |
|---|
| 274 | | - kfree(ep->auth_chunk_list); |
|---|
| 275 | | - |
|---|
| 276 | | - /* AUTH - Free any allocated HMAC transform containers */ |
|---|
| 277 | | - sctp_auth_destroy_hmacs(ep->auth_hmacs); |
|---|
| 215 | + sctp_auth_free(ep); |
|---|
| 278 | 216 | |
|---|
| 279 | 217 | /* Cleanup. */ |
|---|
| 280 | 218 | sctp_inq_free(&ep->base.inqueue); |
|---|
| .. | .. |
|---|
| 313 | 251 | struct sctp_endpoint *retval = NULL; |
|---|
| 314 | 252 | |
|---|
| 315 | 253 | if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) && |
|---|
| 316 | | - net_eq(sock_net(ep->base.sk), net)) { |
|---|
| 254 | + net_eq(ep->base.net, net)) { |
|---|
| 317 | 255 | if (sctp_bind_addr_match(&ep->base.bind_addr, laddr, |
|---|
| 318 | 256 | sctp_sk(ep->base.sk))) |
|---|
| 319 | 257 | retval = ep; |
|---|
| .. | .. |
|---|
| 361 | 299 | const union sctp_addr *paddr) |
|---|
| 362 | 300 | { |
|---|
| 363 | 301 | struct sctp_sockaddr_entry *addr; |
|---|
| 302 | + struct net *net = ep->base.net; |
|---|
| 364 | 303 | struct sctp_bind_addr *bp; |
|---|
| 365 | | - struct net *net = sock_net(ep->base.sk); |
|---|
| 366 | 304 | |
|---|
| 367 | 305 | bp = &ep->base.bind_addr; |
|---|
| 368 | 306 | /* This function is called with the socket lock held, |
|---|
| .. | .. |
|---|
| 453 | 391 | if (asoc && sctp_chunk_is_data(chunk)) |
|---|
| 454 | 392 | asoc->peer.last_data_from = chunk->transport; |
|---|
| 455 | 393 | else { |
|---|
| 456 | | - SCTP_INC_STATS(sock_net(ep->base.sk), SCTP_MIB_INCTRLCHUNKS); |
|---|
| 394 | + SCTP_INC_STATS(ep->base.net, SCTP_MIB_INCTRLCHUNKS); |
|---|
| 457 | 395 | if (asoc) |
|---|
| 458 | 396 | asoc->stats.ictrlchunks++; |
|---|
| 459 | 397 | } |
|---|