1
2
3
4
5
6
7
8
9
10
11
12
13
14#ifndef _INET_HASHTABLES_H
15#define _INET_HASHTABLES_H
16
17
18#include <linux/interrupt.h>
19#include <linux/ip.h>
20#include <linux/ipv6.h>
21#include <linux/list.h>
22#include <linux/slab.h>
23#include <linux/socket.h>
24#include <linux/spinlock.h>
25#include <linux/types.h>
26#include <linux/wait.h>
27
28#include <net/inet_connection_sock.h>
29#include <net/inet_sock.h>
30#include <net/sock.h>
31#include <net/route.h>
32#include <net/tcp_states.h>
33#include <net/netns/hash.h>
34
35#include <linux/atomic.h>
36#include <asm/byteorder.h>
37
38
39
40
41
42struct inet_ehash_bucket {
43 struct hlist_nulls_head chain;
44};
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77struct inet_bind_bucket {
78 possible_net_t ib_net;
79 unsigned short port;
80 signed char fastreuse;
81 signed char fastreuseport;
82 kuid_t fastuid;
83 int num_owners;
84 struct hlist_node node;
85 struct hlist_head owners;
86};
87
88static inline struct net *ib_net(struct inet_bind_bucket *ib)
89{
90 return read_pnet(&ib->ib_net);
91}
92
93#define inet_bind_bucket_for_each(tb, head) \
94 hlist_for_each_entry(tb, head, node)
95
96struct inet_bind_hashbucket {
97 spinlock_t lock;
98 struct hlist_head chain;
99};
100
101
102
103
104
105
106
107#define LISTENING_NULLS_BASE (1U << 29)
108struct inet_listen_hashbucket {
109 spinlock_t lock;
110 struct hlist_nulls_head head;
111};
112
113
114#define INET_LHTABLE_SIZE 32
115
116struct inet_hashinfo {
117
118
119
120
121
122
123 struct inet_ehash_bucket *ehash;
124 spinlock_t *ehash_locks;
125 unsigned int ehash_mask;
126 unsigned int ehash_locks_mask;
127
128
129
130
131 struct inet_bind_hashbucket *bhash;
132
133 unsigned int bhash_size;
134
135
136 struct kmem_cache *bind_bucket_cachep;
137
138
139
140
141
142
143
144
145
146
147
148 struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE]
149 ____cacheline_aligned_in_smp;
150};
151
152static inline struct inet_ehash_bucket *inet_ehash_bucket(
153 struct inet_hashinfo *hashinfo,
154 unsigned int hash)
155{
156 return &hashinfo->ehash[hash & hashinfo->ehash_mask];
157}
158
159static inline spinlock_t *inet_ehash_lockp(
160 struct inet_hashinfo *hashinfo,
161 unsigned int hash)
162{
163 return &hashinfo->ehash_locks[hash & hashinfo->ehash_locks_mask];
164}
165
166int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo);
167
168static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
169{
170 kvfree(hashinfo->ehash_locks);
171 hashinfo->ehash_locks = NULL;
172}
173
174struct inet_bind_bucket *
175inet_bind_bucket_create(struct kmem_cache *cachep, struct net *net,
176 struct inet_bind_hashbucket *head,
177 const unsigned short snum);
178void inet_bind_bucket_destroy(struct kmem_cache *cachep,
179 struct inet_bind_bucket *tb);
180
181static inline u32 inet_bhashfn(const struct net *net, const __u16 lport,
182 const u32 bhash_size)
183{
184 return (lport + net_hash_mix(net)) & (bhash_size - 1);
185}
186
187void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
188 const unsigned short snum);
189
190
191static inline u32 inet_lhashfn(const struct net *net, const unsigned short num)
192{
193 return (num + net_hash_mix(net)) & (INET_LHTABLE_SIZE - 1);
194}
195
196static inline int inet_sk_listen_hashfn(const struct sock *sk)
197{
198 return inet_lhashfn(sock_net(sk), inet_sk(sk)->inet_num);
199}
200
201
202int __inet_inherit_port(struct sock *sk, struct sock *child);
203
204void inet_put_port(struct sock *sk);
205
206void inet_hashinfo_init(struct inet_hashinfo *h);
207
208void __inet_hash_nolisten(struct sock *sk, struct sock *osk);
209void __inet_hash(struct sock *sk, struct sock *osk);
210void inet_hash(struct sock *sk);
211void inet_unhash(struct sock *sk);
212
213struct sock *__inet_lookup_listener(struct net *net,
214 struct inet_hashinfo *hashinfo,
215 const __be32 saddr, const __be16 sport,
216 const __be32 daddr,
217 const unsigned short hnum,
218 const int dif);
219
220static inline struct sock *inet_lookup_listener(struct net *net,
221 struct inet_hashinfo *hashinfo,
222 __be32 saddr, __be16 sport,
223 __be32 daddr, __be16 dport, int dif)
224{
225 return __inet_lookup_listener(net, hashinfo, saddr, sport,
226 daddr, ntohs(dport), dif);
227}
228
229
230
231
232
233
234
235
236
237
238#ifdef __BIG_ENDIAN
239#define INET_COMBINED_PORTS(__sport, __dport) \
240 ((__force __portpair)(((__force __u32)(__be16)(__sport) << 16) | (__u32)(__dport)))
241#else
242#define INET_COMBINED_PORTS(__sport, __dport) \
243 ((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
244#endif
245
246#if (BITS_PER_LONG == 64)
247#ifdef __BIG_ENDIAN
248#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
249 const __addrpair __name = (__force __addrpair) ( \
250 (((__force __u64)(__be32)(__saddr)) << 32) | \
251 ((__force __u64)(__be32)(__daddr)))
252#else
253#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
254 const __addrpair __name = (__force __addrpair) ( \
255 (((__force __u64)(__be32)(__daddr)) << 32) | \
256 ((__force __u64)(__be32)(__saddr)))
257#endif
258#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
259 (((__sk)->sk_portpair == (__ports)) && \
260 ((__sk)->sk_addrpair == (__cookie)) && \
261 (!(__sk)->sk_bound_dev_if || \
262 ((__sk)->sk_bound_dev_if == (__dif))) && \
263 net_eq(sock_net(__sk), (__net)))
264#else
265#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
266 const int __name __deprecated __attribute__((unused))
267
268#define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \
269 (((__sk)->sk_portpair == (__ports)) && \
270 ((__sk)->sk_daddr == (__saddr)) && \
271 ((__sk)->sk_rcv_saddr == (__daddr)) && \
272 (!(__sk)->sk_bound_dev_if || \
273 ((__sk)->sk_bound_dev_if == (__dif))) && \
274 net_eq(sock_net(__sk), (__net)))
275#endif
276
277
278
279
280
281
282
283struct sock *__inet_lookup_established(struct net *net,
284 struct inet_hashinfo *hashinfo,
285 const __be32 saddr, const __be16 sport,
286 const __be32 daddr, const u16 hnum,
287 const int dif);
288
289static inline struct sock *
290 inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
291 const __be32 saddr, const __be16 sport,
292 const __be32 daddr, const __be16 dport,
293 const int dif)
294{
295 return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
296 ntohs(dport), dif);
297}
298
299static inline struct sock *__inet_lookup(struct net *net,
300 struct inet_hashinfo *hashinfo,
301 const __be32 saddr, const __be16 sport,
302 const __be32 daddr, const __be16 dport,
303 const int dif)
304{
305 u16 hnum = ntohs(dport);
306 struct sock *sk = __inet_lookup_established(net, hashinfo,
307 saddr, sport, daddr, hnum, dif);
308
309 return sk ? : __inet_lookup_listener(net, hashinfo, saddr, sport,
310 daddr, hnum, dif);
311}
312
313static inline struct sock *inet_lookup(struct net *net,
314 struct inet_hashinfo *hashinfo,
315 const __be32 saddr, const __be16 sport,
316 const __be32 daddr, const __be16 dport,
317 const int dif)
318{
319 struct sock *sk;
320
321 local_bh_disable();
322 sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
323 local_bh_enable();
324
325 return sk;
326}
327
328static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
329 struct sk_buff *skb,
330 const __be16 sport,
331 const __be16 dport)
332{
333 struct sock *sk = skb_steal_sock(skb);
334 const struct iphdr *iph = ip_hdr(skb);
335
336 if (sk)
337 return sk;
338 else
339 return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
340 iph->saddr, sport,
341 iph->daddr, dport, inet_iif(skb));
342}
343
344u32 sk_ehashfn(const struct sock *sk);
345u32 inet6_ehashfn(const struct net *net,
346 const struct in6_addr *laddr, const u16 lport,
347 const struct in6_addr *faddr, const __be16 fport);
348
349static inline void sk_daddr_set(struct sock *sk, __be32 addr)
350{
351 sk->sk_daddr = addr;
352#if IS_ENABLED(CONFIG_IPV6)
353 ipv6_addr_set_v4mapped(addr, &sk->sk_v6_daddr);
354#endif
355}
356
357static inline void sk_rcv_saddr_set(struct sock *sk, __be32 addr)
358{
359 sk->sk_rcv_saddr = addr;
360#if IS_ENABLED(CONFIG_IPV6)
361 ipv6_addr_set_v4mapped(addr, &sk->sk_v6_rcv_saddr);
362#endif
363}
364
365int __inet_hash_connect(struct inet_timewait_death_row *death_row,
366 struct sock *sk, u32 port_offset,
367 int (*check_established)(struct inet_timewait_death_row *,
368 struct sock *, __u16,
369 struct inet_timewait_sock **));
370
371int inet_hash_connect(struct inet_timewait_death_row *death_row,
372 struct sock *sk);
373#endif
374