hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/net/sctp/bind_addr.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* SCTP kernel implementation
23 * (C) Copyright IBM Corp. 2001, 2003
34 * Copyright (c) Cisco 1999,2000
....@@ -7,22 +8,6 @@
78 * This file is part of the SCTP kernel implementation.
89 *
910 * A collection class to handle the storage of transport addresses.
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/>.
2611 *
2712 * Please send any bug reports or fixes you make to the
2813 * email address(es):
....@@ -87,6 +72,12 @@
8772 goto out;
8873 }
8974 }
75
+
76
+ /* If somehow no addresses were found that can be used with this
77
+ * scope, it's an error.
78
+ */
79
+ if (list_empty(&dest->address_list))
80
+ error = -ENETUNREACH;
9081
9182 out:
9283 if (error)
....@@ -340,6 +331,34 @@
340331 return match;
341332 }
342333
334
+int sctp_bind_addrs_check(struct sctp_sock *sp,
335
+ struct sctp_sock *sp2, int cnt2)
336
+{
337
+ struct sctp_bind_addr *bp2 = &sp2->ep->base.bind_addr;
338
+ struct sctp_bind_addr *bp = &sp->ep->base.bind_addr;
339
+ struct sctp_sockaddr_entry *laddr, *laddr2;
340
+ bool exist = false;
341
+ int cnt = 0;
342
+
343
+ rcu_read_lock();
344
+ list_for_each_entry_rcu(laddr, &bp->address_list, list) {
345
+ list_for_each_entry_rcu(laddr2, &bp2->address_list, list) {
346
+ if (sp->pf->af->cmp_addr(&laddr->a, &laddr2->a) &&
347
+ laddr->valid && laddr2->valid) {
348
+ exist = true;
349
+ goto next;
350
+ }
351
+ }
352
+ cnt = 0;
353
+ break;
354
+next:
355
+ cnt++;
356
+ }
357
+ rcu_read_unlock();
358
+
359
+ return (cnt == cnt2) ? 0 : (exist ? -EEXIST : 1);
360
+}
361
+
343362 /* Does the address 'addr' conflict with any addresses in
344363 * the bp.
345364 */
....@@ -383,24 +402,19 @@
383402 {
384403 struct sctp_sockaddr_entry *laddr;
385404 struct sctp_af *af;
386
- int state = -1;
387405
388406 af = sctp_get_af_specific(addr->sa.sa_family);
389407 if (unlikely(!af))
390
- return state;
408
+ return -1;
391409
392
- rcu_read_lock();
393410 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
394411 if (!laddr->valid)
395412 continue;
396
- if (af->cmp_addr(&laddr->a, addr)) {
397
- state = laddr->state;
398
- break;
399
- }
413
+ if (af->cmp_addr(&laddr->a, addr))
414
+ return laddr->state;
400415 }
401
- rcu_read_unlock();
402416
403
- return state;
417
+ return -1;
404418 }
405419
406420 /* Find the first address in the bind address list that is not present in
....@@ -500,7 +514,7 @@
500514 return 0;
501515 /*
502516 * For INIT and INIT-ACK address list, let L be the level of
503
- * of requested destination address, sender and receiver
517
+ * requested destination address, sender and receiver
504518 * SHOULD include all of its addresses with level greater
505519 * than or equal to L.
506520 *