| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * DCCP over IPv6 |
|---|
| 3 | 4 | * Linux INET6 implementation |
|---|
| .. | .. |
|---|
| 5 | 6 | * Based on net/dccp6/ipv6.c |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License |
|---|
| 11 | | - * as published by the Free Software Foundation; either version |
|---|
| 12 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 68 | 64 | |
|---|
| 69 | 65 | } |
|---|
| 70 | 66 | |
|---|
| 71 | | -static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
|---|
| 67 | +static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
|---|
| 72 | 68 | u8 type, u8 code, int offset, __be32 info) |
|---|
| 73 | 69 | { |
|---|
| 74 | 70 | const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; |
|---|
| .. | .. |
|---|
| 96 | 92 | if (!sk) { |
|---|
| 97 | 93 | __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), |
|---|
| 98 | 94 | ICMP6_MIB_INERRORS); |
|---|
| 99 | | - return; |
|---|
| 95 | + return -ENOENT; |
|---|
| 100 | 96 | } |
|---|
| 101 | 97 | |
|---|
| 102 | 98 | if (sk->sk_state == DCCP_TIME_WAIT) { |
|---|
| 103 | 99 | inet_twsk_put(inet_twsk(sk)); |
|---|
| 104 | | - return; |
|---|
| 100 | + return 0; |
|---|
| 105 | 101 | } |
|---|
| 106 | 102 | seq = dccp_hdr_seq(dh); |
|---|
| 107 | | - if (sk->sk_state == DCCP_NEW_SYN_RECV) |
|---|
| 108 | | - return dccp_req_err(sk, seq); |
|---|
| 103 | + if (sk->sk_state == DCCP_NEW_SYN_RECV) { |
|---|
| 104 | + dccp_req_err(sk, seq); |
|---|
| 105 | + return 0; |
|---|
| 106 | + } |
|---|
| 109 | 107 | |
|---|
| 110 | 108 | bh_lock_sock(sk); |
|---|
| 111 | 109 | if (sock_owned_by_user(sk)) |
|---|
| .. | .. |
|---|
| 183 | 181 | out: |
|---|
| 184 | 182 | bh_unlock_sock(sk); |
|---|
| 185 | 183 | sock_put(sk); |
|---|
| 184 | + return 0; |
|---|
| 186 | 185 | } |
|---|
| 187 | 186 | |
|---|
| 188 | 187 | |
|---|
| .. | .. |
|---|
| 204 | 203 | fl6.flowi6_oif = ireq->ir_iif; |
|---|
| 205 | 204 | fl6.fl6_dport = ireq->ir_rmt_port; |
|---|
| 206 | 205 | fl6.fl6_sport = htons(ireq->ir_num); |
|---|
| 207 | | - security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
|---|
| 206 | + security_req_classify_flow(req, flowi6_to_flowi_common(&fl6)); |
|---|
| 208 | 207 | |
|---|
| 209 | 208 | |
|---|
| 210 | 209 | rcu_read_lock(); |
|---|
| .. | .. |
|---|
| 231 | 230 | opt = ireq->ipv6_opt; |
|---|
| 232 | 231 | if (!opt) |
|---|
| 233 | 232 | opt = rcu_dereference(np->opt); |
|---|
| 234 | | - err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass); |
|---|
| 233 | + err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass, |
|---|
| 234 | + sk->sk_priority); |
|---|
| 235 | 235 | rcu_read_unlock(); |
|---|
| 236 | 236 | err = net_xmit_eval(err); |
|---|
| 237 | 237 | } |
|---|
| .. | .. |
|---|
| 279 | 279 | fl6.flowi6_oif = inet6_iif(rxskb); |
|---|
| 280 | 280 | fl6.fl6_dport = dccp_hdr(skb)->dccph_dport; |
|---|
| 281 | 281 | fl6.fl6_sport = dccp_hdr(skb)->dccph_sport; |
|---|
| 282 | | - security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6)); |
|---|
| 282 | + security_skb_classify_flow(rxskb, flowi6_to_flowi_common(&fl6)); |
|---|
| 283 | 283 | |
|---|
| 284 | 284 | /* sk = NULL, but it is safe for now. RST socket required. */ |
|---|
| 285 | 285 | dst = ip6_dst_lookup_flow(sock_net(ctl_sk), ctl_sk, &fl6, NULL); |
|---|
| 286 | 286 | if (!IS_ERR(dst)) { |
|---|
| 287 | 287 | skb_dst_set(skb, dst); |
|---|
| 288 | | - ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0); |
|---|
| 288 | + ip6_xmit(ctl_sk, skb, &fl6, 0, NULL, 0, 0); |
|---|
| 289 | 289 | DCCP_INC_STATS(DCCP_MIB_OUTSEGS); |
|---|
| 290 | 290 | DCCP_INC_STATS(DCCP_MIB_OUTRSTS); |
|---|
| 291 | 291 | return; |
|---|
| .. | .. |
|---|
| 538 | 538 | dccp_done(newsk); |
|---|
| 539 | 539 | goto out; |
|---|
| 540 | 540 | } |
|---|
| 541 | | - *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); |
|---|
| 541 | + *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash), NULL); |
|---|
| 542 | 542 | /* Clone pktoptions received with SYN, if we own the req */ |
|---|
| 543 | 543 | if (*own_req && ireq->pktopts) { |
|---|
| 544 | 544 | newnp->pktoptions = skb_clone(ireq->pktopts, GFP_ATOMIC); |
|---|
| .. | .. |
|---|
| 836 | 836 | if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) { |
|---|
| 837 | 837 | struct ip6_flowlabel *flowlabel; |
|---|
| 838 | 838 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
|---|
| 839 | | - if (flowlabel == NULL) |
|---|
| 839 | + if (IS_ERR(flowlabel)) |
|---|
| 840 | 840 | return -EINVAL; |
|---|
| 841 | 841 | fl6_sock_release(flowlabel); |
|---|
| 842 | 842 | } |
|---|
| .. | .. |
|---|
| 912 | 912 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
|---|
| 913 | 913 | fl6.fl6_dport = usin->sin6_port; |
|---|
| 914 | 914 | fl6.fl6_sport = inet->inet_sport; |
|---|
| 915 | | - security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
|---|
| 915 | + security_sk_classify_flow(sk, flowi6_to_flowi_common(&fl6)); |
|---|
| 916 | 916 | |
|---|
| 917 | 917 | opt = rcu_dereference_protected(np->opt, lockdep_sock_is_held(sk)); |
|---|
| 918 | 918 | final_p = fl6_update_dst(&fl6, opt, &final); |
|---|
| .. | .. |
|---|
| 957 | 957 | |
|---|
| 958 | 958 | late_failure: |
|---|
| 959 | 959 | dccp_set_state(sk, DCCP_CLOSED); |
|---|
| 960 | + if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) |
|---|
| 961 | + inet_reset_saddr(sk); |
|---|
| 960 | 962 | __sk_dst_reset(sk); |
|---|
| 961 | 963 | failure: |
|---|
| 962 | 964 | inet->inet_dport = 0; |
|---|
| .. | .. |
|---|
| 975 | 977 | .getsockopt = ipv6_getsockopt, |
|---|
| 976 | 978 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
|---|
| 977 | 979 | .sockaddr_len = sizeof(struct sockaddr_in6), |
|---|
| 978 | | -#ifdef CONFIG_COMPAT |
|---|
| 979 | | - .compat_setsockopt = compat_ipv6_setsockopt, |
|---|
| 980 | | - .compat_getsockopt = compat_ipv6_getsockopt, |
|---|
| 981 | | -#endif |
|---|
| 982 | 980 | }; |
|---|
| 983 | 981 | |
|---|
| 984 | 982 | /* |
|---|
| .. | .. |
|---|
| 995 | 993 | .getsockopt = ipv6_getsockopt, |
|---|
| 996 | 994 | .addr2sockaddr = inet6_csk_addr2sockaddr, |
|---|
| 997 | 995 | .sockaddr_len = sizeof(struct sockaddr_in6), |
|---|
| 998 | | -#ifdef CONFIG_COMPAT |
|---|
| 999 | | - .compat_setsockopt = compat_ipv6_setsockopt, |
|---|
| 1000 | | - .compat_getsockopt = compat_ipv6_getsockopt, |
|---|
| 1001 | | -#endif |
|---|
| 1002 | 996 | }; |
|---|
| 1003 | 997 | |
|---|
| 1004 | 998 | /* NOTE: A lot of things set to zero explicitly by call to |
|---|
| .. | .. |
|---|
| 1054 | 1048 | .rsk_prot = &dccp6_request_sock_ops, |
|---|
| 1055 | 1049 | .twsk_prot = &dccp6_timewait_sock_ops, |
|---|
| 1056 | 1050 | .h.hashinfo = &dccp_hashinfo, |
|---|
| 1057 | | -#ifdef CONFIG_COMPAT |
|---|
| 1058 | | - .compat_setsockopt = compat_dccp_setsockopt, |
|---|
| 1059 | | - .compat_getsockopt = compat_dccp_getsockopt, |
|---|
| 1060 | | -#endif |
|---|
| 1061 | 1051 | }; |
|---|
| 1062 | 1052 | |
|---|
| 1063 | 1053 | static const struct inet6_protocol dccp_v6_protocol = { |
|---|
| .. | .. |
|---|
| 1077 | 1067 | .getname = inet6_getname, |
|---|
| 1078 | 1068 | .poll = dccp_poll, |
|---|
| 1079 | 1069 | .ioctl = inet6_ioctl, |
|---|
| 1070 | + .gettstamp = sock_gettstamp, |
|---|
| 1080 | 1071 | .listen = inet_dccp_listen, |
|---|
| 1081 | 1072 | .shutdown = inet_shutdown, |
|---|
| 1082 | 1073 | .setsockopt = sock_common_setsockopt, |
|---|
| .. | .. |
|---|
| 1086 | 1077 | .mmap = sock_no_mmap, |
|---|
| 1087 | 1078 | .sendpage = sock_no_sendpage, |
|---|
| 1088 | 1079 | #ifdef CONFIG_COMPAT |
|---|
| 1089 | | - .compat_setsockopt = compat_sock_common_setsockopt, |
|---|
| 1090 | | - .compat_getsockopt = compat_sock_common_getsockopt, |
|---|
| 1080 | + .compat_ioctl = inet6_compat_ioctl, |
|---|
| 1091 | 1081 | #endif |
|---|
| 1092 | 1082 | }; |
|---|
| 1093 | 1083 | |
|---|