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 */
|