Blame view

include/net/inet_hashtables.h 13.3 KB
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the BSD Socket
   *		interface as the means of communication with the user level.
   *
   * Authors:	Lotsa people, from code originally in tcp
   *
   *	This program is free software; you can redistribute it and/or
   *      modify it under the terms of the GNU General Public License
   *      as published by the Free Software Foundation; either version
   *      2 of the License, or (at your option) any later version.
   */
  
  #ifndef _INET_HASHTABLES_H
  #define _INET_HASHTABLES_H
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
16

2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
17
  #include <linux/interrupt.h>
9a1f27c48   Arnaldo Carvalho de Melo   inet_hashtables: ...
18
  #include <linux/ip.h>
33b622319   Arnaldo Carvalho de Melo   [INET]: Generalis...
19
  #include <linux/ipv6.h>
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
20
21
  #include <linux/list.h>
  #include <linux/slab.h>
33b622319   Arnaldo Carvalho de Melo   [INET]: Generalis...
22
  #include <linux/socket.h>
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
23
  #include <linux/spinlock.h>
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
24
  #include <linux/types.h>
f3f05f704   Arnaldo Carvalho de Melo   [INET]: Generalis...
25
  #include <linux/wait.h>
9e4505c45   Eric Dumazet   [INET]: Add a mis...
26
  #include <linux/vmalloc.h>
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
27

463c84b97   Arnaldo Carvalho de Melo   [NET]: Introduce ...
28
  #include <net/inet_connection_sock.h>
14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
29
  #include <net/inet_sock.h>
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
30
  #include <net/sock.h>
9a1f27c48   Arnaldo Carvalho de Melo   inet_hashtables: ...
31
  #include <net/route.h>
c752f0739   Arnaldo Carvalho de Melo   [TCP]: Move the t...
32
  #include <net/tcp_states.h>
0b4419162   Pavel Emelyanov   netns: introduce ...
33
  #include <net/netns/hash.h>
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
34

60063497a   Arun Sharma   atomic: use <linu...
35
  #include <linux/atomic.h>
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
36
  #include <asm/byteorder.h>
f3f05f704   Arnaldo Carvalho de Melo   [INET]: Generalis...
37

77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
38
  /* This is for all connections with a full identity, no wildcards.
dbca9b275   Eric Dumazet   [NET]: change lay...
39
40
   * One chain is dedicated to TIME_WAIT sockets.
   * I'll experiment with dynamic table growth later.
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
41
42
   */
  struct inet_ehash_bucket {
3ab5aee7f   Eric Dumazet   net: Convert TCP ...
43
44
  	struct hlist_nulls_head chain;
  	struct hlist_nulls_head twchain;
6d2553612   Eric Dumazet   [INET]: Shrink st...
45
  };
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
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
77
78
  
  /* There are a few simple rules, which allow for local port reuse by
   * an application.  In essence:
   *
   *	1) Sockets bound to different interfaces may share a local port.
   *	   Failing that, goto test 2.
   *	2) If all sockets have sk->sk_reuse set, and none of them are in
   *	   TCP_LISTEN state, the port may be shared.
   *	   Failing that, goto test 3.
   *	3) If all sockets are bound to a specific inet_sk(sk)->rcv_saddr local
   *	   address, and none of them are the same, the port may be
   *	   shared.
   *	   Failing this, the port cannot be shared.
   *
   * The interesting point, is test #2.  This is what an FTP server does
   * all day.  To optimize this case we use a specific flag bit defined
   * below.  As we add sockets to a bind bucket list, we perform a
   * check of: (newsk->sk_reuse && (newsk->sk_state != TCP_LISTEN))
   * As long as all sockets added to a bind bucket pass this test,
   * the flag bit will be set.
   * The resulting situation is that tcp_v[46]_verify_bind() can just check
   * for this flag bit, if it is set and the socket trying to bind has
   * sk->sk_reuse set, we don't even have to walk the owners list at all,
   * we return that it is ok to bind this socket to the requested local port.
   *
   * Sounds like a lot of work, but it is worth it.  In a more naive
   * implementation (ie. current FreeBSD etc.) the entire list of ports
   * must be walked for each data port opened by an ftp server.  Needless
   * to say, this does not scale at all.  With a couple thousand FTP
   * users logged onto your box, isn't it nice to know that new data
   * ports are created in O(1) time?  I thought so. ;-)	-DaveM
   */
  struct inet_bind_bucket {
7a9546ee3   Eric Dumazet   net: ib_net point...
79
  #ifdef CONFIG_NET_NS
941b1d22c   Pavel Emelyanov   [NETNS]: Make bin...
80
  	struct net		*ib_net;
7a9546ee3   Eric Dumazet   net: ib_net point...
81
  #endif
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
82
83
  	unsigned short		port;
  	signed short		fastreuse;
a9d8f9110   Evgeniy Polyakov   inet: Allowing mo...
84
  	int			num_owners;
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
85
86
87
  	struct hlist_node	node;
  	struct hlist_head	owners;
  };
