forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/net/dccp/proto.c
....@@ -1,12 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * net/dccp/proto.c
34 *
45 * An implementation of the DCCP protocol
56 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6
- *
7
- * This program is free software; you can redistribute it and/or modify it
8
- * under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
107 */
118
129 #include <linux/dccp.h>
....@@ -104,7 +101,7 @@
104101 if (inet_csk(sk)->icsk_bind_hash != NULL &&
105102 !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
106103 inet_put_port(sk);
107
- /* fall through */
104
+ fallthrough;
108105 default:
109106 if (oldstate == DCCP_OPEN)
110107 DCCP_DEC_STATS(DCCP_MIB_CURRESTAB);
....@@ -263,7 +260,6 @@
263260 struct inet_connection_sock *icsk = inet_csk(sk);
264261 struct inet_sock *inet = inet_sk(sk);
265262 struct dccp_sock *dp = dccp_sk(sk);
266
- int err = 0;
267263 const int old_state = sk->sk_state;
268264
269265 if (old_state != DCCP_CLOSED)
....@@ -307,7 +303,7 @@
307303 WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
308304
309305 sk->sk_error_report(sk);
310
- return err;
306
+ return 0;
311307 }
312308
313309 EXPORT_SYMBOL_GPL(dccp_disconnect);
....@@ -379,6 +375,15 @@
379375 goto out;
380376
381377 switch (cmd) {
378
+ case SIOCOUTQ: {
379
+ int amount = sk_wmem_alloc_get(sk);
380
+ /* Using sk_wmem_alloc here because sk_wmem_queued is not used by DCCP and
381
+ * always 0, comparably to UDP.
382
+ */
383
+
384
+ rc = put_user(amount, (int __user *)arg);
385
+ }
386
+ break;
382387 case SIOCINQ: {
383388 struct sk_buff *skb;
384389 unsigned long amount = 0;
....@@ -406,7 +411,7 @@
406411 EXPORT_SYMBOL_GPL(dccp_ioctl);
407412
408413 static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
409
- char __user *optval, unsigned int optlen)
414
+ sockptr_t optval, unsigned int optlen)
410415 {
411416 struct dccp_sock *dp = dccp_sk(sk);
412417 struct dccp_service_list *sl = NULL;
....@@ -421,9 +426,8 @@
421426 return -ENOMEM;
422427
423428 sl->dccpsl_nr = optlen / sizeof(u32) - 1;
424
- if (copy_from_user(sl->dccpsl_list,
425
- optval + sizeof(service),
426
- optlen - sizeof(service)) ||
429
+ if (copy_from_sockptr_offset(sl->dccpsl_list, optval,
430
+ sizeof(service), optlen - sizeof(service)) ||
427431 dccp_list_has_service(sl, DCCP_SERVICE_INVALID_VALUE)) {
428432 kfree(sl);
429433 return -EFAULT;
....@@ -477,7 +481,7 @@
477481 }
478482
479483 static int dccp_setsockopt_ccid(struct sock *sk, int type,
480
- char __user *optval, unsigned int optlen)
484
+ sockptr_t optval, unsigned int optlen)
481485 {
482486 u8 *val;
483487 int rc = 0;
....@@ -485,7 +489,7 @@
485489 if (optlen < 1 || optlen > DCCP_FEAT_MAX_SP_VALS)
486490 return -EINVAL;
487491
488
- val = memdup_user(optval, optlen);
492
+ val = memdup_sockptr(optval, optlen);
489493 if (IS_ERR(val))
490494 return PTR_ERR(val);
491495
....@@ -502,7 +506,7 @@
502506 }
503507
504508 static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
505
- char __user *optval, unsigned int optlen)
509
+ sockptr_t optval, unsigned int optlen)
506510 {
507511 struct dccp_sock *dp = dccp_sk(sk);
508512 int val, err = 0;
....@@ -524,7 +528,7 @@
524528 if (optlen < (int)sizeof(int))
525529 return -EINVAL;
526530
527
- if (get_user(val, (int __user *)optval))
531
+ if (copy_from_sockptr(&val, optval, sizeof(int)))
528532 return -EFAULT;
529533
530534 if (optname == DCCP_SOCKOPT_SERVICE)
....@@ -567,8 +571,8 @@
567571 return err;
568572 }
569573
570
-int dccp_setsockopt(struct sock *sk, int level, int optname,
571
- char __user *optval, unsigned int optlen)
574
+int dccp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
575
+ unsigned int optlen)
572576 {
573577 if (level != SOL_DCCP)
574578 return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
....@@ -578,19 +582,6 @@
578582 }
579583
580584 EXPORT_SYMBOL_GPL(dccp_setsockopt);
581
-
582
-#ifdef CONFIG_COMPAT
583
-int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
584
- char __user *optval, unsigned int optlen)
585
-{
586
- if (level != SOL_DCCP)
587
- return inet_csk_compat_setsockopt(sk, level, optname,
588
- optval, optlen);
589
- return do_dccp_setsockopt(sk, level, optname, optval, optlen);
590
-}
591
-
592
-EXPORT_SYMBOL_GPL(compat_dccp_setsockopt);
593
-#endif
594585
595586 static int dccp_getsockopt_service(struct sock *sk, int len,
596587 __be32 __user *optval,
....@@ -700,19 +691,6 @@
700691
701692 EXPORT_SYMBOL_GPL(dccp_getsockopt);
702693
703
-#ifdef CONFIG_COMPAT
704
-int compat_dccp_getsockopt(struct sock *sk, int level, int optname,
705
- char __user *optval, int __user *optlen)
706
-{
707
- if (level != SOL_DCCP)
708
- return inet_csk_compat_getsockopt(sk, level, optname,
709
- optval, optlen);
710
- return do_dccp_getsockopt(sk, level, optname, optval, optlen);
711
-}
712
-
713
-EXPORT_SYMBOL_GPL(compat_dccp_getsockopt);
714
-#endif
715
-
716694 static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb)
717695 {
718696 struct cmsghdr *cmsg;
....@@ -769,11 +747,6 @@
769747
770748 lock_sock(sk);
771749
772
- if (dccp_qpolicy_full(sk)) {
773
- rc = -EAGAIN;
774
- goto out_release;
775
- }
776
-
777750 timeo = sock_sndtimeo(sk, noblock);
778751
779752 /*
....@@ -791,6 +764,11 @@
791764 lock_sock(sk);
792765 if (skb == NULL)
793766 goto out_release;
767
+
768
+ if (dccp_qpolicy_full(sk)) {
769
+ rc = -EAGAIN;
770
+ goto out_discard;
771
+ }
794772
795773 if (sk->sk_state == DCCP_CLOSED) {
796774 rc = -ENOTCONN;
....@@ -856,7 +834,7 @@
856834 case DCCP_PKT_CLOSEREQ:
857835 if (!(flags & MSG_PEEK))
858836 dccp_finish_passive_close(sk);
859
- /* fall through */
837
+ fallthrough;
860838 case DCCP_PKT_RESET:
861839 dccp_pr_debug("found fin (%s) ok!\n",
862840 dccp_packet_name(dh->dccph_type));
....@@ -948,6 +926,7 @@
948926 if (!((1 << old_state) & (DCCPF_CLOSED | DCCPF_LISTEN)))
949927 goto out;
950928
929
+ WRITE_ONCE(sk->sk_max_ack_backlog, backlog);
951930 /* Really, if the socket is already in listen state
952931 * we can only allow the backlog to be adjusted.
953932 */
....@@ -960,7 +939,6 @@
960939 if (err)
961940 goto out;
962941 }
963
- sk->sk_max_ack_backlog = backlog;
964942 err = 0;
965943
966944 out:
....@@ -982,7 +960,7 @@
982960 case DCCP_PARTOPEN:
983961 dccp_pr_debug("Stop PARTOPEN timer (%p)\n", sk);
984962 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
985
- /* fall through */
963
+ fallthrough;
986964 case DCCP_OPEN:
987965 dccp_send_close(sk, 1);
988966
....@@ -991,7 +969,7 @@
991969 next_state = DCCP_ACTIVE_CLOSEREQ;
992970 else
993971 next_state = DCCP_CLOSING;
994
- /* fall through */
972
+ fallthrough;
995973 default:
996974 dccp_set_state(sk, next_state);
997975 }
....@@ -1131,22 +1109,26 @@
11311109 static int __init dccp_init(void)
11321110 {
11331111 unsigned long goal;
1112
+ unsigned long nr_pages = totalram_pages();
11341113 int ehash_order, bhash_order, i;
11351114 int rc;
11361115
11371116 BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
1138
- FIELD_SIZEOF(struct sk_buff, cb));
1117
+ sizeof_field(struct sk_buff, cb));
11391118 rc = percpu_counter_init(&dccp_orphan_count, 0, GFP_KERNEL);
11401119 if (rc)
11411120 goto out_fail;
1142
- rc = -ENOBUFS;
11431121 inet_hashinfo_init(&dccp_hashinfo);
1122
+ rc = inet_hashinfo2_init_mod(&dccp_hashinfo);
1123
+ if (rc)
1124
+ goto out_free_percpu;
1125
+ rc = -ENOBUFS;
11441126 dccp_hashinfo.bind_bucket_cachep =
11451127 kmem_cache_create("dccp_bind_bucket",
11461128 sizeof(struct inet_bind_bucket), 0,
11471129 SLAB_HWCACHE_ALIGN, NULL);
11481130 if (!dccp_hashinfo.bind_bucket_cachep)
1149
- goto out_free_percpu;
1131
+ goto out_free_hashinfo2;
11501132
11511133 /*
11521134 * Size and allocate the main established and bind bucket
....@@ -1154,10 +1136,10 @@
11541136 *
11551137 * The methodology is similar to that of the buffer cache.
11561138 */
1157
- if (totalram_pages >= (128 * 1024))
1158
- goal = totalram_pages >> (21 - PAGE_SHIFT);
1139
+ if (nr_pages >= (128 * 1024))
1140
+ goal = nr_pages >> (21 - PAGE_SHIFT);
11591141 else
1160
- goal = totalram_pages >> (23 - PAGE_SHIFT);
1142
+ goal = nr_pages >> (23 - PAGE_SHIFT);
11611143
11621144 if (thash_entries)
11631145 goal = (thash_entries *
....@@ -1242,6 +1224,8 @@
12421224 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
12431225 out_free_bind_bucket_cachep:
12441226 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
1227
+out_free_hashinfo2:
1228
+ inet_hashinfo2_free_mod(&dccp_hashinfo);
12451229 out_free_percpu:
12461230 percpu_counter_destroy(&dccp_orphan_count);
12471231 out_fail:
....@@ -1265,6 +1249,7 @@
12651249 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
12661250 dccp_ackvec_exit();
12671251 dccp_sysctl_exit();
1252
+ inet_hashinfo2_free_mod(&dccp_hashinfo);
12681253 percpu_counter_destroy(&dccp_orphan_count);
12691254 }
12701255