]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - include/net/inet_frag.h
UBUNTU: SAUCE: LSM: Use lsmblob in security_secid_to_secctx
[mirror_ubuntu-hirsute-kernel.git] / include / net / inet_frag.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
5ab11c98
PE
2#ifndef __NET_FRAG_H__
3#define __NET_FRAG_H__
4
0eb71a9d 5#include <linux/rhashtable-types.h>
dc93f46b 6#include <linux/completion.h>
648700f7 7
6ce3b4dc
ED
8/* Per netns frag queues directory */
9struct fqdir {
b2fd5321 10 /* sysctls */
3e67f106
ED
11 long high_thresh;
12 long low_thresh;
b2fd5321 13 int timeout;
0fbf4cb2 14 int max_dist;
093ba729 15 struct inet_frags *f;
a39aca67 16 struct net *net;
3c8fc878 17 bool dead;
c2615cf5
ED
18
19 struct rhashtable rhashtable ____cacheline_aligned_in_smp;
20
21 /* Keep atomic mem on separate cachelines in structs that include it */
22 atomic_long_t mem ____cacheline_aligned_in_smp;
d5dd8879 23 struct work_struct destroy_work;
0b9b2414 24 struct llist_node free_list;
ac18e750
PE
25};
26
1ab1934e
NA
27/**
28 * fragment queue flags
29 *
30 * @INET_FRAG_FIRST_IN: first fragment has arrived
31 * @INET_FRAG_LAST_IN: final fragment has arrived
32 * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
3c8fc878 33 * @INET_FRAG_HASH_DEAD: inet_frag_kill() has not removed fq from rhashtable
1ab1934e
NA
34 */
35enum {
36 INET_FRAG_FIRST_IN = BIT(0),
37 INET_FRAG_LAST_IN = BIT(1),
38 INET_FRAG_COMPLETE = BIT(2),
3c8fc878 39 INET_FRAG_HASH_DEAD = BIT(3),
1ab1934e
NA
40};
41
648700f7
ED
42struct frag_v4_compare_key {
43 __be32 saddr;
44 __be32 daddr;
45 u32 user;
46 u32 vif;
47 __be16 id;
48 u16 protocol;
49};
50
51struct frag_v6_compare_key {
52 struct in6_addr saddr;
53 struct in6_addr daddr;
54 u32 user;
55 __be32 id;
56 u32 iif;
57};
58
1ab1934e
NA
59/**
60 * struct inet_frag_queue - fragment queue
61 *
648700f7
ED
62 * @node: rhash node
63 * @key: keys identifying this frag.
1ab1934e 64 * @timer: queue expiration timer
648700f7 65 * @lock: spinlock protecting this frag
1ab1934e 66 * @refcnt: reference count of the queue
353c9cb3 67 * @rb_fragments: received fragments rb-tree root
1ab1934e 68 * @fragments_tail: received fragments tail
353c9cb3 69 * @last_run_head: the head of the last "run". see ip_fragment.c
1ab1934e
NA
70 * @stamp: timestamp of the last received fragment
71 * @len: total length of the original datagram
72 * @meat: length of received fragments so far
73 * @flags: fragment queue flags
d6b915e2 74 * @max_size: maximum received fragment size
6ce3b4dc 75 * @fqdir: pointer to struct fqdir
648700f7 76 * @rcu: rcu head for freeing deferall
1ab1934e 77 */
5ab11c98 78struct inet_frag_queue {
648700f7
ED
79 struct rhash_head node;
80 union {
81 struct frag_v4_compare_key v4;
82 struct frag_v6_compare_key v6;
83 } key;
1ab1934e 84 struct timer_list timer;
648700f7 85 spinlock_t lock;
edcb6918 86 refcount_t refcnt;
d8cf757f 87 struct rb_root rb_fragments;
d6bebca9 88 struct sk_buff *fragments_tail;
353c9cb3 89 struct sk_buff *last_run_head;
5ab11c98 90 ktime_t stamp;
1ab1934e 91 int len;
5ab11c98 92 int meat;
1ab1934e 93 __u8 flags;
5f2d04f1 94 u16 max_size;
6ce3b4dc 95 struct fqdir *fqdir;
648700f7 96 struct rcu_head rcu;
19952cc4
JDB
97};
98
7eb95156 99struct inet_frags {
4c0ebd6f 100 unsigned int qsize;
321a3a99 101
c6fda282 102 void (*constructor)(struct inet_frag_queue *q,
36c77782 103 const void *arg);
1e4b8287 104 void (*destructor)(struct inet_frag_queue *);
78802011 105 void (*frag_expire)(struct timer_list *t);
d4ad4d22
NA
106 struct kmem_cache *frags_cachep;
107 const char *frags_cache_name;
648700f7 108 struct rhashtable_params rhash_params;
dc93f46b
ED
109 refcount_t refcnt;
110 struct completion completion;
7eb95156
PE
111};
112
d4ad4d22 113int inet_frags_init(struct inet_frags *);
7eb95156
PE
114void inet_frags_fini(struct inet_frags *);
115
6b73d197 116int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
d5dd8879 117
08003d0b 118static inline void fqdir_pre_exit(struct fqdir *fqdir)
d5dd8879
ED
119{
120 fqdir->high_thresh = 0; /* prevent creation of new frags */
121 fqdir->dead = true;
122}
89fb9005 123void fqdir_exit(struct fqdir *fqdir);
e5a2bb84 124
093ba729
ED
125void inet_frag_kill(struct inet_frag_queue *q);
126void inet_frag_destroy(struct inet_frag_queue *q);
6ce3b4dc 127struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
277e650d 128
353c9cb3
PO
129/* Free all skbs in the queue; return the sum of their truesizes. */
130unsigned int inet_frag_rbtree_purge(struct rb_root *root);
131
093ba729 132static inline void inet_frag_put(struct inet_frag_queue *q)
762cc408 133{
edcb6918 134 if (refcount_dec_and_test(&q->refcnt))
093ba729 135 inet_frag_destroy(q);
762cc408
PE
136}
137
d433673e
JDB
138/* Memory Tracking Functions. */
139
6ce3b4dc 140static inline long frag_mem_limit(const struct fqdir *fqdir)
d433673e 141{
6ce3b4dc 142 return atomic_long_read(&fqdir->mem);
d433673e
JDB
143}
144
6ce3b4dc 145static inline void sub_frag_mem_limit(struct fqdir *fqdir, long val)
d433673e 146{
6ce3b4dc 147 atomic_long_sub(val, &fqdir->mem);
d433673e
JDB
148}
149
6ce3b4dc 150static inline void add_frag_mem_limit(struct fqdir *fqdir, long val)
d433673e 151{
6ce3b4dc 152 atomic_long_add(val, &fqdir->mem);
d433673e
JDB
153}
154
be991971
HFS
155/* RFC 3168 support :
156 * We want to check ECN values of all fragments, do detect invalid combinations.
157 * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
158 */
159#define IPFRAG_ECN_NOT_ECT 0x01 /* one frag had ECN_NOT_ECT */
160#define IPFRAG_ECN_ECT_1 0x02 /* one frag had ECN_ECT_1 */
161#define IPFRAG_ECN_ECT_0 0x04 /* one frag had ECN_ECT_0 */
162#define IPFRAG_ECN_CE 0x08 /* one frag had ECN_CE */
163
164extern const u8 ip_frag_ecn_table[16];
165
c23f35d1
PO
166/* Return values of inet_frag_queue_insert() */
167#define IPFRAG_OK 0
168#define IPFRAG_DUP 1
169#define IPFRAG_OVERLAP 2
170int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
171 int offset, int end);
172void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
173 struct sk_buff *parent);
174void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
891584f4 175 void *reasm_data, bool try_coalesce);
c23f35d1
PO
176struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q);
177
5ab11c98 178#endif