7a9546ee3   Eric Dumazet   net: ib_net point...
88
89
90
91
  static inline struct net *ib_net(struct inet_bind_bucket *ib)
  {
  	return read_pnet(&ib->ib_net);
  }
5256f2ef3   Lucian Adrian Grijincu   inet: fix inet_bi...
92
93
  #define inet_bind_bucket_for_each(tb, pos, head) \
  	hlist_for_each_entry(tb, pos, head, node)
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
94
95
96
97
98
  
  struct inet_bind_hashbucket {
  	spinlock_t		lock;
  	struct hlist_head	chain;
  };
c25eb3bfb   Eric Dumazet   net: Convert TCP/...
99
100
101
102
103
104
105
  /*
   * Sockets can be hashed in established or listening table
   * We must use different 'nulls' end-of-chain value for listening
   * hash table, or we might find a socket that was closed and
   * reallocated/inserted into established hash table
   */
  #define LISTENING_NULLS_BASE (1U << 29)
5caea4ea7   Eric Dumazet   net: listening_ha...
106
107
  struct inet_listen_hashbucket {
  	spinlock_t		lock;
c25eb3bfb   Eric Dumazet   net: Convert TCP/...
108
  	struct hlist_nulls_head	head;
5caea4ea7   Eric Dumazet   net: listening_ha...
109
  };
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
110
111
112
113
114
115
116
117
118
  /* This is for listening sockets, thus all sockets which possess wildcards. */
  #define INET_LHTABLE_SIZE	32	/* Yes, really, this is all you need. */
  
  struct inet_hashinfo {
  	/* This is for sockets with full identity only.  Sockets here will
  	 * always be without wildcards and will have the following invariant:
  	 *
  	 *          TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
  	 *
dbca9b275   Eric Dumazet   [NET]: change lay...
119
  	 * TIME_WAIT sockets use a separate chain (twchain).
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
120
121
  	 */
  	struct inet_ehash_bucket	*ehash;
9db66bdcc   Eric Dumazet   net: convert TCP/...
122
  	spinlock_t			*ehash_locks;
f373b53b5   Eric Dumazet   tcp: replace ehas...
123
  	unsigned int			ehash_mask;
230140cff   Eric Dumazet   [INET]: Remove pe...
124
  	unsigned int			ehash_locks_mask;
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
125
126
127
128
129
  
  	/* Ok, let's try this, I give up, we do need a local binding
  	 * TCP hash as well as the others for fast bind/connect.
  	 */
  	struct inet_bind_hashbucket	*bhash;
cfcabdcc2   Stephen Hemminger   [NET]: sparse war...
130
  	unsigned int			bhash_size;
24dd1fa18   Eric Dumazet   net: move bsocket...
131
  	/* 4 bytes hole on 64 bit */
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
132

5caea4ea7   Eric Dumazet   net: listening_ha...
133
  	struct kmem_cache		*bind_bucket_cachep;
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
134
135
136
137
138
  
  	/* All the above members are written once at bootup and
  	 * never written again _or_ are predominantly read-access.
  	 *
  	 * Now align to a new cache line as all the following members
5caea4ea7   Eric Dumazet   net: listening_ha...
139
140
141
142
143
  	 * might be often dirty.
  	 */
  	/* All sockets in TCP_LISTEN state will be in here.  This is the only
  	 * table where wildcard'd TCP sockets can exist.  Hash function here
  	 * is just local port number.
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
144
  	 */
5caea4ea7   Eric Dumazet   net: listening_ha...
145
146
  	struct inet_listen_hashbucket	listening_hash[INET_LHTABLE_SIZE]
  					____cacheline_aligned_in_smp;
24dd1fa18   Eric Dumazet   net: move bsocket...
147
  	atomic_t			bsockets;
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
148
  };
