^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) * Authors: Lotsa people, from code originally in tcp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifndef _INET6_HASHTABLES_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define _INET6_HASHTABLES_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #if IS_ENABLED(CONFIG_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <net/inet_sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <net/netns/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct inet_hashinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static inline unsigned int __inet6_ehashfn(const u32 lhash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const u16 lport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) const u32 fhash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) const __be16 fport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const u32 initval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) const u32 ports = (((u32)lport) << 16) | (__force u32)fport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return jhash_3words(lhash, fhash, ports, initval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The sockhash lock must be held as a reader here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct sock *__inet6_lookup_established(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct inet_hashinfo *hashinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const struct in6_addr *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) const __be16 sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) const u16 hnum, const int dif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) const int sdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct sock *inet6_lookup_listener(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct inet_hashinfo *hashinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct sk_buff *skb, int doff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) const struct in6_addr *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const __be16 sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const unsigned short hnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) const int dif, const int sdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static inline struct sock *__inet6_lookup(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct inet_hashinfo *hashinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct sk_buff *skb, int doff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) const struct in6_addr *saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const __be16 sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const u16 hnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const int dif, const int sdif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) bool *refcounted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct sock *sk = __inet6_lookup_established(net, hashinfo, saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) sport, daddr, hnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) dif, sdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *refcounted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *refcounted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return inet6_lookup_listener(net, hashinfo, skb, doff, saddr, sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) daddr, hnum, dif, sdif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct sk_buff *skb, int doff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const __be16 sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const __be16 dport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int iif, int sdif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) bool *refcounted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct sock *sk = skb_steal_sock(skb, refcounted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo, skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) doff, &ipv6_hdr(skb)->saddr, sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) &ipv6_hdr(skb)->daddr, ntohs(dport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) iif, sdif, refcounted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct sock *inet6_lookup(struct net *net, struct inet_hashinfo *hashinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sk_buff *skb, int doff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) const struct in6_addr *saddr, const __be16 sport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const struct in6_addr *daddr, const __be16 dport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const int dif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int inet6_hash(struct sock *sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif /* IS_ENABLED(CONFIG_IPV6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) (((__sk)->sk_portpair == (__ports)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ((__sk)->sk_family == AF_INET6) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ipv6_addr_equal(&(__sk)->sk_v6_daddr, (__saddr)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ipv6_addr_equal(&(__sk)->sk_v6_rcv_saddr, (__daddr)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) (((__sk)->sk_bound_dev_if == (__dif)) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ((__sk)->sk_bound_dev_if == (__sdif))) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) net_eq(sock_net(__sk), (__net)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif /* _INET6_HASHTABLES_H */