0001
0002 #ifndef __NET_FRAG_H__
0003 #define __NET_FRAG_H__
0004
0005 #include <linux/rhashtable-types.h>
0006 #include <linux/completion.h>
0007 #include <linux/in6.h>
0008 #include <linux/rbtree_types.h>
0009 #include <linux/refcount.h>
0010
0011
0012 struct fqdir {
0013
0014 long high_thresh;
0015 long low_thresh;
0016 int timeout;
0017 int max_dist;
0018 struct inet_frags *f;
0019 struct net *net;
0020 bool dead;
0021
0022 struct rhashtable rhashtable ____cacheline_aligned_in_smp;
0023
0024
0025 atomic_long_t mem ____cacheline_aligned_in_smp;
0026 struct work_struct destroy_work;
0027 struct llist_node free_list;
0028 };
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 enum {
0039 INET_FRAG_FIRST_IN = BIT(0),
0040 INET_FRAG_LAST_IN = BIT(1),
0041 INET_FRAG_COMPLETE = BIT(2),
0042 INET_FRAG_HASH_DEAD = BIT(3),
0043 };
0044
0045 struct frag_v4_compare_key {
0046 __be32 saddr;
0047 __be32 daddr;
0048 u32 user;
0049 u32 vif;
0050 __be16 id;
0051 u16 protocol;
0052 };
0053
0054 struct frag_v6_compare_key {
0055 struct in6_addr saddr;
0056 struct in6_addr daddr;
0057 u32 user;
0058 __be32 id;
0059 u32 iif;
0060 };
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct inet_frag_queue {
0083 struct rhash_head node;
0084 union {
0085 struct frag_v4_compare_key v4;
0086 struct frag_v6_compare_key v6;
0087 } key;
0088 struct timer_list timer;
0089 spinlock_t lock;
0090 refcount_t refcnt;
0091 struct rb_root rb_fragments;
0092 struct sk_buff *fragments_tail;
0093 struct sk_buff *last_run_head;
0094 ktime_t stamp;
0095 int len;
0096 int meat;
0097 u8 mono_delivery_time;
0098 __u8 flags;
0099 u16 max_size;
0100 struct fqdir *fqdir;
0101 struct rcu_head rcu;
0102 };
0103
0104 struct inet_frags {
0105 unsigned int qsize;
0106
0107 void (*constructor)(struct inet_frag_queue *q,
0108 const void *arg);
0109 void (*destructor)(struct inet_frag_queue *);
0110 void (*frag_expire)(struct timer_list *t);
0111 struct kmem_cache *frags_cachep;
0112 const char *frags_cache_name;
0113 struct rhashtable_params rhash_params;
0114 refcount_t refcnt;
0115 struct completion completion;
0116 };
0117
0118 int inet_frags_init(struct inet_frags *);
0119 void inet_frags_fini(struct inet_frags *);
0120
0121 int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
0122
0123 static inline void fqdir_pre_exit(struct fqdir *fqdir)
0124 {
0125
0126
0127
0128 WRITE_ONCE(fqdir->high_thresh, 0);
0129
0130
0131
0132
0133 WRITE_ONCE(fqdir->dead, true);
0134 }
0135 void fqdir_exit(struct fqdir *fqdir);
0136
0137 void inet_frag_kill(struct inet_frag_queue *q);
0138 void inet_frag_destroy(struct inet_frag_queue *q);
0139 struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
0140
0141
0142 unsigned int inet_frag_rbtree_purge(struct rb_root *root);
0143
0144 static inline void inet_frag_put(struct inet_frag_queue *q)
0145 {
0146 if (refcount_dec_and_test(&q->refcnt))
0147 inet_frag_destroy(q);
0148 }
0149
0150
0151
0152 static inline long frag_mem_limit(const struct fqdir *fqdir)
0153 {
0154 return atomic_long_read(&fqdir->mem);
0155 }
0156
0157 static inline void sub_frag_mem_limit(struct fqdir *fqdir, long val)
0158 {
0159 atomic_long_sub(val, &fqdir->mem);
0160 }
0161
0162 static inline void add_frag_mem_limit(struct fqdir *fqdir, long val)
0163 {
0164 atomic_long_add(val, &fqdir->mem);
0165 }
0166
0167
0168
0169
0170
0171 #define IPFRAG_ECN_NOT_ECT 0x01
0172 #define IPFRAG_ECN_ECT_1 0x02
0173 #define IPFRAG_ECN_ECT_0 0x04
0174 #define IPFRAG_ECN_CE 0x08
0175
0176 extern const u8 ip_frag_ecn_table[16];
0177
0178
0179 #define IPFRAG_OK 0
0180 #define IPFRAG_DUP 1
0181 #define IPFRAG_OVERLAP 2
0182 int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
0183 int offset, int end);
0184 void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
0185 struct sk_buff *parent);
0186 void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
0187 void *reasm_data, bool try_coalesce);
0188 struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q);
0189
0190 #endif