81c3d5470   Eric Dumazet   [INET]: speedup i...
149
150
151
152
  static inline struct inet_ehash_bucket *inet_ehash_bucket(
  	struct inet_hashinfo *hashinfo,
  	unsigned int hash)
  {
f373b53b5   Eric Dumazet   tcp: replace ehas...
153
  	return &hashinfo->ehash[hash & hashinfo->ehash_mask];
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
154
  }
9db66bdcc   Eric Dumazet   net: convert TCP/...
155
  static inline spinlock_t *inet_ehash_lockp(
230140cff   Eric Dumazet   [INET]: Remove pe...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  	struct inet_hashinfo *hashinfo,
  	unsigned int hash)
  {
  	return &hashinfo->ehash_locks[hash & hashinfo->ehash_locks_mask];
  }
  
  static inline int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo)
  {
  	unsigned int i, size = 256;
  #if defined(CONFIG_PROVE_LOCKING)
  	unsigned int nr_pcpus = 2;
  #else
  	unsigned int nr_pcpus = num_possible_cpus();
  #endif
  	if (nr_pcpus >= 4)
  		size = 512;
  	if (nr_pcpus >= 8)
  		size = 1024;
  	if (nr_pcpus >= 16)
  		size = 2048;
  	if (nr_pcpus >= 32)
  		size = 4096;
94cd3e6cb   Eric Dumazet   net: wrong test i...
178
  	if (sizeof(spinlock_t) != 0) {
230140cff   Eric Dumazet   [INET]: Remove pe...
179
  #ifdef CONFIG_NUMA
9db66bdcc   Eric Dumazet   net: convert TCP/...
180
181
  		if (size * sizeof(spinlock_t) > PAGE_SIZE)
  			hashinfo->ehash_locks = vmalloc(size * sizeof(spinlock_t));
230140cff   Eric Dumazet   [INET]: Remove pe...
182
183
  		else
  #endif
9db66bdcc   Eric Dumazet   net: convert TCP/...
184
  		hashinfo->ehash_locks =	kmalloc(size * sizeof(spinlock_t),
230140cff   Eric Dumazet   [INET]: Remove pe...
185
186
187
188
  						GFP_KERNEL);
  		if (!hashinfo->ehash_locks)
  			return ENOMEM;
  		for (i = 0; i < size; i++)
9db66bdcc   Eric Dumazet   net: convert TCP/...
189
  			spin_lock_init(&hashinfo->ehash_locks[i]);
230140cff   Eric Dumazet   [INET]: Remove pe...
190
191
192
193
194
195
196
197
198
199
  	}
  	hashinfo->ehash_locks_mask = size - 1;
  	return 0;
  }
  
  static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo)
  {
  	if (hashinfo->ehash_locks) {
  #ifdef CONFIG_NUMA
  		unsigned int size = (hashinfo->ehash_locks_mask + 1) *
9db66bdcc   Eric Dumazet   net: convert TCP/...
200
  							sizeof(spinlock_t);
230140cff   Eric Dumazet   [INET]: Remove pe...
201
202
203
  		if (size > PAGE_SIZE)
  			vfree(hashinfo->ehash_locks);
  		else
230140cff   Eric Dumazet   [INET]: Remove pe...
204
  #endif
218ad12f4   Pavel Emelyanov   [IPV4]: Fix memor...
205
  		kfree(hashinfo->ehash_locks);
230140cff   Eric Dumazet   [INET]: Remove pe...
206
207
208
  		hashinfo->ehash_locks = NULL;
  	}
  }
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
209
  extern struct inet_bind_bucket *
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
210
  		    inet_bind_bucket_create(struct kmem_cache *cachep,
941b1d22c   Pavel Emelyanov   [NETNS]: Make bin...
211
  					    struct net *net,
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
212
213
  					    struct inet_bind_hashbucket *head,
  					    const unsigned short snum);
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
214
  extern void inet_bind_bucket_destroy(struct kmem_cache *cachep,
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
215
  				     struct inet_bind_bucket *tb);
