Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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 /* Per netns frag queues directory */
0012 struct fqdir {
0013     /* sysctls */
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     /* Keep atomic mem on separate cachelines in structs that include it */
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  * fragment queue flags
0032  *
0033  * @INET_FRAG_FIRST_IN: first fragment has arrived
0034  * @INET_FRAG_LAST_IN: final fragment has arrived
0035  * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
0036  * @INET_FRAG_HASH_DEAD: inet_frag_kill() has not removed fq from rhashtable
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  * struct inet_frag_queue - fragment queue
0064  *
0065  * @node: rhash node
0066  * @key: keys identifying this frag.
0067  * @timer: queue expiration timer
0068  * @lock: spinlock protecting this frag
0069  * @refcnt: reference count of the queue
0070  * @rb_fragments: received fragments rb-tree root
0071  * @fragments_tail: received fragments tail
0072  * @last_run_head: the head of the last "run". see ip_fragment.c
0073  * @stamp: timestamp of the last received fragment
0074  * @len: total length of the original datagram
0075  * @meat: length of received fragments so far
0076  * @mono_delivery_time: stamp has a mono delivery time (EDT)
0077  * @flags: fragment queue flags
0078  * @max_size: maximum received fragment size
0079  * @fqdir: pointer to struct fqdir
0080  * @rcu: rcu head for freeing deferall
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     /* Prevent creation of new frags.
0126      * Pairs with READ_ONCE() in inet_frag_find().
0127      */
0128     WRITE_ONCE(fqdir->high_thresh, 0);
0129 
0130     /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
0131      * and ip6frag_expire_frag_queue().
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 /* Free all skbs in the queue; return the sum of their truesizes. */
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 /* Memory Tracking Functions. */
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 /* RFC 3168 support :
0168  * We want to check ECN values of all fragments, do detect invalid combinations.
0169  * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
0170  */
0171 #define IPFRAG_ECN_NOT_ECT  0x01 /* one frag had ECN_NOT_ECT */
0172 #define IPFRAG_ECN_ECT_1    0x02 /* one frag had ECN_ECT_1 */
0173 #define IPFRAG_ECN_ECT_0    0x04 /* one frag had ECN_ECT_0 */
0174 #define IPFRAG_ECN_CE       0x08 /* one frag had ECN_CE */
0175 
0176 extern const u8 ip_frag_ecn_table[16];
0177 
0178 /* Return values of inet_frag_queue_insert() */
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