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