7f635ab71   Pavel Emelyanov   inet: add struct ...
216
217
  static inline int inet_bhashfn(struct net *net,
  		const __u16 lport, const int bhash_size)
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
218
  {
0b4419162   Pavel Emelyanov   netns: introduce ...
219
  	return (lport + net_hash_mix(net)) & (bhash_size - 1);
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
220
  }
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
221
222
  extern void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb,
  			   const unsigned short snum);
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
223
  /* These can have wildcards, don't try too hard. */
2086a6507   Pavel Emelyanov   inet: add struct ...
224
  static inline int inet_lhashfn(struct net *net, const unsigned short num)
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
225
  {
0b4419162   Pavel Emelyanov   netns: introduce ...
226
  	return (num + net_hash_mix(net)) & (INET_LHTABLE_SIZE - 1);
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
227
228
229
230
  }
  
  static inline int inet_sk_listen_hashfn(const struct sock *sk)
  {
c720c7e83   Eric Dumazet   inet: rename some...
231
  	return inet_lhashfn(sock_net(sk), inet_sk(sk)->inet_num);
77d8bf9c6   Arnaldo Carvalho de Melo   [INET]: Move the ...
232
  }
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
233
  /* Caller must disable local BH processing. */
093d28232   Balazs Scheidler   tproxy: fix hash ...
234
  extern int __inet_inherit_port(struct sock *sk, struct sock *child);
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
235

ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
236
  extern void inet_put_port(struct sock *sk);
2d8c4ce51   Arnaldo Carvalho de Melo   [INET]: Generalis...
237

5caea4ea7   Eric Dumazet   net: listening_ha...
238
  void inet_hashinfo_init(struct inet_hashinfo *h);
f3f05f704   Arnaldo Carvalho de Melo   [INET]: Generalis...
239

9327f7053   Eric Dumazet   tcp: Fix a connec...
240
  extern int __inet_hash_nolisten(struct sock *sk, struct inet_timewait_sock *tw);
ab1e0a13d   Arnaldo Carvalho de Melo   [SOCK] proto: Add...
241
242
  extern void inet_hash(struct sock *sk);
  extern void inet_unhash(struct sock *sk);
33b622319   Arnaldo Carvalho de Melo   [INET]: Generalis...
243

c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
244
245
  extern struct sock *__inet_lookup_listener(struct net *net,
  					   struct inet_hashinfo *hashinfo,
fb99c848e   Al Viro   [IPV4]: annotate ...
246
  					   const __be32 daddr,
8f491069b   Herbert Xu   [IPV4]: Use netwo...
247
248
  					   const unsigned short hnum,
  					   const int dif);
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
249
250
251
  static inline struct sock *inet_lookup_listener(struct net *net,
  		struct inet_hashinfo *hashinfo,
  		__be32 daddr, __be16 dport, int dif)
8f491069b   Herbert Xu   [IPV4]: Use netwo...
252
  {
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
253
  	return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif);
8f491069b   Herbert Xu   [IPV4]: Use netwo...
254
  }
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
255
256
  
  /* Socket demux engine toys. */
4f765d842   Al Viro   [IPV4]: INET_MATC...
257
258
259
260
261
262
263
264
265
  /* What happens here is ugly; there's a pair of adjacent fields in
     struct inet_sock; __be16 dport followed by __u16 num.  We want to
     search by pair, so we combine the keys into a single 32bit value
     and compare with 32bit value read from &...->dport.  Let's at least
     make sure that it's not mixed with anything else...
     On 64bit targets we combine comparisons with pair of adjacent __be32
     fields in the same way.
  */
  typedef __u32 __bitwise __portpair;
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
266
267
  #ifdef __BIG_ENDIAN
  #define INET_COMBINED_PORTS(__sport, __dport) \
