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

nf_conntrack.h (10622B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Connection state tracking for netfilter.  This is separated from,
      4 * but required by, the (future) NAT layer; it can also be used by an iptables
      5 * extension.
      6 *
      7 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
      8 *	- generalize L3 protocol dependent part.
      9 *
     10 * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
     11 */
     12
     13#ifndef _NF_CONNTRACK_H
     14#define _NF_CONNTRACK_H
     15
     16#include <linux/bitops.h>
     17#include <linux/compiler.h>
     18
     19#include <linux/netfilter/nf_conntrack_common.h>
     20#include <linux/netfilter/nf_conntrack_tcp.h>
     21#include <linux/netfilter/nf_conntrack_dccp.h>
     22#include <linux/netfilter/nf_conntrack_sctp.h>
     23#include <linux/netfilter/nf_conntrack_proto_gre.h>
     24
     25#include <net/netfilter/nf_conntrack_tuple.h>
     26
     27struct nf_ct_udp {
     28	unsigned long	stream_ts;
     29};
     30
     31/* per conntrack: protocol private data */
     32union nf_conntrack_proto {
     33	/* insert conntrack proto private data here */
     34	struct nf_ct_dccp dccp;
     35	struct ip_ct_sctp sctp;
     36	struct ip_ct_tcp tcp;
     37	struct nf_ct_udp udp;
     38	struct nf_ct_gre gre;
     39	unsigned int tmpl_padto;
     40};
     41
     42union nf_conntrack_expect_proto {
     43	/* insert expect proto private data here */
     44};
     45
     46struct nf_conntrack_net_ecache {
     47	struct delayed_work dwork;
     48	spinlock_t dying_lock;
     49	struct hlist_nulls_head dying_list;
     50};
     51
     52struct nf_conntrack_net {
     53	/* only used when new connection is allocated: */
     54	atomic_t count;
     55	unsigned int expect_count;
     56	u8 sysctl_auto_assign_helper;
     57	bool auto_assign_helper_warned;
     58
     59	/* only used from work queues, configuration plane, and so on: */
     60	unsigned int users4;
     61	unsigned int users6;
     62	unsigned int users_bridge;
     63#ifdef CONFIG_SYSCTL
     64	struct ctl_table_header	*sysctl_header;
     65#endif
     66#ifdef CONFIG_NF_CONNTRACK_EVENTS
     67	struct nf_conntrack_net_ecache ecache;
     68#endif
     69};
     70
     71#include <linux/types.h>
     72#include <linux/skbuff.h>
     73
     74#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
     75#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
     76
     77struct nf_conn {
     78	/* Usage count in here is 1 for hash table, 1 per skb,
     79	 * plus 1 for any connection(s) we are `master' for
     80	 *
     81	 * Hint, SKB address this struct and refcnt via skb->_nfct and
     82	 * helpers nf_conntrack_get() and nf_conntrack_put().
     83	 * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
     84	 * except that the latter uses internal indirection and does not
     85	 * result in a conntrack module dependency.
     86	 * beware nf_ct_get() is different and don't inc refcnt.
     87	 */
     88	struct nf_conntrack ct_general;
     89
     90	spinlock_t	lock;
     91	/* jiffies32 when this ct is considered dead */
     92	u32 timeout;
     93
     94#ifdef CONFIG_NF_CONNTRACK_ZONES
     95	struct nf_conntrack_zone zone;
     96#endif
     97	/* XXX should I move this to the tail ? - Y.K */
     98	/* These are my tuples; original and reply */
     99	struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
    100
    101	/* Have we seen traffic both ways yet? (bitset) */
    102	unsigned long status;
    103
    104	possible_net_t ct_net;
    105
    106#if IS_ENABLED(CONFIG_NF_NAT)
    107	struct hlist_node	nat_bysource;
    108#endif
    109	/* all members below initialized via memset */
    110	struct { } __nfct_init_offset;
    111
    112	/* If we were expected by an expectation, this will be it */
    113	struct nf_conn *master;
    114
    115#if defined(CONFIG_NF_CONNTRACK_MARK)
    116	u_int32_t mark;
    117#endif
    118
    119#ifdef CONFIG_NF_CONNTRACK_SECMARK
    120	u_int32_t secmark;
    121#endif
    122
    123	/* Extensions */
    124	struct nf_ct_ext *ext;
    125
    126	/* Storage reserved for other modules, must be the last member */
    127	union nf_conntrack_proto proto;
    128};
    129
    130static inline struct nf_conn *
    131nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
    132{
    133	return container_of(hash, struct nf_conn,
    134			    tuplehash[hash->tuple.dst.dir]);
    135}
    136
    137static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct)
    138{
    139	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
    140}
    141
    142static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
    143{
    144	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
    145}
    146
    147#define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
    148
    149/* get master conntrack via master expectation */
    150#define master_ct(conntr) (conntr->master)
    151
    152extern struct net init_net;
    153
    154static inline struct net *nf_ct_net(const struct nf_conn *ct)
    155{
    156	return read_pnet(&ct->ct_net);
    157}
    158
    159/* Alter reply tuple (maybe alter helper). */
    160void nf_conntrack_alter_reply(struct nf_conn *ct,
    161			      const struct nf_conntrack_tuple *newreply);
    162
    163/* Is this tuple taken? (ignoring any belonging to the given
    164   conntrack). */
    165int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
    166			     const struct nf_conn *ignored_conntrack);
    167
    168/* Return conntrack_info and tuple hash for given skb. */
    169static inline struct nf_conn *
    170nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
    171{
    172	unsigned long nfct = skb_get_nfct(skb);
    173
    174	*ctinfo = nfct & NFCT_INFOMASK;
    175	return (struct nf_conn *)(nfct & NFCT_PTRMASK);
    176}
    177
    178void nf_ct_destroy(struct nf_conntrack *nfct);
    179
    180/* decrement reference count on a conntrack */
    181static inline void nf_ct_put(struct nf_conn *ct)
    182{
    183	if (ct && refcount_dec_and_test(&ct->ct_general.use))
    184		nf_ct_destroy(&ct->ct_general);
    185}
    186
    187/* Protocol module loading */
    188int nf_ct_l3proto_try_module_get(unsigned short l3proto);
    189void nf_ct_l3proto_module_put(unsigned short l3proto);
    190
    191/* load module; enable/disable conntrack in this namespace */
    192int nf_ct_netns_get(struct net *net, u8 nfproto);
    193void nf_ct_netns_put(struct net *net, u8 nfproto);
    194
    195/*
    196 * Allocate a hashtable of hlist_head (if nulls == 0),
    197 * or hlist_nulls_head (if nulls == 1)
    198 */
    199void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls);
    200
    201int nf_conntrack_hash_check_insert(struct nf_conn *ct);
    202bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report);
    203
    204bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
    205		       u_int16_t l3num, struct net *net,
    206		       struct nf_conntrack_tuple *tuple);
    207
    208void __nf_ct_refresh_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
    209			  const struct sk_buff *skb,
    210			  u32 extra_jiffies, bool do_acct);
    211
    212/* Refresh conntrack for this many jiffies and do accounting */
    213static inline void nf_ct_refresh_acct(struct nf_conn *ct,
    214				      enum ip_conntrack_info ctinfo,
    215				      const struct sk_buff *skb,
    216				      u32 extra_jiffies)
    217{
    218	__nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, true);
    219}
    220
    221/* Refresh conntrack for this many jiffies */
    222static inline void nf_ct_refresh(struct nf_conn *ct,
    223				 const struct sk_buff *skb,
    224				 u32 extra_jiffies)
    225{
    226	__nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, false);
    227}
    228
    229/* kill conntrack and do accounting */
    230bool nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
    231		     const struct sk_buff *skb);
    232
    233/* kill conntrack without accounting */
    234static inline bool nf_ct_kill(struct nf_conn *ct)
    235{
    236	return nf_ct_delete(ct, 0, 0);
    237}
    238
    239struct nf_ct_iter_data {
    240	struct net *net;
    241	void *data;
    242	u32 portid;
    243	int report;
    244};
    245
    246/* Iterate over all conntracks: if iter returns true, it's deleted. */
    247void nf_ct_iterate_cleanup_net(int (*iter)(struct nf_conn *i, void *data),
    248			       const struct nf_ct_iter_data *iter_data);
    249
    250/* also set unconfirmed conntracks as dying. Only use in module exit path. */
    251void nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data),
    252			   void *data);
    253
    254struct nf_conntrack_zone;
    255
    256void nf_conntrack_free(struct nf_conn *ct);
    257struct nf_conn *nf_conntrack_alloc(struct net *net,
    258				   const struct nf_conntrack_zone *zone,
    259				   const struct nf_conntrack_tuple *orig,
    260				   const struct nf_conntrack_tuple *repl,
    261				   gfp_t gfp);
    262
    263static inline int nf_ct_is_template(const struct nf_conn *ct)
    264{
    265	return test_bit(IPS_TEMPLATE_BIT, &ct->status);
    266}
    267
    268/* It's confirmed if it is, or has been in the hash table. */
    269static inline int nf_ct_is_confirmed(const struct nf_conn *ct)
    270{
    271	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
    272}
    273
    274static inline int nf_ct_is_dying(const struct nf_conn *ct)
    275{
    276	return test_bit(IPS_DYING_BIT, &ct->status);
    277}
    278
    279/* Packet is received from loopback */
    280static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
    281{
    282	return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
    283}
    284
    285#define nfct_time_stamp ((u32)(jiffies))
    286
    287/* jiffies until ct expires, 0 if already expired */
    288static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
    289{
    290	s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
    291
    292	return max(timeout, 0);
    293}
    294
    295static inline bool nf_ct_is_expired(const struct nf_conn *ct)
    296{
    297	return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0;
    298}
    299
    300/* use after obtaining a reference count */
    301static inline bool nf_ct_should_gc(const struct nf_conn *ct)
    302{
    303	return nf_ct_is_expired(ct) && nf_ct_is_confirmed(ct) &&
    304	       !nf_ct_is_dying(ct);
    305}
    306
    307#define	NF_CT_DAY	(86400 * HZ)
    308
    309/* Set an arbitrary timeout large enough not to ever expire, this save
    310 * us a check for the IPS_OFFLOAD_BIT from the packet path via
    311 * nf_ct_is_expired().
    312 */
    313static inline void nf_ct_offload_timeout(struct nf_conn *ct)
    314{
    315	if (nf_ct_expires(ct) < NF_CT_DAY / 2)
    316		WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
    317}
    318
    319struct kernel_param;
    320
    321int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp);
    322int nf_conntrack_hash_resize(unsigned int hashsize);
    323
    324extern struct hlist_nulls_head *nf_conntrack_hash;
    325extern unsigned int nf_conntrack_htable_size;
    326extern seqcount_spinlock_t nf_conntrack_generation;
    327extern unsigned int nf_conntrack_max;
    328
    329/* must be called with rcu read lock held */
    330static inline void
    331nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize)
    332{
    333	struct hlist_nulls_head *hptr;
    334	unsigned int sequence, hsz;
    335
    336	do {
    337		sequence = read_seqcount_begin(&nf_conntrack_generation);
    338		hsz = nf_conntrack_htable_size;
    339		hptr = nf_conntrack_hash;
    340	} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
    341
    342	*hash = hptr;
    343	*hsize = hsz;
    344}
    345
    346struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
    347				 const struct nf_conntrack_zone *zone,
    348				 gfp_t flags);
    349void nf_ct_tmpl_free(struct nf_conn *tmpl);
    350
    351u32 nf_ct_get_id(const struct nf_conn *ct);
    352u32 nf_conntrack_count(const struct net *net);
    353
    354static inline void
    355nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info)
    356{
    357	skb_set_nfct(skb, (unsigned long)ct | info);
    358}
    359
    360extern unsigned int nf_conntrack_net_id;
    361
    362static inline struct nf_conntrack_net *nf_ct_pernet(const struct net *net)
    363{
    364	return net_generic(net, nf_conntrack_net_id);
    365}
    366
    367#define NF_CT_STAT_INC(net, count)	  __this_cpu_inc((net)->ct.stat->count)
    368#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
    369#define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
    370
    371#define MODULE_ALIAS_NFCT_HELPER(helper) \
    372        MODULE_ALIAS("nfct-helper-" helper)
    373
    374#endif /* _NF_CONNTRACK_H */