GNU Linux-libre 4.9.311-gnu1
[releases.git] / include / net / inet_frag.h
1 #ifndef __NET_FRAG_H__
2 #define __NET_FRAG_H__
3
4 #include <linux/rhashtable.h>
5
6 struct netns_frags {
7         /* sysctls */
8         long                    high_thresh;
9         long                    low_thresh;
10         int                     timeout;
11         int                     max_dist;
12         struct inet_frags       *f;
13
14         struct rhashtable       rhashtable ____cacheline_aligned_in_smp;
15
16         /* Keep atomic mem on separate cachelines in structs that include it */
17         atomic_long_t           mem ____cacheline_aligned_in_smp;
18 };
19
20 /**
21  * fragment queue flags
22  *
23  * @INET_FRAG_FIRST_IN: first fragment has arrived
24  * @INET_FRAG_LAST_IN: final fragment has arrived
25  * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
26  */
27 enum {
28         INET_FRAG_FIRST_IN      = BIT(0),
29         INET_FRAG_LAST_IN       = BIT(1),
30         INET_FRAG_COMPLETE      = BIT(2),
31 };
32
33 struct frag_v4_compare_key {
34         __be32          saddr;
35         __be32          daddr;
36         u32             user;
37         u32             vif;
38         __be16          id;
39         u16             protocol;
40 };
41
42 struct frag_v6_compare_key {
43         struct in6_addr saddr;
44         struct in6_addr daddr;
45         u32             user;
46         __be32          id;
47         u32             iif;
48 };
49
50 /**
51  * struct inet_frag_queue - fragment queue
52  *
53  * @node: rhash node
54  * @key: keys identifying this frag.
55  * @timer: queue expiration timer
56  * @lock: spinlock protecting this frag
57  * @refcnt: reference count of the queue
58  * @fragments: received fragments head
59  * @rb_fragments: received fragments rb-tree root
60  * @fragments_tail: received fragments tail
61  * @last_run_head: the head of the last "run". see ip_fragment.c
62  * @stamp: timestamp of the last received fragment
63  * @len: total length of the original datagram
64  * @meat: length of received fragments so far
65  * @flags: fragment queue flags
66  * @max_size: maximum received fragment size
67  * @net: namespace that this frag belongs to
68  * @rcu: rcu head for freeing deferall
69  */
70 struct inet_frag_queue {
71         struct rhash_head       node;
72         union {
73                 struct frag_v4_compare_key v4;
74                 struct frag_v6_compare_key v6;
75         } key;
76         struct timer_list       timer;
77         spinlock_t              lock;
78         atomic_t                refcnt;
79         struct sk_buff          *fragments;  /* used in 6lopwpan IPv6. */
80         struct rb_root          rb_fragments; /* Used in IPv4/IPv6. */
81         struct sk_buff          *fragments_tail;
82         struct sk_buff          *last_run_head;
83         ktime_t                 stamp;
84         int                     len;
85         int                     meat;
86         __u8                    flags;
87         u16                     max_size;
88         struct netns_frags      *net;
89         struct rcu_head         rcu;
90 };
91
92 struct inet_frags {
93         int                     qsize;
94
95         void                    (*constructor)(struct inet_frag_queue *q,
96                                                const void *arg);
97         void                    (*destructor)(struct inet_frag_queue *);
98         void                    (*frag_expire)(unsigned long data);
99         struct kmem_cache       *frags_cachep;
100         const char              *frags_cache_name;
101         struct rhashtable_params rhash_params;
102 };
103
104 int inet_frags_init(struct inet_frags *);
105 void inet_frags_fini(struct inet_frags *);
106
107 static inline int inet_frags_init_net(struct netns_frags *nf)
108 {
109         atomic_long_set(&nf->mem, 0);
110         return rhashtable_init(&nf->rhashtable, &nf->f->rhash_params);
111 }
112 void inet_frags_exit_net(struct netns_frags *nf);
113
114 void inet_frag_kill(struct inet_frag_queue *q);
115 void inet_frag_destroy(struct inet_frag_queue *q);
116 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key);
117
118 /* Free all skbs in the queue; return the sum of their truesizes. */
119 unsigned int inet_frag_rbtree_purge(struct rb_root *root);
120
121 static inline void inet_frag_put(struct inet_frag_queue *q)
122 {
123         if (atomic_dec_and_test(&q->refcnt))
124                 inet_frag_destroy(q);
125 }
126
127 /* Memory Tracking Functions. */
128
129 static inline long frag_mem_limit(const struct netns_frags *nf)
130 {
131         return atomic_long_read(&nf->mem);
132 }
133
134 static inline void sub_frag_mem_limit(struct netns_frags *nf, long val)
135 {
136         atomic_long_sub(val, &nf->mem);
137 }
138
139 static inline void add_frag_mem_limit(struct netns_frags *nf, long val)
140 {
141         atomic_long_add(val, &nf->mem);
142 }
143
144 /* RFC 3168 support :
145  * We want to check ECN values of all fragments, do detect invalid combinations.
146  * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
147  */
148 #define IPFRAG_ECN_NOT_ECT      0x01 /* one frag had ECN_NOT_ECT */
149 #define IPFRAG_ECN_ECT_1        0x02 /* one frag had ECN_ECT_1 */
150 #define IPFRAG_ECN_ECT_0        0x04 /* one frag had ECN_ECT_0 */
151 #define IPFRAG_ECN_CE           0x08 /* one frag had ECN_CE */
152
153 extern const u8 ip_frag_ecn_table[16];
154
155 /* Return values of inet_frag_queue_insert() */
156 #define IPFRAG_OK       0
157 #define IPFRAG_DUP      1
158 #define IPFRAG_OVERLAP  2
159 int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
160                            int offset, int end);
161 void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
162                               struct sk_buff *parent);
163 void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
164                             void *reasm_data);
165 struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q);
166
167 #endif