4f765d842   Al Viro   [IPV4]: INET_MATC...
268
  	((__force __portpair)(((__force __u32)(__be16)(__sport) << 16) | (__u32)(__dport)))
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
269
270
  #else /* __LITTLE_ENDIAN */
  #define INET_COMBINED_PORTS(__sport, __dport) \
4f765d842   Al Viro   [IPV4]: INET_MATC...
271
  	((__force __portpair)(((__u32)(__dport) << 16) | (__force __u32)(__be16)(__sport)))
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
272
273
274
  #endif
  
  #if (BITS_PER_LONG == 64)
4f765d842   Al Viro   [IPV4]: INET_MATC...
275
  typedef __u64 __bitwise __addrpair;
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
276
277
  #ifdef __BIG_ENDIAN
  #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
4f765d842   Al Viro   [IPV4]: INET_MATC...
278
279
280
  	const __addrpair __name = (__force __addrpair) ( \
  				   (((__force __u64)(__be32)(__saddr)) << 32) | \
  				   ((__force __u64)(__be32)(__daddr)));
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
281
282
  #else /* __LITTLE_ENDIAN */
  #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \
4f765d842   Al Viro   [IPV4]: INET_MATC...
283
284
285
  	const __addrpair __name = (__force __addrpair) ( \
  				   (((__force __u64)(__be32)(__daddr)) << 32) | \
  				   ((__force __u64)(__be32)(__saddr)));
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
286
  #endif /* __BIG_ENDIAN */
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
287
  #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
f757fec4b   Eric Dumazet   net: use net_eq()...
288
  	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&	\
c720c7e83   Eric Dumazet   inet: rename some...
289
290
  	 ((*((__addrpair *)&(inet_sk(__sk)->inet_daddr))) == (__cookie))  &&	\
  	 ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports))   &&	\
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
291
  	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
292
  #define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
f757fec4b   Eric Dumazet   net: use net_eq()...
293
  	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&	\
4f765d842   Al Viro   [IPV4]: INET_MATC...
294
295
  	 ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&	\
  	 ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&	\
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
296
297
298
  	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
  #else /* 32-bit arch */
  #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
299
  #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)	\
f757fec4b   Eric Dumazet   net: use net_eq()...
300
  	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))	&&	\
c720c7e83   Eric Dumazet   inet: rename some...
301
302
303
  	 (inet_sk(__sk)->inet_daddr	== (__saddr))		&&	\
  	 (inet_sk(__sk)->inet_rcv_saddr	== (__daddr))		&&	\
  	 ((*((__portpair *)&(inet_sk(__sk)->inet_dport))) == (__ports))	&&	\
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
304
  	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
305
  #define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif)	\
