hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
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;
....@@ -563,6 +559,9 @@
563559 }
564560
565561 ipcm_init_sk(&ipc, inet);
562
+ /* Keep backward compat */
563
+ if (hdrincl)
564
+ ipc.protocol = IPPROTO_RAW;
566565
567566 if (msg->msg_controllen) {
568567 err = ip_cmsg_send(sk, msg, &ipc, false);
....@@ -608,14 +607,14 @@
608607 tos |= RTO_ONLINK;
609608
610609 if (ipv4_is_multicast(daddr)) {
611
- if (!ipc.oif)
610
+ if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
612611 ipc.oif = inet->mc_index;
613612 if (!saddr)
614613 saddr = inet->mc_addr;
615614 } else if (!ipc.oif) {
616615 ipc.oif = inet->uc_index;
617616 } else if (ipv4_is_lbcast(daddr) && inet->uc_index) {
618
- /* oif is set, packet is to local broadcast and
617
+ /* oif is set, packet is to local broadcast
619618 * and uc_index is set. oif is most likely set
620619 * by sk_bound_dev_if. If uc_index != oif check if the
621620 * oif is an L3 master and uc_index is an L3 slave.
....@@ -628,9 +627,9 @@
628627 }
629628 }
630629
631
- flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
630
+ flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
632631 RT_SCOPE_UNIVERSE,
633
- hdrincl ? IPPROTO_RAW : sk->sk_protocol,
632
+ hdrincl ? ipc.protocol : sk->sk_protocol,
634633 inet_sk_flowi_flags(sk) |
635634 (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
636635 daddr, saddr, 0, 0, sk->sk_uid);
....@@ -644,7 +643,7 @@
644643 goto done;
645644 }
646645
647
- security_sk_classify_flow(sk, flowi4_to_flowi(&fl4));
646
+ security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
648647 rt = ip_route_output_flow(net, &fl4, sk);
649648 if (IS_ERR(rt)) {
650649 err = PTR_ERR(rt);
....@@ -808,7 +807,7 @@
808807 return copied;
809808 }
810809
811
-static int raw_init(struct sock *sk)
810
+static int raw_sk_init(struct sock *sk)
812811 {
813812 struct raw_sock *rp = raw_sk(sk);
814813
....@@ -817,11 +816,11 @@
817816 return 0;
818817 }
819818
820
-static int raw_seticmpfilter(struct sock *sk, char __user *optval, int optlen)
819
+static int raw_seticmpfilter(struct sock *sk, sockptr_t optval, int optlen)
821820 {
822821 if (optlen > sizeof(struct icmp_filter))
823822 optlen = sizeof(struct icmp_filter);
824
- if (copy_from_user(&raw_sk(sk)->filter, optval, optlen))
823
+ if (copy_from_sockptr(&raw_sk(sk)->filter, optval, optlen))
825824 return -EFAULT;
826825 return 0;
827826 }
....@@ -846,7 +845,7 @@
846845 }
847846
848847 static int do_raw_setsockopt(struct sock *sk, int level, int optname,
849
- char __user *optval, unsigned int optlen)
848
+ sockptr_t optval, unsigned int optlen)
850849 {
851850 if (optname == ICMP_FILTER) {
852851 if (inet_sk(sk)->inet_num != IPPROTO_ICMP)
....@@ -858,22 +857,12 @@
858857 }
859858
860859 static int raw_setsockopt(struct sock *sk, int level, int optname,
861
- char __user *optval, unsigned int optlen)
860
+ sockptr_t optval, unsigned int optlen)
862861 {
863862 if (level != SOL_RAW)
864863 return ip_setsockopt(sk, level, optname, optval, optlen);
865864 return do_raw_setsockopt(sk, level, optname, optval, optlen);
866865 }
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
877866
878867 static int do_raw_getsockopt(struct sock *sk, int level, int optname,
879868 char __user *optval, int __user *optlen)
....@@ -894,16 +883,6 @@
894883 return ip_getsockopt(sk, level, optname, optval, optlen);
895884 return do_raw_getsockopt(sk, level, optname, optval, optlen);
896885 }
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
907886
908887 static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
909888 {
....@@ -973,7 +952,7 @@
973952 .connect = ip4_datagram_connect,
974953 .disconnect = __udp_disconnect,
975954 .ioctl = raw_ioctl,
976
- .init = raw_init,
955
+ .init = raw_sk_init,
977956 .setsockopt = raw_setsockopt,
978957 .getsockopt = raw_getsockopt,
979958 .sendmsg = raw_sendmsg,
....@@ -988,8 +967,6 @@
988967 .usersize = sizeof_field(struct raw_sock, filter),
989968 .h.raw_hash = &raw_v4_hashinfo,
990969 #ifdef CONFIG_COMPAT
991
- .compat_setsockopt = compat_raw_setsockopt,
992
- .compat_getsockopt = compat_raw_getsockopt,
993970 .compat_ioctl = compat_raw_ioctl,
994971 #endif
995972 .diag_destroy = raw_abort,
....@@ -1042,6 +1019,7 @@
10421019 }
10431020
10441021 void *raw_seq_start(struct seq_file *seq, loff_t *pos)
1022
+ __acquires(&h->lock)
10451023 {
10461024 struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
10471025
....@@ -1064,6 +1042,7 @@
10641042 EXPORT_SYMBOL_GPL(raw_seq_next);
10651043
10661044 void raw_seq_stop(struct seq_file *seq, void *v)
1045
+ __releases(&h->lock)
10671046 {
10681047 struct raw_hashinfo *h = PDE_DATA(file_inode(seq->file));
10691048
....@@ -1080,7 +1059,7 @@
10801059 srcp = inet->inet_num;
10811060
10821061 seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
1083
- " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d\n",
1062
+ " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u\n",
10841063 i, src, srcp, dest, destp, sp->sk_state,
10851064 sk_wmem_alloc_get(sp),
10861065 sk_rmem_alloc_get(sp),
....@@ -1137,3 +1116,27 @@
11371116 unregister_pernet_subsys(&raw_net_ops);
11381117 }
11391118 #endif /* CONFIG_PROC_FS */
1119
+
1120
+static void raw_sysctl_init_net(struct net *net)
1121
+{
1122
+#ifdef CONFIG_NET_L3_MASTER_DEV
1123
+ net->ipv4.sysctl_raw_l3mdev_accept = 1;
1124
+#endif
1125
+}
1126
+
1127
+static int __net_init raw_sysctl_init(struct net *net)
1128
+{
1129
+ raw_sysctl_init_net(net);
1130
+ return 0;
1131
+}
1132
+
1133
+static struct pernet_operations __net_initdata raw_sysctl_ops = {
1134
+ .init = raw_sysctl_init,
1135
+};
1136
+
1137
+void __init raw_init(void)
1138
+{
1139
+ raw_sysctl_init_net(&init_net);
1140
+ if (register_pernet_subsys(&raw_sysctl_ops))
1141
+ panic("RAW: failed to init sysctl parameters.\n");
1142
+}