diff options
author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-08-09 23:09:06 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:42:08 -0400 |
commit | 33b62231908c58ae04185e4f1063d1e35a7c8576 (patch) | |
tree | 502ba8c1c445d0b0f4c19d1aa3b86b01ea88478d /include/net | |
parent | 81849d106b1fb97f8e2d311c0c4d36347def55b8 (diff) |
[INET]: Generalise tcp_v4_lookup_listener
[acme@toy net-2.6.14]$ grep built-in /tmp/before /tmp/after
/tmp/before: 282560 13122 9312 304994 4a762 net/ipv4/built-in.o
/tmp/after: 282560 13122 9312 304994 4a762 net/ipv4/built-in.o
Will be used in DCCP, not exporting it right now not to get in Adrian
Bunk's exported-but-not-used-on-modules radar 8)
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/inet_hashtables.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 6731df2cea67..1c4fa0065a8e 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -16,8 +16,10 @@ | |||
16 | 16 | ||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/ip.h> | 18 | #include <linux/ip.h> |
19 | #include <linux/ipv6.h> | ||
19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/socket.h> | ||
21 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
22 | #include <linux/types.h> | 24 | #include <linux/types.h> |
23 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
@@ -274,4 +276,38 @@ out: | |||
274 | if (sk->sk_state == TCP_LISTEN) | 276 | if (sk->sk_state == TCP_LISTEN) |
275 | wake_up(&hashinfo->lhash_wait); | 277 | wake_up(&hashinfo->lhash_wait); |
276 | } | 278 | } |
279 | |||
280 | extern struct sock *__inet_lookup_listener(const struct hlist_head *head, | ||
281 | const u32 daddr, | ||
282 | const unsigned short hnum, | ||
283 | const int dif); | ||
284 | |||
285 | /* Optimize the common listener case. */ | ||
286 | static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo, | ||
287 | const u32 daddr, | ||
288 | const unsigned short hnum, | ||
289 | const int dif) | ||
290 | { | ||
291 | struct sock *sk = NULL; | ||
292 | struct hlist_head *head; | ||
293 | |||
294 | read_lock(&hashinfo->lhash_lock); | ||
295 | head = &hashinfo->listening_hash[inet_lhashfn(hnum)]; | ||
296 | if (!hlist_empty(head)) { | ||
297 | const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); | ||
298 | |||
299 | if (inet->num == hnum && !sk->sk_node.next && | ||
300 | (!inet->rcv_saddr || inet->rcv_saddr == daddr) && | ||
301 | (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) && | ||
302 | !sk->sk_bound_dev_if) | ||
303 | goto sherry_cache; | ||
304 | sk = __inet_lookup_listener(head, daddr, hnum, dif); | ||
305 | } | ||
306 | if (sk) { | ||
307 | sherry_cache: | ||
308 | sock_hold(sk); | ||
309 | } | ||
310 | read_unlock(&hashinfo->lhash_lock); | ||
311 | return sk; | ||
312 | } | ||
277 | #endif /* _INET_HASHTABLES_H */ | 313 | #endif /* _INET_HASHTABLES_H */ |