2005-08-12 09:19:38 -03: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 09:26:18 -03:00
2011-12-10 09:48:31 +00:00
# if IS_ENABLED(CONFIG_IPV6)
2005-08-12 09:26:18 -03:00
# include <linux/in6.h>
# include <linux/ipv6.h>
2005-08-12 09:19:38 -03:00
# include <linux/types.h>
2007-03-23 11:40:27 -07:00
# include <linux/jhash.h>
# include <net/inet_sock.h>
2005-08-12 09:19:38 -03:00
2005-08-12 09:26:18 -03:00
# include <net/ipv6.h>
2008-06-16 17:14:11 -07:00
# include <net/netns/hash.h>
2005-08-12 09:26:18 -03:00
2005-08-12 09:19:38 -03:00
struct inet_hashinfo ;
2013-10-19 21:48:52 +02: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 09:26:18 -03:00
{
2013-10-19 21:48:52 +02:00
const u32 ports = ( ( ( u32 ) lport ) < < 16 ) | ( __force u32 ) fport ;
return jhash_3words ( lhash , fhash , ports , initval ) ;
2005-08-12 09:26:18 -03: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 10:22:41 -07: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 ,
2017-08-07 08:44:21 -07:00
const u16 hnum , const int dif ,
const int sdif ) ;
2013-09-21 10:22:41 -07:00
struct sock * inet6_lookup_listener ( struct net * net ,
struct inet_hashinfo * hashinfo ,
2016-02-10 11:50:38 -05:00
struct sk_buff * skb , int doff ,
2013-09-21 10:22:41 -07:00
const struct in6_addr * saddr ,
const __be16 sport ,
const struct in6_addr * daddr ,
2017-08-07 08:44:21 -07:00
const unsigned short hnum ,
const int dif , const int sdif ) ;
2005-08-12 09:26:18 -03:00
2008-01-31 05:07:21 -08:00
static inline struct sock * __inet6_lookup ( struct net * net ,
struct inet_hashinfo * hashinfo ,
2016-02-10 11:50:38 -05:00
struct sk_buff * skb , int doff ,
2005-08-12 09:26:18 -03:00
const struct in6_addr * saddr ,
2006-11-08 00:20:00 -08:00
const __be16 sport ,
2005-08-12 09:26:18 -03:00
const struct in6_addr * daddr ,
const u16 hnum ,
2017-08-07 08:44:21 -07:00
const int dif , const int sdif ,
2016-04-01 08:52:17 -07:00
bool * refcounted )
2005-08-12 09:26:18 -03:00
{
2008-01-31 05:07:21 -08:00
struct sock * sk = __inet6_lookup_established ( net , hashinfo , saddr ,
2017-08-07 08:44:21 -07:00
sport , daddr , hnum ,
dif , sdif ) ;
2016-04-01 08:52:17 -07:00
* refcounted = true ;
2005-08-12 09:26:18 -03:00
if ( sk )
return sk ;
2016-04-01 08:52:17 -07:00
* refcounted = false ;
2016-02-10 11:50:38 -05:00
return inet6_lookup_listener ( net , hashinfo , skb , doff , saddr , sport ,
2017-08-07 08:44:21 -07:00
daddr , hnum , dif , sdif ) ;
2005-08-12 09:26:18 -03:00
}
2008-10-07 11:41:57 -07:00
static inline struct sock * __inet6_lookup_skb ( struct inet_hashinfo * hashinfo ,
2016-02-10 11:50:38 -05:00
struct sk_buff * skb , int doff ,
2008-10-07 11:41:57 -07:00
const __be16 sport ,
2014-10-17 09:17:20 -07:00
const __be16 dport ,
2017-08-07 08:44:21 -07:00
int iif , int sdif ,
2016-04-01 08:52:17 -07:00
bool * refcounted )
2008-10-07 11:41:57 -07:00
{
2012-07-26 12:18:11 +00:00
struct sock * sk = skb_steal_sock ( skb ) ;
2008-10-07 12:41:01 -07:00
2016-04-01 08:52:17 -07:00
* refcounted = true ;
2012-07-26 12:18:11 +00:00
if ( sk )
2008-10-07 12:41:01 -07:00
return sk ;
2012-07-26 12:18:11 +00:00
2016-02-10 11:50:38 -05:00
return __inet6_lookup ( dev_net ( skb_dst ( skb ) - > dev ) , hashinfo , skb ,
doff , & ipv6_hdr ( skb ) - > saddr , sport ,
2012-07-26 12:18:11 +00:00
& ipv6_hdr ( skb ) - > daddr , ntohs ( dport ) ,
2017-08-07 08:44:21 -07:00
iif , sdif , refcounted ) ;
2008-10-07 11:41:57 -07:00
}
2013-09-21 10:22:41 -07:00
struct sock * inet6_lookup ( struct net * net , struct inet_hashinfo * hashinfo ,
2016-02-10 11:50:38 -05:00
struct sk_buff * skb , int doff ,
2013-09-21 10:22:41 -07:00
const struct in6_addr * saddr , const __be16 sport ,
const struct in6_addr * daddr , const __be16 dport ,
const int dif ) ;
2016-02-10 11:50:36 -05:00
int inet6_hash ( struct sock * sk ) ;
2011-12-10 09:48:31 +00:00
# endif /* IS_ENABLED(CONFIG_IPV6) */
2014-11-04 10:59:47 -08:00
2017-08-07 08:44:21 -07:00
# define INET6_MATCH(__sk, __net, __saddr, __daddr, __ports, __dif, __sdif) \
2014-11-04 10:59:47 -08:00
( ( ( __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 | | \
2017-08-07 08:44:21 -07:00
( ( __sk ) - > sk_bound_dev_if = = ( __dif ) ) | | \
( ( __sk ) - > sk_bound_dev_if = = ( __sdif ) ) ) & & \
2014-11-04 10:59:47 -08:00
net_eq ( sock_net ( __sk ) , ( __net ) ) )
2005-08-12 09:19:38 -03:00
# endif /* _INET6_HASHTABLES_H */