2007-10-15 13:24:19 +04:00
# ifndef __NET_FRAG_H__
# define __NET_FRAG_H__
2008-01-22 17:02:14 +03:00
struct netns_frags {
2008-01-22 17:06:23 +03:00
int nqueues ;
2008-01-22 17:11:48 +03:00
struct list_head lru_list ;
2008-01-22 17:09:37 +03:00
2013-01-29 03:44:14 +04:00
/* Its important for performance to keep lru_list and mem on
* separate cachelines
*/
atomic_t mem ____cacheline_aligned_in_smp ;
2008-01-22 17:09:37 +03:00
/* sysctls */
int timeout ;
2008-01-22 17:10:13 +03:00
int high_thresh ;
int low_thresh ;
2008-01-22 17:02:14 +03:00
} ;
2007-10-15 13:24:19 +04:00
struct inet_frag_queue {
struct hlist_node list ;
2008-01-22 17:02:14 +03:00
struct netns_frags * net ;
2007-10-15 13:24:19 +04:00
struct list_head lru_list ; /* lru list member */
spinlock_t lock ;
atomic_t refcnt ;
struct timer_list timer ; /* when will this queue expire? */
struct sk_buff * fragments ; /* list of received fragments */
2010-06-29 08:39:37 +04:00
struct sk_buff * fragments_tail ;
2007-10-15 13:24:19 +04:00
ktime_t stamp ;
int len ; /* total length of orig datagram */
int meat ;
__u8 last_in ; /* first/last segment arrived? */
2008-03-29 02:35:27 +03:00
# define INET_FRAG_COMPLETE 4
# define INET_FRAG_FIRST_IN 2
# define INET_FRAG_LAST_IN 1
2012-08-26 21:13:55 +04:00
u16 max_size ;
2007-10-15 13:24:19 +04:00
} ;
2007-10-15 13:31:52 +04:00
# define INETFRAGS_HASHSZ 64
struct inet_frags {
struct hlist_head hash [ INETFRAGS_HASHSZ ] ;
rwlock_t lock ;
u32 rnd ;
2007-10-15 13:39:14 +04:00
int qsize ;
2008-01-22 17:11:04 +03:00
int secret_interval ;
2007-10-15 13:31:52 +04:00
struct timer_list secret_timer ;
2007-10-15 13:38:08 +04:00
unsigned int ( * hashfn ) ( struct inet_frag_queue * ) ;
2007-10-18 06:46:47 +04:00
void ( * constructor ) ( struct inet_frag_queue * q ,
void * arg ) ;
2007-10-15 13:39:14 +04:00
void ( * destructor ) ( struct inet_frag_queue * ) ;
void ( * skb_free ) ( struct sk_buff * ) ;
2012-05-18 07:57:13 +04:00
bool ( * match ) ( struct inet_frag_queue * q , void * arg ) ;
2007-10-18 06:45:23 +04:00
void ( * frag_expire ) ( unsigned long data ) ;
2007-10-15 13:31:52 +04:00
} ;
void inet_frags_init ( struct inet_frags * ) ;
void inet_frags_fini ( struct inet_frags * ) ;
2008-01-22 17:06:23 +03:00
void inet_frags_init_net ( struct netns_frags * nf ) ;
2008-01-22 17:12:39 +03:00
void inet_frags_exit_net ( struct netns_frags * nf , struct inet_frags * f ) ;
2008-01-22 17:06:23 +03:00
2007-10-15 13:37:18 +04:00
void inet_frag_kill ( struct inet_frag_queue * q , struct inet_frags * f ) ;
2007-10-15 13:39:14 +04:00
void inet_frag_destroy ( struct inet_frag_queue * q ,
struct inet_frags * f , int * work ) ;
2012-09-18 20:50:11 +04:00
int inet_frag_evictor ( struct netns_frags * nf , struct inet_frags * f , bool force ) ;
2008-01-22 17:02:14 +03:00
struct inet_frag_queue * inet_frag_find ( struct netns_frags * nf ,
2009-02-25 13:32:52 +03:00
struct inet_frags * f , void * key , unsigned int hash )
__releases ( & f - > lock ) ;
2007-10-15 13:37:18 +04:00
2007-10-15 13:41:56 +04:00
static inline void inet_frag_put ( struct inet_frag_queue * q , struct inet_frags * f )
{
if ( atomic_dec_and_test ( & q - > refcnt ) )
inet_frag_destroy ( q , f , NULL ) ;
}
2007-10-15 13:24:19 +04:00
# endif