2005-08-12 16:19:38 +04:00
/*
* 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 _INET6_HASHTABLES_H
# define _INET6_HASHTABLES_H
2005-08-12 16:26:18 +04:00
2011-12-10 13:48:31 +04:00
# if IS_ENABLED(CONFIG_IPV6)
2005-08-12 16:26:18 +04:00
# include <linux/in6.h>
# include <linux/ipv6.h>
2005-08-12 16:19:38 +04:00
# include <linux/types.h>
2007-03-23 21:40:27 +03:00
# include <linux/jhash.h>
# include <net/inet_sock.h>
2005-08-12 16:19:38 +04:00
2005-08-12 16:26:18 +04:00
# include <net/ipv6.h>
2008-06-17 04:14:11 +04:00
# include <net/netns/hash.h>
2005-08-12 16:26:18 +04:00
2005-08-12 16:19:38 +04:00
struct inet_hashinfo ;
2013-10-19 23:48:52 +04:00
static inline unsigned int __inet6_ehashfn ( const u32 lhash ,
const u16 lport ,
const u32 fhash ,
const __be16 fport ,
const u32 initval )
2005-08-12 16:26:18 +04:00
{
2013-10-19 23:48:52 +04:00
const u32 ports = ( ( ( u32 ) lport ) < < 16 ) | ( __force u32 ) fport ;
return jhash_3words ( lhash , fhash , ports , initval ) ;
2005-08-12 16:26:18 +04:00
}
/*
* Sockets in TCP_CLOSE state are _always_ taken out of the hash , so
* we need not check it for TCP lookups anymore , thanks Alexey . - DaveM
*
* The sockhash lock must be held as a reader here .
*/
2013-09-21 21:22:41 +04:00
struct sock * __inet6_lookup_established ( struct net * net ,
struct inet_hashinfo * hashinfo ,
const struct in6_addr * saddr ,
const __be16 sport ,
const struct in6_addr * daddr ,
const u16 hnum , const int dif ) ;
struct sock * inet6_lookup_listener ( struct net * net ,
struct inet_hashinfo * hashinfo ,
const struct in6_addr * saddr ,
const __be16 sport ,
const struct in6_addr * daddr ,
const unsigned short hnum , const int dif ) ;
2005-08-12 16:26:18 +04:00
2008-01-31 16:07:21 +03:00
static inline struct sock * __inet6_lookup ( struct net * net ,
struct inet_hashinfo * hashinfo ,
2005-08-12 16:26:18 +04:00
const struct in6_addr * saddr ,
2006-11-08 11:20:00 +03:00
const __be16 sport ,
2005-08-12 16:26:18 +04:00
const struct in6_addr * daddr ,
const u16 hnum ,
const int dif )
{
2008-01-31 16:07:21 +03:00
struct sock * sk = __inet6_lookup_established ( net , hashinfo , saddr ,
sport , daddr , hnum , dif ) ;
2005-08-12 16:26:18 +04:00
if ( sk )
return sk ;
2013-01-22 13:50:39 +04:00
return inet6_lookup_listener ( net , hashinfo , saddr , sport ,
daddr , hnum , dif ) ;
2005-08-12 16:26:18 +04:00
}
2008-10-07 22:41:57 +04:00
static inline struct sock * __inet6_lookup_skb ( struct inet_hashinfo * hashinfo ,
struct sk_buff * skb ,
const __be16 sport ,
2014-10-17 20:17:20 +04:00
const __be16 dport ,
int iif )
2008-10-07 22:41:57 +04:00
{
2012-07-26 16:18:11 +04:00
struct sock * sk = skb_steal_sock ( skb ) ;
2008-10-07 23:41:01 +04:00
2012-07-26 16:18:11 +04:00
if ( sk )
2008-10-07 23:41:01 +04:00
return sk ;
2012-07-26 16:18:11 +04:00
return __inet6_lookup ( dev_net ( skb_dst ( skb ) - > dev ) , hashinfo ,
& ipv6_hdr ( skb ) - > saddr , sport ,
& ipv6_hdr ( skb ) - > daddr , ntohs ( dport ) ,
2014-10-17 20:17:20 +04:00
iif ) ;
2008-10-07 22:41:57 +04:00
}
2013-09-21 21:22:41 +04:00
struct sock * inet6_lookup ( struct net * net , struct inet_hashinfo * hashinfo ,
const struct in6_addr * saddr , const __be16 sport ,
const struct in6_addr * daddr , const __be16 dport ,
const int dif ) ;
2016-02-10 19:50:36 +03:00
int inet6_hash ( struct sock * sk ) ;
2011-12-10 13:48:31 +04:00
# endif /* IS_ENABLED(CONFIG_IPV6) */
2014-11-04 21:59:47 +03:00
# define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif) \
( ( ( __sk ) - > sk_portpair = = ( __ports ) ) & & \
( ( __sk ) - > sk_family = = AF_INET6 ) & & \
ipv6_addr_equal ( & ( __sk ) - > sk_v6_daddr , ( __saddr ) ) & & \
ipv6_addr_equal ( & ( __sk ) - > sk_v6_rcv_saddr , ( __daddr ) ) & & \
( ! ( __sk ) - > sk_bound_dev_if | | \
( ( __sk ) - > sk_bound_dev_if = = ( __dif ) ) ) & & \
net_eq ( sock_net ( __sk ) , ( __net ) ) )
2005-08-12 16:19:38 +04:00
# endif /* _INET6_HASHTABLES_H */