Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0 */ 2 : #ifndef __NET_FRAG_H__ 3 : #define __NET_FRAG_H__ 4 : 5 : #include <linux/rhashtable-types.h> 6 : #include <linux/completion.h> 7 : 8 : /* Per netns frag queues directory */ 9 : struct fqdir { 10 : /* sysctls */ 11 : long high_thresh; 12 : long low_thresh; 13 : int timeout; 14 : int max_dist; 15 : struct inet_frags *f; 16 : struct net *net; 17 : bool dead; 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; 23 : struct work_struct destroy_work; 24 : struct llist_node free_list; 25 : }; 26 : 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 33 : * @INET_FRAG_HASH_DEAD: inet_frag_kill() has not removed fq from rhashtable 34 : */ 35 : enum { 36 : INET_FRAG_FIRST_IN = BIT(0), 37 : INET_FRAG_LAST_IN = BIT(1), 38 : INET_FRAG_COMPLETE = BIT(2), 39 : INET_FRAG_HASH_DEAD = BIT(3), 40 : }; 41 : 42 : struct frag_v4_compare_key { 43 : __be32 saddr; 44 : __be32 daddr; 45 : u32 user; 46 : u32 vif; 47 : __be16 id; 48 : u16 protocol; 49 : }; 50 : 51 : struct 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 : 59 : /** 60 : * struct inet_frag_queue - fragment queue 61 : * 62 : * @node: rhash node 63 : * @key: keys identifying this frag. 64 : * @timer: queue expiration timer 65 : * @lock: spinlock protecting this frag 66 : * @refcnt: reference count of the queue 67 : * @rb_fragments: received fragments rb-tree root 68 : * @fragments_tail: received fragments tail 69 : * @last_run_head: the head of the last "run". see ip_fragment.c 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 74 : * @max_size: maximum received fragment size 75 : * @fqdir: pointer to struct fqdir 76 : * @rcu: rcu head for freeing deferall 77 : */ 78 : struct inet_frag_queue { 79 : struct rhash_head node; 80 : union { 81 : struct frag_v4_compare_key v4; 82 : struct frag_v6_compare_key v6; 83 : } key; 84 : struct timer_list timer; 85 : spinlock_t lock; 86 : refcount_t refcnt; 87 : struct rb_root rb_fragments; 88 : struct sk_buff *fragments_tail; 89 : struct sk_buff *last_run_head; 90 : ktime_t stamp; 91 : int len; 92 : int meat; 93 : __u8 flags; 94 : u16 max_size; 95 : struct fqdir *fqdir; 96 : struct rcu_head rcu; 97 : }; 98 : 99 : struct inet_frags { 100 : unsigned int qsize; 101 : 102 : void (*constructor)(struct inet_frag_queue *q, 103 : const void *arg); 104 : void (*destructor)(struct inet_frag_queue *); 105 : void (*frag_expire)(struct timer_list *t); 106 : struct kmem_cache *frags_cachep; 107 : const char *frags_cache_name; 108 : struct rhashtable_params rhash_params; 109 : refcount_t refcnt; 110 : struct completion completion; 111 : }; 112 : 113 : int inet_frags_init(struct inet_frags *); 114 : void inet_frags_fini(struct inet_frags *); 115 : 116 : int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net); 117 : 118 0 : static inline void fqdir_pre_exit(struct fqdir *fqdir) 119 : { 120 0 : fqdir->high_thresh = 0; /* prevent creation of new frags */ 121 0 : fqdir->dead = true; 122 : } 123 : void fqdir_exit(struct fqdir *fqdir); 124 : 125 : void inet_frag_kill(struct inet_frag_queue *q); 126 : void inet_frag_destroy(struct inet_frag_queue *q); 127 : struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key); 128 : 129 : /* Free all skbs in the queue; return the sum of their truesizes. */ 130 : unsigned int inet_frag_rbtree_purge(struct rb_root *root); 131 : 132 0 : static inline void inet_frag_put(struct inet_frag_queue *q) 133 : { 134 0 : if (refcount_dec_and_test(&q->refcnt)) 135 0 : inet_frag_destroy(q); 136 0 : } 137 : 138 : /* Memory Tracking Functions. */ 139 : 140 0 : static inline long frag_mem_limit(const struct fqdir *fqdir) 141 : { 142 0 : return atomic_long_read(&fqdir->mem); 143 : } 144 : 145 0 : static inline void sub_frag_mem_limit(struct fqdir *fqdir, long val) 146 : { 147 0 : atomic_long_sub(val, &fqdir->mem); 148 0 : } 149 : 150 0 : static inline void add_frag_mem_limit(struct fqdir *fqdir, long val) 151 : { 152 0 : atomic_long_add(val, &fqdir->mem); 153 0 : } 154 : 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 : 164 : extern const u8 ip_frag_ecn_table[16]; 165 : 166 : /* Return values of inet_frag_queue_insert() */ 167 : #define IPFRAG_OK 0 168 : #define IPFRAG_DUP 1 169 : #define IPFRAG_OVERLAP 2 170 : int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb, 171 : int offset, int end); 172 : void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb, 173 : struct sk_buff *parent); 174 : void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head, 175 : void *reasm_data, bool try_coalesce); 176 : struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q); 177 : 178 : #endif