hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/ipv6/raw.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * RAW sockets for IPv6
34 * Linux INET6 implementation
....@@ -11,11 +12,6 @@
1112 * Hideaki YOSHIFUJI : sin6_scope_id support
1213 * YOSHIFUJI,H.@USAGI : raw checksum (RFC2292(bis) compliance)
1314 * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data
14
- *
15
- * This program is free software; you can redistribute it and/or
16
- * modify it under the terms of the GNU General Public License
17
- * as published by the Free Software Foundation; either version
18
- * 2 of the License, or (at your option) any later version.
1915 */
2016
2117 #include <linux/errno.h>
....@@ -86,9 +82,8 @@
8682 !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
8783 continue;
8884
89
- if (sk->sk_bound_dev_if &&
90
- sk->sk_bound_dev_if != dif &&
91
- sk->sk_bound_dev_if != sdif)
85
+ if (!raw_sk_bound_dev_eq(net, sk->sk_bound_dev_if,
86
+ dif, sdif))
9287 continue;
9388
9489 if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
....@@ -220,7 +215,7 @@
220215
221216 /* Not releasing hash table! */
222217 if (clone) {
223
- nf_reset(clone);
218
+ nf_reset_ct(clone);
224219 rawv6_rcv(sk, clone);
225220 }
226221 }
....@@ -651,7 +646,7 @@
651646
652647 skb->protocol = htons(ETH_P_IPV6);
653648 skb->priority = sk->sk_priority;
654
- skb->mark = sk->sk_mark;
649
+ skb->mark = sockc->mark;
655650 skb->tstamp = sockc->transmit_time;
656651
657652 skb_put(skb, length);
....@@ -660,7 +655,7 @@
660655
661656 skb->ip_summed = CHECKSUM_NONE;
662657
663
- sock_tx_timestamp(sk, sockc->tsflags, &skb_shinfo(skb)->tx_flags);
658
+ skb_setup_tx_timestamp(skb, sockc->tsflags);
664659
665660 if (flags & MSG_CONFIRM)
666661 skb_set_dst_pending_confirm(skb, 1);
....@@ -751,7 +746,7 @@
751746 skb->csum = csum_block_add(
752747 skb->csum,
753748 csum_partial_copy_nocheck(rfv->c + offset,
754
- to, copy, 0),
749
+ to, copy),
755750 odd);
756751
757752 odd = 0;
....@@ -815,6 +810,7 @@
815810
816811 ipcm6_init(&ipc6);
817812 ipc6.sockc.tsflags = sk->sk_tsflags;
813
+ ipc6.sockc.mark = sk->sk_mark;
818814
819815 if (sin6) {
820816 if (addr_len < SIN6_LEN_RFC2133)
....@@ -839,7 +835,7 @@
839835 fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
840836 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
841837 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
842
- if (!flowlabel)
838
+ if (IS_ERR(flowlabel))
843839 return -EINVAL;
844840 }
845841 }
....@@ -881,7 +877,7 @@
881877 }
882878 if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
883879 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
884
- if (!flowlabel)
880
+ if (IS_ERR(flowlabel))
885881 return -EINVAL;
886882 }
887883 if (!(opt->opt_nflen|opt->opt_flen))
....@@ -896,6 +892,7 @@
896892 opt = ipv6_fixup_options(&opt_space, opt);
897893
898894 fl6.flowi6_proto = proto;
895
+ fl6.flowi6_mark = ipc6.sockc.mark;
899896
900897 if (!hdrincl) {
901898 rfv.msg = msg;
....@@ -918,7 +915,7 @@
918915 fl6.flowi6_oif = np->mcast_oif;
919916 else if (!fl6.flowi6_oif)
920917 fl6.flowi6_oif = np->ucast_oif;
921
- security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
918
+ security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6));
922919
923920 if (hdrincl)
924921 fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH;
....@@ -975,13 +972,13 @@
975972 }
976973
977974 static int rawv6_seticmpfilter(struct sock *sk, int level, int optname,
978
- char __user *optval, int optlen)
975
+ sockptr_t optval, int optlen)
979976 {
980977 switch (optname) {
981978 case ICMPV6_FILTER:
982979 if (optlen > sizeof(struct icmp6_filter))
983980 optlen = sizeof(struct icmp6_filter);
984
- if (copy_from_user(&raw6_sk(sk)->filter, optval, optlen))
981
+ if (copy_from_sockptr(&raw6_sk(sk)->filter, optval, optlen))
985982 return -EFAULT;
986983 return 0;
987984 default:
....@@ -1018,12 +1015,15 @@
10181015
10191016
10201017 static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
1021
- char __user *optval, unsigned int optlen)
1018
+ sockptr_t optval, unsigned int optlen)
10221019 {
10231020 struct raw6_sock *rp = raw6_sk(sk);
10241021 int val;
10251022
1026
- if (get_user(val, (int __user *)optval))
1023
+ if (optlen < sizeof(val))
1024
+ return -EINVAL;
1025
+
1026
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
10271027 return -EFAULT;
10281028
10291029 switch (optname) {
....@@ -1065,7 +1065,7 @@
10651065 }
10661066
10671067 static int rawv6_setsockopt(struct sock *sk, int level, int optname,
1068
- char __user *optval, unsigned int optlen)
1068
+ sockptr_t optval, unsigned int optlen)
10691069 {
10701070 switch (level) {
10711071 case SOL_RAW:
....@@ -1079,37 +1079,13 @@
10791079 if (optname == IPV6_CHECKSUM ||
10801080 optname == IPV6_HDRINCL)
10811081 break;
1082
- /* fall through */
1082
+ fallthrough;
10831083 default:
10841084 return ipv6_setsockopt(sk, level, optname, optval, optlen);
10851085 }
10861086
10871087 return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
10881088 }
1089
-
1090
-#ifdef CONFIG_COMPAT
1091
-static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
1092
- char __user *optval, unsigned int optlen)
1093
-{
1094
- switch (level) {
1095
- case SOL_RAW:
1096
- break;
1097
- case SOL_ICMPV6:
1098
- if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1099
- return -EOPNOTSUPP;
1100
- return rawv6_seticmpfilter(sk, level, optname, optval, optlen);
1101
- case SOL_IPV6:
1102
- if (optname == IPV6_CHECKSUM ||
1103
- optname == IPV6_HDRINCL)
1104
- break;
1105
- /* fall through */
1106
- default:
1107
- return compat_ipv6_setsockopt(sk, level, optname,
1108
- optval, optlen);
1109
- }
1110
- return do_rawv6_setsockopt(sk, level, optname, optval, optlen);
1111
-}
1112
-#endif
11131089
11141090 static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,
11151091 char __user *optval, int __user *optlen)
....@@ -1164,37 +1140,13 @@
11641140 if (optname == IPV6_CHECKSUM ||
11651141 optname == IPV6_HDRINCL)
11661142 break;
1167
- /* fall through */
1143
+ fallthrough;
11681144 default:
11691145 return ipv6_getsockopt(sk, level, optname, optval, optlen);
11701146 }
11711147
11721148 return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
11731149 }
1174
-
1175
-#ifdef CONFIG_COMPAT
1176
-static int compat_rawv6_getsockopt(struct sock *sk, int level, int optname,
1177
- char __user *optval, int __user *optlen)
1178
-{
1179
- switch (level) {
1180
- case SOL_RAW:
1181
- break;
1182
- case SOL_ICMPV6:
1183
- if (inet_sk(sk)->inet_num != IPPROTO_ICMPV6)
1184
- return -EOPNOTSUPP;
1185
- return rawv6_geticmpfilter(sk, level, optname, optval, optlen);
1186
- case SOL_IPV6:
1187
- if (optname == IPV6_CHECKSUM ||
1188
- optname == IPV6_HDRINCL)
1189
- break;
1190
- /* fall through */
1191
- default:
1192
- return compat_ipv6_getsockopt(sk, level, optname,
1193
- optval, optlen);
1194
- }
1195
- return do_rawv6_getsockopt(sk, level, optname, optval, optlen);
1196
-}
1197
-#endif
11981150
11991151 static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
12001152 {
....@@ -1300,8 +1252,6 @@
13001252 .usersize = sizeof_field(struct raw6_sock, filter),
13011253 .h.raw_hash = &raw_v6_hashinfo,
13021254 #ifdef CONFIG_COMPAT
1303
- .compat_setsockopt = compat_rawv6_setsockopt,
1304
- .compat_getsockopt = compat_rawv6_getsockopt,
13051255 .compat_ioctl = compat_rawv6_ioctl,
13061256 #endif
13071257 .diag_destroy = raw_abort,
....@@ -1370,6 +1320,7 @@
13701320 .getname = inet6_getname,
13711321 .poll = datagram_poll, /* ok */
13721322 .ioctl = inet6_ioctl, /* must change */
1323
+ .gettstamp = sock_gettstamp,
13731324 .listen = sock_no_listen, /* ok */
13741325 .shutdown = inet_shutdown, /* ok */
13751326 .setsockopt = sock_common_setsockopt, /* ok */
....@@ -1379,8 +1330,7 @@
13791330 .mmap = sock_no_mmap,
13801331 .sendpage = sock_no_sendpage,
13811332 #ifdef CONFIG_COMPAT
1382
- .compat_setsockopt = compat_sock_common_setsockopt,
1383
- .compat_getsockopt = compat_sock_common_getsockopt,
1333
+ .compat_ioctl = inet6_compat_ioctl,
13841334 #endif
13851335 };
13861336