aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:09:06 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:42:08 -0400
commit33b62231908c58ae04185e4f1063d1e35a7c8576 (patch)
tree502ba8c1c445d0b0f4c19d1aa3b86b01ea88478d /include/net
parent81849d106b1fb97f8e2d311c0c4d36347def55b8 (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.h36
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
280extern 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. */
286static 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) {
307sherry_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 */