^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INET An implementation of the TCP/IP protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * operating system. INET is implemented using the BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Support for INET6 connection oriented protocols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Authors: See the TCPv6 sources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <net/addrconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <net/inet_connection_sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/inet_ecn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/inet_hashtables.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/ip6_route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/inet6_connection_sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <net/sock_reuseport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct dst_entry *inet6_csk_route_req(const struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct flowi6 *fl6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const struct request_sock *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u8 proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct inet_request_sock *ireq = inet_rsk(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) const struct ipv6_pinfo *np = inet6_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct in6_addr *final_p, final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) memset(fl6, 0, sizeof(*fl6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) fl6->flowi6_proto = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) fl6->daddr = ireq->ir_v6_rmt_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) fl6->saddr = ireq->ir_v6_loc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) fl6->flowi6_oif = ireq->ir_iif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) fl6->flowi6_mark = ireq->ir_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) fl6->fl6_dport = ireq->ir_rmt_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) fl6->fl6_sport = htons(ireq->ir_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) fl6->flowi6_uid = sk->sk_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) security_req_classify_flow(req, flowi6_to_flowi(fl6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (IS_ERR(dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) EXPORT_SYMBOL(inet6_csk_route_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) sin6->sin6_family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) sin6->sin6_addr = sk->sk_v6_daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) sin6->sin6_port = inet_sk(sk)->inet_dport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* We do not store received flowlabel for TCP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) sin6->sin6_flowinfo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) sk->sk_bound_dev_if);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return __sk_dst_check(sk, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct flowi6 *fl6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct inet_sock *inet = inet_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct ipv6_pinfo *np = inet6_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct in6_addr *final_p, final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) memset(fl6, 0, sizeof(*fl6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) fl6->flowi6_proto = sk->sk_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) fl6->daddr = sk->sk_v6_daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) fl6->saddr = np->saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) fl6->flowlabel = np->flow_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) IP6_ECN_flow_xmit(sk, fl6->flowlabel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) fl6->flowi6_oif = sk->sk_bound_dev_if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) fl6->flowi6_mark = sk->sk_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) fl6->fl6_sport = inet->inet_sport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) fl6->fl6_dport = inet->inet_dport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) fl6->flowi6_uid = sk->sk_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dst = __inet6_csk_dst_check(sk, np->dst_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (!dst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!IS_ERR(dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ip6_dst_store(sk, dst, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct ipv6_pinfo *np = inet6_sk(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct flowi6 fl6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct dst_entry *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dst = inet6_csk_route_socket(sk, &fl6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (IS_ERR(dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) sk->sk_err_soft = -PTR_ERR(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) sk->sk_route_caps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return PTR_ERR(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) skb_dst_set_noref(skb, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Restore final destination back after routing done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) fl6.daddr = sk->sk_v6_daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) res = ip6_xmit(sk, skb, &fl6, sk->sk_mark, rcu_dereference(np->opt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) np->tclass, sk->sk_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) EXPORT_SYMBOL_GPL(inet6_csk_xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct flowi6 fl6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct dst_entry *dst = inet6_csk_route_socket(sk, &fl6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (IS_ERR(dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dst->ops->update_pmtu(dst, sk, NULL, mtu, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dst = inet6_csk_route_socket(sk, &fl6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return IS_ERR(dst) ? NULL : dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);