15ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov#ifndef __NET_FRAG_H__
25ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov#define __NET_FRAG_H__
35ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov
4ac18e7509e7df327e30d6e073a787d922eaf211dPavel Emelyanovstruct netns_frags {
5e5a2bb842cd9681d00d4ca963e63e4d3647e66f8Pavel Emelyanov	int			nqueues;
66ddc082223ef0f73717b4133fa7e648842bbfd02Pavel Emelyanov	atomic_t		mem;
73140c25c82106645a6b1fc469dab7006a1d09fd0Pavel Emelyanov	struct list_head	lru_list;
8b2fd5321dd160ef309dfb6cfc78ed8de4a830659Pavel Emelyanov
9b2fd5321dd160ef309dfb6cfc78ed8de4a830659Pavel Emelyanov	/* sysctls */
10b2fd5321dd160ef309dfb6cfc78ed8de4a830659Pavel Emelyanov	int			timeout;
11e31e0bdc7e7fb9a4b09d2f3266c035a18fdcee9dPavel Emelyanov	int			high_thresh;
12e31e0bdc7e7fb9a4b09d2f3266c035a18fdcee9dPavel Emelyanov	int			low_thresh;
13ac18e7509e7df327e30d6e073a787d922eaf211dPavel Emelyanov};
14ac18e7509e7df327e30d6e073a787d922eaf211dPavel Emelyanov
155ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanovstruct inet_frag_queue {
165ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	struct hlist_node	list;
17ac18e7509e7df327e30d6e073a787d922eaf211dPavel Emelyanov	struct netns_frags	*net;
185ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	struct list_head	lru_list;   /* lru list member */
195ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	spinlock_t		lock;
205ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	atomic_t		refcnt;
215ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	struct timer_list	timer;      /* when will this queue expire? */
225ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	struct sk_buff		*fragments; /* list of received fragments */
23d6bebca92c663fb216c072193945946f3807ca7fChangli Gao	struct sk_buff		*fragments_tail;
245ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	ktime_t			stamp;
255ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	int			len;        /* total length of orig datagram */
265ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	int			meat;
275ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov	__u8			last_in;    /* first/last segment arrived? */
285ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov
29bc578a54f0fd489d0722303f9a52508495ccaf9aJoe Perches#define INET_FRAG_COMPLETE	4
30bc578a54f0fd489d0722303f9a52508495ccaf9aJoe Perches#define INET_FRAG_FIRST_IN	2
31bc578a54f0fd489d0722303f9a52508495ccaf9aJoe Perches#define INET_FRAG_LAST_IN	1
325ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov};
335ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov
347eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov#define INETFRAGS_HASHSZ		64
357eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov
367eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanovstruct inet_frags {
377eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov	struct hlist_head	hash[INETFRAGS_HASHSZ];
387eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov	rwlock_t		lock;
397eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov	u32			rnd;
401e4b82873af0f21002e37a81ef063d2e5410deb3Pavel Emelyanov	int			qsize;
413b4bc4a2bfe80d01ebd4f2b6dcc58986c970ed16Pavel Emelyanov	int			secret_interval;
427eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov	struct timer_list	secret_timer;
43321a3a99e4717b960e21c62fc6a140d21453df7fPavel Emelyanov
44321a3a99e4717b960e21c62fc6a140d21453df7fPavel Emelyanov	unsigned int		(*hashfn)(struct inet_frag_queue *);
45c6fda282294da882f8d8cc4c513940277dd380f5Pavel Emelyanov	void			(*constructor)(struct inet_frag_queue *q,
46c6fda282294da882f8d8cc4c513940277dd380f5Pavel Emelyanov						void *arg);
471e4b82873af0f21002e37a81ef063d2e5410deb3Pavel Emelyanov	void			(*destructor)(struct inet_frag_queue *);
481e4b82873af0f21002e37a81ef063d2e5410deb3Pavel Emelyanov	void			(*skb_free)(struct sk_buff *);
49abd6523d15f40bfee14652619a31a7f65f77f581Pavel Emelyanov	int			(*match)(struct inet_frag_queue *q,
50abd6523d15f40bfee14652619a31a7f65f77f581Pavel Emelyanov						void *arg);
51e521db9d790aaa60ae8920e21cb7faedc280fc36Pavel Emelyanov	void			(*frag_expire)(unsigned long data);
527eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov};
537eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov
547eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanovvoid inet_frags_init(struct inet_frags *);
557eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanovvoid inet_frags_fini(struct inet_frags *);
567eb95156d9dce2f59794264db336ce007d71638bPavel Emelyanov
57e5a2bb842cd9681d00d4ca963e63e4d3647e66f8Pavel Emelyanovvoid inet_frags_init_net(struct netns_frags *nf);
5881566e8322c3f6c6f9a2277fe0e440fee8d917bdPavel Emelyanovvoid inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
59e5a2bb842cd9681d00d4ca963e63e4d3647e66f8Pavel Emelyanov
60277e650ddfc6944ef5f5466fd898b8da7f06cd82Pavel Emelyanovvoid inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
611e4b82873af0f21002e37a81ef063d2e5410deb3Pavel Emelyanovvoid inet_frag_destroy(struct inet_frag_queue *q,
621e4b82873af0f21002e37a81ef063d2e5410deb3Pavel Emelyanov				struct inet_frags *f, int *work);
636ddc082223ef0f73717b4133fa7e648842bbfd02Pavel Emelyanovint inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
64ac18e7509e7df327e30d6e073a787d922eaf211dPavel Emelyanovstruct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
6556bca31ff1989aa8b60f717e984b0e624f06324eHannes Eder		struct inet_frags *f, void *key, unsigned int hash)
6656bca31ff1989aa8b60f717e984b0e624f06324eHannes Eder	__releases(&f->lock);
67277e650ddfc6944ef5f5466fd898b8da7f06cd82Pavel Emelyanov
68762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanovstatic inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
69762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanov{
70762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanov	if (atomic_dec_and_test(&q->refcnt))
71762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanov		inet_frag_destroy(q, f, NULL);
72762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanov}
73762cc40801ad757a34527d5e548816cf3b6fc606Pavel Emelyanov
745ab11c98d3a950faf6922b6166e5f8fc874590e7Pavel Emelyanov#endif
75