forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/net/ipv4/raw.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * INET An implementation of the TCP/IP protocol suite for the LINUX
34 * operating system. INET is implemented using the BSD Socket
....@@ -30,11 +31,6 @@
3031 * Alan Cox : Added IP_HDRINCL option.
3132 * Alan Cox : Skip broadcast check if BSDism set.
3233 * David S. Miller : New socket lookup architecture.
33
- *
34
- * This program is free software; you can redistribute it and/or
35
- * modify it under the terms of the GNU General Public License
36
- * as published by the Free Software Foundation; either version
37
- * 2 of the License, or (at your option) any later version.
3834 */
3935
4036 #include <linux/types.h>
....@@ -131,8 +127,7 @@
131127 if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
132128 !(inet->inet_daddr && inet->inet_daddr != raddr) &&
133129 !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
134
- !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
135
- sk->sk_bound_dev_if != sdif))
130
+ raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif))
136131 goto found; /* gotcha */
137132 }
138133 sk = NULL;
....@@ -265,11 +260,12 @@
265260 err = EHOSTUNREACH;
266261 if (code > NR_ICMP_UNREACH)
267262 break;
268
- err = icmp_err_convert[code].errno;
269
- harderr = icmp_err_convert[code].fatal;
270263 if (code == ICMP_FRAG_NEEDED) {
271264 harderr = inet->pmtudisc != IP_PMTUDISC_DONT;
272265 err = EMSGSIZE;
266
+ } else {
267
+ err = icmp_err_convert[code].errno;
268
+ harderr = icmp_err_convert[code].fatal;
273269 }
274270 }
275271
....@@ -337,7 +333,7 @@
337333 kfree_skb(skb);
338334 return NET_RX_DROP;
339335 }
340
- nf_reset(skb);
336
+ nf_reset_ct(skb);
341337
342338 skb_push(skb, skb->data - skb_network_header(skb));
343339
....@@ -380,7 +376,7 @@
380376 skb_reserve(skb, hlen);
381377
382378 skb->priority = sk->sk_priority;
383
- skb->mark = sk->sk_mark;
379
+ skb->mark = sockc->mark;
384380 skb->tstamp = sockc->transmit_time;
385381 skb_dst_set(skb, &rt->dst);
386382 *rtp = NULL;
....@@ -391,7 +387,7 @@
391387
392388 skb->ip_summed = CHECKSUM_NONE;
393389
394
- sock_tx_timestamp(sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags);
390
+ skb_setup_tx_timestamp(skb, sockc->tsflags);
395391
396392 if (flags & MSG_CONFIRM)
397393 skb_set_dst_pending_confirm(skb, 1);
....@@ -483,7 +479,7 @@
483479 skb->csum = csum_block_add(
484480 skb->csum,
485481 csum_partial_copy_nocheck(rfv->hdr.c + offset,
486
- to, copy, 0),
482
+ to, copy),
487483 odd);
488484
489485 odd = 0;
....@@ -608,14 +604,14 @@
608604 tos |= RTO_ONLINK;
609605
610606 if (ipv4_is_multicast(daddr)) {
611
- if (!ipc.oif)
607
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
612608 ipc.oif = inet->mc_index;
613609 if (!saddr)
614610 saddr = inet->mc_addr;
615611 } else if (!ipc.oif) {
616612 ipc.oif = inet->uc_index;
617613 } else if (ipv4_is_lbcast(daddr) && inet->uc_index) {
618
- /* oif is set, packet is to local broadcast and
614
+ /* oif is set, packet is to local broadcast
619615 * and uc_index is set. oif is most likely set
620616 * by sk_bound_dev_if. If uc_index != oif check if the
621617 * oif is an L3 master and uc_index is an L3 slave.
....@@ -628,7 +624,7 @@
628624 }
629625 }
630626
631
- flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
627
+ flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
632628 RT_SCOPE_UNIVERSE,
633629 hdrincl ? IPPROTO_RAW : sk->sk_protocol,
634630 inet_sk_flowi_flags(sk) |
....@@ -644,7 +640,7 @@
644640 goto done;
645641 }
646642
647
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
643
+ security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
648644 rt = ip_route_output_flow(net, &fl4, sk);
649645 if (IS_ERR(rt)) {
650646 err = PTR_ERR(rt);
....@@ -808,7 +804,7 @@
808804 return copied;
809805 }
810806
811
-static int raw_init(struct sock *sk)
807
+static int raw_sk_init(struct sock *sk)
812808 {
813809 struct raw_sock *rp = raw_sk(sk);
814810
....@@ -817,11 +813,11 @@
817813 return 0;
818814 }
819815
820
-static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen)
816
+static int raw_seticmpfilter(struct sock *sk, sockptr_t optval, int optlen)
821817 {
822818 if (optlen > sizeof(struct icmp_filter))
823819 optlen = sizeof(struct icmp_filter);
824
- if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
820
+ if (copy_from_sockptr(&raw_sk(sk)->filter, optval, optlen))
825821 return -EFAULT;
826822 return 0;
827823 }
....@@ -846,7 +842,7 @@
846842 }
847843
848844 static int do_raw_setsockopt(struct sock *sk, int level, int optname,
849
- char __user *optval, unsigned int optlen)
845
+ sockptr_t optval, unsigned int optlen)
850846 {
851847 if (optname == ICMP_FILTER) {
852848 if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
....@@ -858,22 +854,12 @@
858854 }
859855
860856 static int raw_setsockopt(struct sock *sk, int level, int optname,
861
- char __user *optval, unsigned int optlen)
857
+ sockptr_t optval, unsigned int optlen)
862858 {
863859 if (level != SOL_RAW)
864860 return ip_setsockopt(sk, level, optname, optval, optlen);
865861 return do_raw_setsockopt(sk, level, optname, optval, optlen);
866862 }
867
-
868
-#ifdef CONFIG_COMPAT
869
-static int compat_raw_setsockopt(struct sock *sk, int level, int optname,
870
- char __user *optval, unsigned int optlen)
871
-{
872
- if (level != SOL_RAW)
873
- return compat_ip_setsockopt(sk, level, optname, optval, optlen);
874
- return do_raw_setsockopt(sk, level, optname, optval, optlen);
875
-}
876
-#endif
877863
878864 static int do_raw_getsockopt(struct sock *sk, int level, int optname,
879865 char __user *optval, int __user *optlen)
....@@ -894,16 +880,6 @@
894880 return ip_getsockopt(sk, level, optname, optval, optlen);
895881 return do_raw_getsockopt(sk, level, optname, optval, optlen);
896882 }
897
-
898
-#ifdef CONFIG_COMPAT
899
-static int compat_raw_getsockopt(struct sock *sk, int level, int optname,
900
- char __user *optval, int __user *optlen)
901
-{
902
- if (level != SOL_RAW)
903
- return compat_ip_getsockopt(sk, level, optname, optval, optlen);
904
- return do_raw_getsockopt(sk, level, optname, optval, optlen);
905
-}
906
-#endif
907883
908884 static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
909885 {
....@@ -973,7 +949,7 @@
973949 .connect = ip4_datagram_connect,
974950 .disconnect = __udp_disconnect,
975951 .ioctl = raw_ioctl,
976
- .init = raw_init,
952
+ .init = raw_sk_init,
977953 .setsockopt = raw_setsockopt,
978954 .getsockopt = raw_getsockopt,
979955 .sendmsg = raw_sendmsg,
....@@ -988,8 +964,6 @@
988964 .usersize = sizeof_field(struct raw_sock, filter),
989965 .h.raw_hash = &raw_v4_hashinfo,
990966 #ifdef CONFIG_COMPAT
991
- .compat_setsockopt = compat_raw_setsockopt,
992
- .compat_getsockopt = compat_raw_getsockopt,
993967 .compat_ioctl = compat_raw_ioctl,
994968 #endif
995969 .diag_destroy = raw_abort,
....@@ -1042,6 +1016,7 @@
10421016 }
10431017
10441018 void *raw_seq_start(struct seq_file *seq, loff_t *pos)
1019
+ __acquires(&h->lock)
10451020 {
10461021 struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
10471022
....@@ -1064,6 +1039,7 @@
10641039 EXPORT_SYMBOL_GPL(raw_seq_next);
10651040
10661041 void raw_seq_stop(struct seq_file *seq, void *v)
1042
+ __releases(&h->lock)
10671043 {
10681044 struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
10691045
....@@ -1080,7 +1056,7 @@
10801056 srcp = inet->inet_num;
10811057
10821058 seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
1083
- " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d\n",
1059
+ " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u\n",
10841060 i, src, srcp, dest, destp, sp->sk_state,
10851061 sk_wmem_alloc_get(sp),
10861062 sk_rmem_alloc_get(sp),
....@@ -1137,3 +1113,27 @@
11371113 unregister_pernet_subsys(&raw_net_ops);
11381114 }
11391115 #endif /* CONFIG_PROC_FS */
1116
+
1117
+static void raw_sysctl_init_net(struct net *net)
1118
+{
1119
+#ifdef CONFIG_NET_L3_MASTER_DEV
1120
+ net->ipv4.sysctl_raw_l3mdev_accept = 1;
1121
+#endif
1122
+}
1123
+
1124
+static int __net_init raw_sysctl_init(struct net *net)
1125
+{
1126
+ raw_sysctl_init_net(net);
1127
+ return 0;
1128
+}
1129
+
1130
+static struct pernet_operations __net_initdata raw_sysctl_ops = {
1131
+ .init = raw_sysctl_init,
1132
+};
1133
+
1134
+void __init raw_init(void)
1135
+{
1136
+ raw_sysctl_init_net(&init_net);
1137
+ if (register_pernet_subsys(&raw_sysctl_ops))
1138
+ panic("RAW: failed to init sysctl parameters.\n");
1139
+}