f757fec4b   Eric Dumazet   net: use net_eq()...
306
  	(((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))	&&	\
81c3d5470   Eric Dumazet   [INET]: speedup i...
307
  	 (inet_twsk(__sk)->tw_daddr	== (__saddr))		&&	\
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
308
  	 (inet_twsk(__sk)->tw_rcv_saddr	== (__daddr))		&&	\
4f765d842   Al Viro   [IPV4]: INET_MATC...
309
  	 ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&	\
8feaf0c0a   Arnaldo Carvalho de Melo   [INET]: Generalis...
310
311
  	 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
  #endif /* 64-bit arch */
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
312
313
314
315
316
317
318
  
  /*
   * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
   * not check it for lookups anymore, thanks Alexey. -DaveM
   *
   * Local BH must be disabled here.
   */
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
319
320
  extern struct sock * __inet_lookup_established(struct net *net,
  		struct inet_hashinfo *hashinfo,
77a5ba55d   Pavel Emelyanov   [INET]: Uninline ...
321
322
  		const __be32 saddr, const __be16 sport,
  		const __be32 daddr, const u16 hnum, const int dif);
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
323

8f491069b   Herbert Xu   [IPV4]: Use netwo...
324
  static inline struct sock *
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
325
  	inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo,
fb99c848e   Al Viro   [IPV4]: annotate ...
326
327
  				const __be32 saddr, const __be16 sport,
  				const __be32 daddr, const __be16 dport,
8f491069b   Herbert Xu   [IPV4]: Use netwo...
328
329
  				const int dif)
  {
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
330
  	return __inet_lookup_established(net, hashinfo, saddr, sport, daddr,
8f491069b   Herbert Xu   [IPV4]: Use netwo...
331
332
  					 ntohs(dport), dif);
  }
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
333
334
  static inline struct sock *__inet_lookup(struct net *net,
  					 struct inet_hashinfo *hashinfo,
fb99c848e   Al Viro   [IPV4]: annotate ...
335
336
  					 const __be32 saddr, const __be16 sport,
  					 const __be32 daddr, const __be16 dport,
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
337
338
  					 const int dif)
  {
8f491069b   Herbert Xu   [IPV4]: Use netwo...
339
  	u16 hnum = ntohs(dport);
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
340
341
342
343
  	struct sock *sk = __inet_lookup_established(net, hashinfo,
  				saddr, sport, daddr, hnum, dif);
  
  	return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif);
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
344
  }
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
345
346
  static inline struct sock *inet_lookup(struct net *net,
  				       struct inet_hashinfo *hashinfo,
fb99c848e   Al Viro   [IPV4]: annotate ...
347
348
  				       const __be32 saddr, const __be16 sport,
  				       const __be32 daddr, const __be16 dport,
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
349
350
351
352
353
  				       const int dif)
  {
  	struct sock *sk;
  
  	local_bh_disable();
c67499c0e   Pavel Emelyanov   [NETNS]: Tcp-v4 s...
354
  	sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif);
e48c414ee   Arnaldo Carvalho de Melo   [INET]: Generalis...
355
356
357
358
  	local_bh_enable();
  
  	return sk;
  }
a7f5e7f16   Arnaldo Carvalho de Melo   [INET]: Generalis...
359

9a1f27c48   Arnaldo Carvalho de Melo   inet_hashtables: ...
360
361
362
363
364
  static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
  					     struct sk_buff *skb,
  					     const __be16 sport,
  					     const __be16 dport)
  {
23542618d   KOVACS Krisztian   inet: Don't looku...
365
  	struct sock *sk;
9a1f27c48   Arnaldo Carvalho de Melo   inet_hashtables: ...
366
  	const struct iphdr *iph = ip_hdr(skb);
23542618d   KOVACS Krisztian   inet: Don't looku...
367
368
369
  	if (unlikely(sk = skb_steal_sock(skb)))
  		return sk;
  	else
adf30907d   Eric Dumazet   net: skb->dst acc...
370
  		return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
23542618d   KOVACS Krisztian   inet: Don't looku...
371
372
  				     iph->saddr, sport,
  				     iph->daddr, dport, inet_iif(skb));
9a1f27c48   Arnaldo Carvalho de Melo   inet_hashtables: ...
373
  }
5ee31fc1e   Pavel Emelyanov   [INET]: Consolida...
374
  extern int __inet_hash_connect(struct inet_timewait_death_row *death_row,
9327f7053   Eric Dumazet   tcp: Fix a connec...
375
376
  		struct sock *sk,
  		u32 port_offset,
5ee31fc1e   Pavel Emelyanov   [INET]: Consolida...
377
378
  		int (*check_established)(struct inet_timewait_death_row *,
  			struct sock *, __u16, struct inet_timewait_sock **),
9327f7053   Eric Dumazet   tcp: Fix a connec...
379
  		int (*hash)(struct sock *sk, struct inet_timewait_sock *twp));
a7f5e7f16   Arnaldo Carvalho de Melo   [INET]: Generalis...
380
381
  extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
  			     struct sock *sk);
304a16180   Arnaldo Carvalho de Melo   [INET]: Move the ...
382
  #endif /* _INET_HASHTABLES_H */