aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/inet_hashtables.h77
-rw-r--r--include/net/inet_timewait_sock.h9
-rw-r--r--include/net/sock.h12
3 files changed, 87 insertions, 11 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index c38c637e0734..b5c0d64ea741 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -30,6 +30,7 @@
30#include <net/tcp_states.h> 30#include <net/tcp_states.h>
31 31
32#include <asm/atomic.h> 32#include <asm/atomic.h>
33#include <asm/byteorder.h>
33 34
34/* This is for all connections with a full identity, no wildcards. 35/* This is for all connections with a full identity, no wildcards.
35 * New scheme, half the table is for TIME_WAIT, the other half is 36 * New scheme, half the table is for TIME_WAIT, the other half is
@@ -285,13 +286,13 @@ extern struct sock *__inet_lookup_listener(const struct hlist_head *head,
285 const int dif); 286 const int dif);
286 287
287/* Optimize the common listener case. */ 288/* Optimize the common listener case. */
288static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo, 289static inline struct sock *
289 const u32 daddr, 290 inet_lookup_listener(struct inet_hashinfo *hashinfo,
290 const unsigned short hnum, 291 const u32 daddr,
291 const int dif) 292 const unsigned short hnum, const int dif)
292{ 293{
293 struct sock *sk = NULL; 294 struct sock *sk = NULL;
294 struct hlist_head *head; 295 const struct hlist_head *head;
295 296
296 read_lock(&hashinfo->lhash_lock); 297 read_lock(&hashinfo->lhash_lock);
297 head = &hashinfo->listening_hash[inet_lhashfn(hnum)]; 298 head = &hashinfo->listening_hash[inet_lhashfn(hnum)];
@@ -351,4 +352,70 @@ sherry_cache:
351 ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ 352 ((*((__u32 *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \
352 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) 353 (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
353#endif /* 64-bit arch */ 354#endif /* 64-bit arch */
355
356/*
357 * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need
358 * not check it for lookups anymore, thanks Alexey. -DaveM
359 *
360 * Local BH must be disabled here.
361 */
362static inline struct sock *
363 __inet_lookup_established(struct inet_hashinfo *hashinfo,
364 const u32 saddr, const u16 sport,
365 const u32 daddr, const u16 hnum,
366 const int dif)
367{
368 INET_ADDR_COOKIE(acookie, saddr, daddr)
369 const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
370 struct sock *sk;
371 const struct hlist_node *node;
372 /* Optimize here for direct hit, only listening connections can
373 * have wildcards anyways.
374 */
375 const int hash = inet_ehashfn(daddr, hnum, saddr, sport, hashinfo->ehash_size);
376 struct inet_ehash_bucket *head = &hashinfo->ehash[hash];
377
378 read_lock(&head->lock);
379 sk_for_each(sk, node, &head->chain) {
380 if (INET_MATCH(sk, acookie, saddr, daddr, ports, dif))
381 goto hit; /* You sunk my battleship! */
382 }
383
384 /* Must check for a TIME_WAIT'er before going to listener hash. */
385 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
386 if (INET_TW_MATCH(sk, acookie, saddr, daddr, ports, dif))
387 goto hit;
388 }
389 sk = NULL;
390out:
391 read_unlock(&head->lock);
392 return sk;
393hit:
394 sock_hold(sk);
395 goto out;
396}
397
398static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo,
399 const u32 saddr, const u16 sport,
400 const u32 daddr, const u16 hnum,
401 const int dif)
402{
403 struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr,
404 hnum, dif);
405 return sk ? : inet_lookup_listener(hashinfo, daddr, hnum, dif);
406}
407
408static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo,
409 const u32 saddr, const u16 sport,
410 const u32 daddr, const u16 dport,
411 const int dif)
412{
413 struct sock *sk;
414
415 local_bh_disable();
416 sk = __inet_lookup(hashinfo, saddr, sport, daddr, ntohs(dport), dif);
417 local_bh_enable();
418
419 return sk;
420}
354#endif /* _INET_HASHTABLES_H */ 421#endif /* _INET_HASHTABLES_H */
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index ce117048f2fd..020f28058fd4 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -17,6 +17,7 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19 19
20#include <linux/ip.h>
20#include <linux/list.h> 21#include <linux/list.h>
21#include <linux/types.h> 22#include <linux/types.h>
22 23
@@ -32,6 +33,7 @@
32#endif 33#endif
33 34
34struct inet_bind_bucket; 35struct inet_bind_bucket;
36struct inet_hashinfo;
35 37
36/* 38/*
37 * This is a TIME_WAIT sock. It works around the memory consumption 39 * This is a TIME_WAIT sock. It works around the memory consumption
@@ -139,4 +141,11 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw)
139 kmem_cache_free(tw->tw_prot->twsk_slab, tw); 141 kmem_cache_free(tw->tw_prot->twsk_slab, tw);
140 } 142 }
141} 143}
144
145extern void __inet_twsk_kill(struct inet_timewait_sock *tw,
146 struct inet_hashinfo *hashinfo);
147
148extern void __inet_twsk_hashdance(struct inet_timewait_sock *tw,
149 struct sock *sk,
150 struct inet_hashinfo *hashinfo);
142#endif /* _INET_TIMEWAIT_SOCK_ */ 151#endif /* _INET_TIMEWAIT_SOCK_ */
diff --git a/include/net/sock.h b/include/net/sock.h
index c902c57bf2b7..bdae0a5eadf5 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -255,28 +255,28 @@ struct sock {
255/* 255/*
256 * Hashed lists helper routines 256 * Hashed lists helper routines
257 */ 257 */
258static inline struct sock *__sk_head(struct hlist_head *head) 258static inline struct sock *__sk_head(const struct hlist_head *head)
259{ 259{
260 return hlist_entry(head->first, struct sock, sk_node); 260 return hlist_entry(head->first, struct sock, sk_node);
261} 261}
262 262
263static inline struct sock *sk_head(struct hlist_head *head) 263static inline struct sock *sk_head(const struct hlist_head *head)
264{ 264{
265 return hlist_empty(head) ? NULL : __sk_head(head); 265 return hlist_empty(head) ? NULL : __sk_head(head);
266} 266}
267 267
268static inline struct sock *sk_next(struct sock *sk) 268static inline struct sock *sk_next(const struct sock *sk)
269{ 269{
270 return sk->sk_node.next ? 270 return sk->sk_node.next ?
271 hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL; 271 hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL;
272} 272}
273 273
274static inline int sk_unhashed(struct sock *sk) 274static inline int sk_unhashed(const struct sock *sk)
275{ 275{
276 return hlist_unhashed(&sk->sk_node); 276 return hlist_unhashed(&sk->sk_node);
277} 277}
278 278
279static inline int sk_hashed(struct sock *sk) 279static inline int sk_hashed(const struct sock *sk)
280{ 280{
281 return sk->sk_node.pprev != NULL; 281 return sk->sk_node.pprev != NULL;
282} 282}
@@ -494,7 +494,7 @@ extern int sk_wait_data(struct sock *sk, long *timeo);
494struct request_sock_ops; 494struct request_sock_ops;
495 495
496/* Here is the right place to enable sock refcounting debugging */ 496/* Here is the right place to enable sock refcounting debugging */
497#define SOCK_REFCNT_DEBUG 497//#define SOCK_REFCNT_DEBUG
498 498
499/* Networking protocol blocks we attach to sockets. 499/* Networking protocol blocks we attach to sockets.
500 * socket layer -> transport layer interface 500 * socket layer -> transport layer interface