GNU Linux-libre 4.4.285-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         struct inet_frags       *f;
12
13         struct rhashtable       rhashtable ____cacheline_aligned_in_smp;
14
15         /* Keep atomic mem on separate cachelines in structs that include it */
16         atomic_long_t           mem ____cacheline_aligned_in_smp;
17 };
18
19 /**
20  * fragment queue flags
21  *
22  * @INET_FRAG_FIRST_IN: first fragment has arrived
23  * @INET_FRAG_LAST_IN: final fragment has arrived
24  * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
25  */
26 enum {
27         INET_FRAG_FIRST_IN      = BIT(0),
28         INET_FRAG_LAST_IN       = BIT(1),
29         INET_FRAG_COMPLETE      = BIT(2),
30 };
31
32 struct frag_v4_compare_key {
33         __be32          saddr;
34         __be32          daddr;
35         u32             user;
36         u32             vif;
37         __be16          id;
38         u16             protocol;
39 };
40
41 struct frag_v6_compare_key {
42         struct in6_addr saddr;
43         struct in6_addr daddr;
44         u32             user;
45         __be32          id;
46         u32             iif;
47 };
48
49 /**
50  * struct inet_frag_queue - fragment queue
51  *
52  * @node: rhash node
53  * @key: keys identifying this frag.
54  * @timer: queue expiration timer
55  * @lock: spinlock protecting this frag
56  * @refcnt: reference count of the queue
57  * @fragments: received fragments head
58  * @rb_fragments: received fragments rb-tree root
59  * @fragments_tail: received fragments tail
60  * @last_run_head: the head of the last "run". see ip_fragment.c
61  * @stamp: timestamp of the last received fragment
62  * @len: total length of the original datagram
63  * @meat: length of received fragments so far
64  * @flags: fragment queue flags
65  * @max_size: maximum received fragment size
66  * @net: namespace that this frag belongs to
67  * @rcu: rcu head for freeing deferall
68  */
69 struct inet_frag_queue {
70         struct rhash_head       node;
71         union {
72                 struct frag_v4_compare_key v4;
73                 struct frag_v6_compare_key v6;
74         } key;
75         struct timer_list       timer;
76         spinlock_t              lock;
77         atomic_t                refcnt;
78         struct sk_buff          *fragments;  /* Used in IPv6. */
79         struct rb_root          rb_fragments; /* Used in IPv4. */
80         struct sk_buff          *fragments_tail;
81         struct sk_buff          *last_run_head;
82         ktime_t                 stamp;
83         int                     len;
84         int                     meat;
85         __u8                    flags;
86         u16                     max_size;
87         struct netns_frags      *net;
88         struct rcu_head         rcu;
89 };
90
91 struct inet_frags {
92         int                     qsize;
93
94         void                    (*constructor)(struct inet_frag_queue *q,
95                                                const void *arg);
96         void                    (*destructor)(struct inet_frag_queue *);
97         void                    (*skb_free)(struct sk_buff *);
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 #endif