linux/include/net/inet_frag.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __NET_FRAG_H__
   3#define __NET_FRAG_H__
   4
   5#include <linux/rhashtable.h>
   6
   7struct netns_frags {
   8        /* sysctls */
   9        long                    high_thresh;
  10        long                    low_thresh;
  11        int                     timeout;
  12        int                     max_dist;
  13        struct inet_frags       *f;
  14
  15        struct rhashtable       rhashtable ____cacheline_aligned_in_smp;
  16
  17        /* Keep atomic mem on separate cachelines in structs that include it */
  18        atomic_long_t           mem ____cacheline_aligned_in_smp;
  19};
  20
  21/**
  22 * fragment queue flags
  23 *
  24 * @INET_FRAG_FIRST_IN: first fragment has arrived
  25 * @INET_FRAG_LAST_IN: final fragment has arrived
  26 * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
  27 */
  28enum {
  29        INET_FRAG_FIRST_IN      = BIT(0),
  30        INET_FRAG_LAST_IN       = BIT(1),
  31        INET_FRAG_COMPLETE      = BIT(2),
  32};
  33
  34struct frag_v4_compare_key {
  35        __be32          saddr;
  36        __be32          daddr;
  37        u32             user;
  38        u32             vif;
  39        __be16          id;
  40        u16             protocol;
  41};
  42
  43struct frag_v6_compare_key {
  44        struct in6_addr saddr;
  45        struct in6_addr daddr;
  46        u32             user;
  47        __be32          id;
  48        u32             iif;
  49};
  50
  51/**
  52 * struct inet_frag_queue - fragment queue
  53 *
  54 * @node: rhash node
  55 * @key: keys identifying this frag.
  56 * @timer: queue expiration timer
  57 * @lock: spinlock protecting this frag
  58 * @refcnt: reference count of the queue
  59 * @fragments: received fragments head
  60 * @fragments_tail: received fragments tail
  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 */
  69struct 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        refcount_t              refcnt;
  78        struct sk_buff          *fragments;
  79        struct sk_buff          *fragments_tail;
  80        ktime_t                 stamp;
  81        int                     len;
  82        int                     meat;
  83        __u8                    flags;
  84        u16                     max_size;
  85        struct netns_frags      *net;
  86        struct rcu_head         rcu;
  87};
  88
  89struct inet_frags {
  90        unsigned int            qsize;
  91
  92        void                    (*constructor)(struct inet_frag_queue *q,
  93                                               const void *arg);
  94        void                    (*destructor)(struct inet_frag_queue *);
  95        void                    (*frag_expire)(struct timer_list *t);
  96        struct kmem_cache       *frags_cachep;
  97        const char              *frags_cache_name;
  98        struct rhashtable_params rhash_params;
  99};
 100
 101int inet_frags_init(struct inet_frags *);
 102void inet_frags_fini(struct inet_frags *);
 103
 104static inline int inet_frags_init_net(struct netns_frags *nf)
 105{
 106        atomic_long_set(&nf->mem, 0);
 107        return rhashtable_init(&nf->rhashtable, &nf->f->rhash_params);
 108}
 109void inet_frags_exit_net(struct netns_frags *nf);
 110
 111void inet_frag_kill(struct inet_frag_queue *q);
 112void inet_frag_destroy(struct inet_frag_queue *q);
 113struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key);
 114
 115static inline void inet_frag_put(struct inet_frag_queue *q)
 116{
 117        if (refcount_dec_and_test(&q->refcnt))
 118                inet_frag_destroy(q);
 119}
 120
 121/* Memory Tracking Functions. */
 122
 123static inline long frag_mem_limit(const struct netns_frags *nf)
 124{
 125        return atomic_long_read(&nf->mem);
 126}
 127
 128static inline void sub_frag_mem_limit(struct netns_frags *nf, long val)
 129{
 130        atomic_long_sub(val, &nf->mem);
 131}
 132
 133static inline void add_frag_mem_limit(struct netns_frags *nf, long val)
 134{
 135        atomic_long_add(val, &nf->mem);
 136}
 137
 138/* RFC 3168 support :
 139 * We want to check ECN values of all fragments, do detect invalid combinations.
 140 * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
 141 */
 142#define IPFRAG_ECN_NOT_ECT      0x01 /* one frag had ECN_NOT_ECT */
 143#define IPFRAG_ECN_ECT_1        0x02 /* one frag had ECN_ECT_1 */
 144#define IPFRAG_ECN_ECT_0        0x04 /* one frag had ECN_ECT_0 */
 145#define IPFRAG_ECN_CE           0x08 /* one frag had ECN_CE */
 146
 147extern const u8 ip_frag_ecn_table[16];
 148
 149#endif
 150