X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=include%2Fnet%2Finet_hashtables.h;h=97dc35ad09bef3c8618445f44d5e97976b0aa2a9;hb=c96a6d41aa033c03b43e5a09448bddcc971797b1;hp=8461cda37490f2ba6a207f6e4583d3f998dd661f;hpb=64c911a3f7c9864a4bbddbb77b722d5553ddcd32;p=linux-2.6-omap-h63xx.git diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 8461cda3749..97dc35ad09b 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,7 @@ struct inet_ehash_bucket { * ports are created in O(1) time? I thought so. ;-) -DaveM */ struct inet_bind_bucket { + struct net *ib_net; unsigned short port; signed short fastreuse; struct hlist_node node; @@ -185,15 +187,15 @@ static inline void inet_ehash_locks_free(struct inet_hashinfo *hashinfo) if (size > PAGE_SIZE) vfree(hashinfo->ehash_locks); else -#else - kfree(hashinfo->ehash_locks); #endif + kfree(hashinfo->ehash_locks); hashinfo->ehash_locks = NULL; } } extern struct inet_bind_bucket * inet_bind_bucket_create(struct kmem_cache *cachep, + struct net *net, struct inet_bind_hashbucket *head, const unsigned short snum); extern void inet_bind_bucket_destroy(struct kmem_cache *cachep, @@ -219,9 +221,9 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk) } /* Caller must disable local BH processing. */ -static inline void __inet_inherit_port(struct inet_hashinfo *table, - struct sock *sk, struct sock *child) +static inline void __inet_inherit_port(struct sock *sk, struct sock *child) { + struct inet_hashinfo *table = sk->sk_prot->hashinfo; const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size); struct inet_bind_hashbucket *head = &table->bhash[bhash]; struct inet_bind_bucket *tb; @@ -233,15 +235,14 @@ static inline void __inet_inherit_port(struct inet_hashinfo *table, spin_unlock(&head->lock); } -static inline void inet_inherit_port(struct inet_hashinfo *table, - struct sock *sk, struct sock *child) +static inline void inet_inherit_port(struct sock *sk, struct sock *child) { local_bh_disable(); - __inet_inherit_port(table, sk, child); + __inet_inherit_port(sk, child); local_bh_enable(); } -extern void inet_put_port(struct inet_hashinfo *table, struct sock *sk); +extern void inet_put_port(struct sock *sk); extern void inet_listen_wlock(struct inet_hashinfo *hashinfo); @@ -264,74 +265,21 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo) wake_up(&hashinfo->lhash_wait); } -static inline void __inet_hash(struct inet_hashinfo *hashinfo, - struct sock *sk, const int listen_possible) -{ - struct hlist_head *list; - rwlock_t *lock; - - BUG_TRAP(sk_unhashed(sk)); - if (listen_possible && sk->sk_state == TCP_LISTEN) { - list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; - lock = &hashinfo->lhash_lock; - inet_listen_wlock(hashinfo); - } else { - struct inet_ehash_bucket *head; - sk->sk_hash = inet_sk_ehashfn(sk); - head = inet_ehash_bucket(hashinfo, sk->sk_hash); - list = &head->chain; - lock = inet_ehash_lockp(hashinfo, sk->sk_hash); - write_lock(lock); - } - __sk_add_node(sk, list); - sock_prot_inc_use(sk->sk_prot); - write_unlock(lock); - if (listen_possible && sk->sk_state == TCP_LISTEN) - wake_up(&hashinfo->lhash_wait); -} - -static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) -{ - if (sk->sk_state != TCP_CLOSE) { - local_bh_disable(); - __inet_hash(hashinfo, sk, 1); - local_bh_enable(); - } -} - -static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk) -{ - rwlock_t *lock; - - if (sk_unhashed(sk)) - goto out; - - if (sk->sk_state == TCP_LISTEN) { - local_bh_disable(); - inet_listen_wlock(hashinfo); - lock = &hashinfo->lhash_lock; - } else { - lock = inet_ehash_lockp(hashinfo, sk->sk_hash); - write_lock_bh(lock); - } +extern void __inet_hash_nolisten(struct sock *sk); +extern void inet_hash(struct sock *sk); +extern void inet_unhash(struct sock *sk); - if (__sk_del_node_init(sk)) - sock_prot_dec_use(sk->sk_prot); - write_unlock_bh(lock); -out: - if (sk->sk_state == TCP_LISTEN) - wake_up(&hashinfo->lhash_wait); -} - -extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, +extern struct sock *__inet_lookup_listener(struct net *net, + struct inet_hashinfo *hashinfo, const __be32 daddr, const unsigned short hnum, const int dif); -static inline struct sock *inet_lookup_listener(struct inet_hashinfo *hashinfo, - __be32 daddr, __be16 dport, int dif) +static inline struct sock *inet_lookup_listener(struct net *net, + struct inet_hashinfo *hashinfo, + __be32 daddr, __be16 dport, int dif) { - return __inet_lookup_listener(hashinfo, daddr, ntohs(dport), dif); + return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif); } /* Socket demux engine toys. */ @@ -365,26 +313,26 @@ typedef __u64 __bitwise __addrpair; (((__force __u64)(__be32)(__daddr)) << 32) | \ ((__force __u64)(__be32)(__saddr))); #endif /* __BIG_ENDIAN */ -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie)) && \ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) && \ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) #else /* 32-bit arch */ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) -#define INET_MATCH(__sk, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif) \ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ (inet_sk(__sk)->daddr == (__saddr)) && \ (inet_sk(__sk)->rcv_saddr == (__daddr)) && \ ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports)) && \ (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif)))) -#define INET_TW_MATCH(__sk, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ - (((__sk)->sk_hash == (__hash)) && \ +#define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif) \ + (((__sk)->sk_hash == (__hash)) && ((__sk)->sk_net == (__net)) && \ (inet_twsk(__sk)->tw_daddr == (__saddr)) && \ (inet_twsk(__sk)->tw_rcv_saddr == (__daddr)) && \ ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) && \ @@ -397,66 +345,36 @@ typedef __u64 __bitwise __addrpair; * * Local BH must be disabled here. */ -static inline struct sock * - __inet_lookup_established(struct inet_hashinfo *hashinfo, - const __be32 saddr, const __be16 sport, - const __be32 daddr, const u16 hnum, - const int dif) -{ - INET_ADDR_COOKIE(acookie, saddr, daddr) - const __portpair ports = INET_COMBINED_PORTS(sport, hnum); - struct sock *sk; - const struct hlist_node *node; - /* Optimize here for direct hit, only listening connections can - * have wildcards anyways. - */ - unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); - struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); - rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); - - prefetch(head->chain.first); - read_lock(lock); - sk_for_each(sk, node, &head->chain) { - if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) - goto hit; /* You sunk my battleship! */ - } - - /* Must check for a TIME_WAIT'er before going to listener hash. */ - sk_for_each(sk, node, &head->twchain) { - if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) - goto hit; - } - sk = NULL; -out: - read_unlock(lock); - return sk; -hit: - sock_hold(sk); - goto out; -} +extern struct sock * __inet_lookup_established(struct net *net, + struct inet_hashinfo *hashinfo, + const __be32 saddr, const __be16 sport, + const __be32 daddr, const u16 hnum, const int dif); static inline struct sock * - inet_lookup_established(struct inet_hashinfo *hashinfo, + inet_lookup_established(struct net *net, struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const __be16 dport, const int dif) { - return __inet_lookup_established(hashinfo, saddr, sport, daddr, + return __inet_lookup_established(net, hashinfo, saddr, sport, daddr, ntohs(dport), dif); } -static inline struct sock *__inet_lookup(struct inet_hashinfo *hashinfo, +static inline struct sock *__inet_lookup(struct net *net, + struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const __be16 dport, const int dif) { u16 hnum = ntohs(dport); - struct sock *sk = __inet_lookup_established(hashinfo, saddr, sport, daddr, - hnum, dif); - return sk ? : __inet_lookup_listener(hashinfo, daddr, hnum, dif); + struct sock *sk = __inet_lookup_established(net, hashinfo, + saddr, sport, daddr, hnum, dif); + + return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif); } -static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, +static inline struct sock *inet_lookup(struct net *net, + struct inet_hashinfo *hashinfo, const __be32 saddr, const __be16 sport, const __be32 daddr, const __be16 dport, const int dif) @@ -464,12 +382,17 @@ static inline struct sock *inet_lookup(struct inet_hashinfo *hashinfo, struct sock *sk; local_bh_disable(); - sk = __inet_lookup(hashinfo, saddr, sport, daddr, dport, dif); + sk = __inet_lookup(net, hashinfo, saddr, sport, daddr, dport, dif); local_bh_enable(); return sk; } +extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk, u32 port_offset, + int (*check_established)(struct inet_timewait_death_row *, + struct sock *, __u16, struct inet_timewait_sock **), + void (*hash)(struct sock *sk)); extern int inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk); #endif /* _INET_HASHTABLES_H */