cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inet_frag.h (5133B)


      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 */
      9struct 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 */
     35enum {
     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
     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
     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 * @mono_delivery_time: stamp has a mono delivery time (EDT)
     74 * @flags: fragment queue flags
     75 * @max_size: maximum received fragment size
     76 * @fqdir: pointer to struct fqdir
     77 * @rcu: rcu head for freeing deferall
     78 */
     79struct inet_frag_queue {
     80	struct rhash_head	node;
     81	union {
     82		struct frag_v4_compare_key v4;
     83		struct frag_v6_compare_key v6;
     84	} key;
     85	struct timer_list	timer;
     86	spinlock_t		lock;
     87	refcount_t		refcnt;
     88	struct rb_root		rb_fragments;
     89	struct sk_buff		*fragments_tail;
     90	struct sk_buff		*last_run_head;
     91	ktime_t			stamp;
     92	int			len;
     93	int			meat;
     94	u8			mono_delivery_time;
     95	__u8			flags;
     96	u16			max_size;
     97	struct fqdir		*fqdir;
     98	struct rcu_head		rcu;
     99};
    100
    101struct inet_frags {
    102	unsigned int		qsize;
    103
    104	void			(*constructor)(struct inet_frag_queue *q,
    105					       const void *arg);
    106	void			(*destructor)(struct inet_frag_queue *);
    107	void			(*frag_expire)(struct timer_list *t);
    108	struct kmem_cache	*frags_cachep;
    109	const char		*frags_cache_name;
    110	struct rhashtable_params rhash_params;
    111	refcount_t		refcnt;
    112	struct completion	completion;
    113};
    114
    115int inet_frags_init(struct inet_frags *);
    116void inet_frags_fini(struct inet_frags *);
    117
    118int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
    119
    120static inline void fqdir_pre_exit(struct fqdir *fqdir)
    121{
    122	/* Prevent creation of new frags.
    123	 * Pairs with READ_ONCE() in inet_frag_find().
    124	 */
    125	WRITE_ONCE(fqdir->high_thresh, 0);
    126
    127	/* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
    128	 * and ip6frag_expire_frag_queue().
    129	 */
    130	WRITE_ONCE(fqdir->dead, true);
    131}
    132void fqdir_exit(struct fqdir *fqdir);
    133
    134void inet_frag_kill(struct inet_frag_queue *q);
    135void inet_frag_destroy(struct inet_frag_queue *q);
    136struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
    137
    138/* Free all skbs in the queue; return the sum of their truesizes. */
    139unsigned int inet_frag_rbtree_purge(struct rb_root *root);
    140
    141static inline void inet_frag_put(struct inet_frag_queue *q)
    142{
    143	if (refcount_dec_and_test(&q->refcnt))
    144		inet_frag_destroy(q);
    145}
    146
    147/* Memory Tracking Functions. */
    148
    149static inline long frag_mem_limit(const struct fqdir *fqdir)
    150{
    151	return atomic_long_read(&fqdir->mem);
    152}
    153
    154static inline void sub_frag_mem_limit(struct fqdir *fqdir, long val)
    155{
    156	atomic_long_sub(val, &fqdir->mem);
    157}
    158
    159static inline void add_frag_mem_limit(struct fqdir *fqdir, long val)
    160{
    161	atomic_long_add(val, &fqdir->mem);
    162}
    163
    164/* RFC 3168 support :
    165 * We want to check ECN values of all fragments, do detect invalid combinations.
    166 * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value.
    167 */
    168#define	IPFRAG_ECN_NOT_ECT	0x01 /* one frag had ECN_NOT_ECT */
    169#define	IPFRAG_ECN_ECT_1	0x02 /* one frag had ECN_ECT_1 */
    170#define	IPFRAG_ECN_ECT_0	0x04 /* one frag had ECN_ECT_0 */
    171#define	IPFRAG_ECN_CE		0x08 /* one frag had ECN_CE */
    172
    173extern const u8 ip_frag_ecn_table[16];
    174
    175/* Return values of inet_frag_queue_insert() */
    176#define IPFRAG_OK	0
    177#define IPFRAG_DUP	1
    178#define IPFRAG_OVERLAP	2
    179int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
    180			   int offset, int end);
    181void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
    182			      struct sk_buff *parent);
    183void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
    184			    void *reasm_data, bool try_coalesce);
    185struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q);
    186
    187#endif