hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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):
....@@ -340,6 +325,34 @@
340325 return match;
341326 }
342327
328
+int sctp_bind_addrs_check(struct sctp_sock *sp,
329
+ struct sctp_sock *sp2, int cnt2)
330
+{
331
+ struct sctp_bind_addr *bp2 = &sp2->ep->base.bind_addr;
332
+ struct sctp_bind_addr *bp = &sp->ep->base.bind_addr;
333
+ struct sctp_sockaddr_entry *laddr, *laddr2;
334
+ bool exist = false;
335
+ int cnt = 0;
336
+
337
+ rcu_read_lock();
338
+ list_for_each_entry_rcu(laddr, &bp->address_list, list) {
339
+ list_for_each_entry_rcu(laddr2, &bp2->address_list, list) {
340
+ if (sp->pf->af->cmp_addr(&laddr->a, &laddr2->a) &&
341
+ laddr->valid && laddr2->valid) {
342
+ exist = true;
343
+ goto next;
344
+ }
345
+ }
346
+ cnt = 0;
347
+ break;
348
+next:
349
+ cnt++;
350
+ }
351
+ rcu_read_unlock();
352
+
353
+ return (cnt == cnt2) ? 0 : (exist ? -EEXIST : 1);
354
+}
355
+
343356 /* Does the address 'addr' conflict with any addresses in
344357 * the bp.
345358 */
....@@ -383,24 +396,19 @@
383396 {
384397 struct sctp_sockaddr_entry *laddr;
385398 struct sctp_af *af;
386
- int state = -1;
387399
388400 af = sctp_get_af_specific(addr->sa.sa_family);
389401 if (unlikely(!af))
390
- return state;
402
+ return -1;
391403
392
- rcu_read_lock();
393404 list_for_each_entry_rcu(laddr, &bp->address_list, list) {
394405 if (!laddr->valid)
395406 continue;
396
- if (af->cmp_addr(&laddr->a, addr)) {
397
- state = laddr->state;
398
- break;
399
- }
407
+ if (af->cmp_addr(&laddr->a, addr))
408
+ return laddr->state;
400409 }
401
- rcu_read_unlock();
402410
403
- return state;
411
+ return -1;
404412 }
405413
406414 /* Find the first address in the bind address list that is not present in
....@@ -500,7 +508,7 @@
500508 return 0;
501509 /*
502510 * For INIT and INIT-ACK address list, let L be the level of
503
- * of requested destination address, sender and receiver
511
+ * requested destination address, sender and receiver
504512 * SHOULD include all of its addresses with level greater
505513 * than or equal to L.
506514 *