1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
29fb9cbb1SYasuyuki Kozakai /*
39fb9cbb1SYasuyuki Kozakai  * Connection state tracking for netfilter.  This is separated from,
49fb9cbb1SYasuyuki Kozakai  * but required by, the (future) NAT layer; it can also be used by an iptables
59fb9cbb1SYasuyuki Kozakai  * extension.
69fb9cbb1SYasuyuki Kozakai  *
79fb9cbb1SYasuyuki Kozakai  * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
89fb9cbb1SYasuyuki Kozakai  *	- generalize L3 protocol dependent part.
99fb9cbb1SYasuyuki Kozakai  *
109fb9cbb1SYasuyuki Kozakai  * Derived from include/linux/netfiter_ipv4/ip_conntrack.h
119fb9cbb1SYasuyuki Kozakai  */
129fb9cbb1SYasuyuki Kozakai 
139fb9cbb1SYasuyuki Kozakai #ifndef _NF_CONNTRACK_H
149fb9cbb1SYasuyuki Kozakai #define _NF_CONNTRACK_H
159fb9cbb1SYasuyuki Kozakai 
169fb9cbb1SYasuyuki Kozakai #include <linux/bitops.h>
179fb9cbb1SYasuyuki Kozakai #include <linux/compiler.h>
189fb9cbb1SYasuyuki Kozakai 
19261db6c2SJeremy Sowden #include <linux/netfilter/nf_conntrack_common.h>
209fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_tcp.h>
212bc78049SPatrick McHardy #include <linux/netfilter/nf_conntrack_dccp.h>
229fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_sctp.h>
23f09943feSPatrick McHardy #include <linux/netfilter/nf_conntrack_proto_gre.h>
249fb9cbb1SYasuyuki Kozakai 
259fb9cbb1SYasuyuki Kozakai #include <net/netfilter/nf_conntrack_tuple.h>
269fb9cbb1SYasuyuki Kozakai 
27d535c8a6SFlorian Westphal struct nf_ct_udp {
28d535c8a6SFlorian Westphal 	unsigned long	stream_ts;
29d535c8a6SFlorian Westphal };
30d535c8a6SFlorian Westphal 
319fb9cbb1SYasuyuki Kozakai /* per conntrack: protocol private data */
329fb9cbb1SYasuyuki Kozakai union nf_conntrack_proto {
339fb9cbb1SYasuyuki Kozakai 	/* insert conntrack proto private data here */
342bc78049SPatrick McHardy 	struct nf_ct_dccp dccp;
359fb9cbb1SYasuyuki Kozakai 	struct ip_ct_sctp sctp;
369fb9cbb1SYasuyuki Kozakai 	struct ip_ct_tcp tcp;
37d535c8a6SFlorian Westphal 	struct nf_ct_udp udp;
38f09943feSPatrick McHardy 	struct nf_ct_gre gre;
39c74454faSFlorian Westphal 	unsigned int tmpl_padto;
409fb9cbb1SYasuyuki Kozakai };
419fb9cbb1SYasuyuki Kozakai 
429fb9cbb1SYasuyuki Kozakai union nf_conntrack_expect_proto {
439fb9cbb1SYasuyuki Kozakai 	/* insert expect proto private data here */
449fb9cbb1SYasuyuki Kozakai };
459fb9cbb1SYasuyuki Kozakai 
469027ce0bSFlorian Westphal struct nf_conntrack_net_ecache {
479027ce0bSFlorian Westphal 	struct delayed_work dwork;
482ed3bf18SFlorian Westphal 	spinlock_t dying_lock;
492ed3bf18SFlorian Westphal 	struct hlist_nulls_head dying_list;
509027ce0bSFlorian Westphal };
519027ce0bSFlorian Westphal 
52a0ae2562SFlorian Westphal struct nf_conntrack_net {
53098b5d35SFlorian Westphal 	/* only used when new connection is allocated: */
54c53bd0e9SFlorian Westphal 	atomic_t count;
55f6f2e580SFlorian Westphal 	unsigned int expect_count;
56098b5d35SFlorian Westphal 
57098b5d35SFlorian Westphal 	/* only used from work queues, configuration plane, and so on: */
58a0ae2562SFlorian Westphal 	unsigned int users4;
59a0ae2562SFlorian Westphal 	unsigned int users6;
60d035f19fSPablo Neira Ayuso 	unsigned int users_bridge;
617b597470SFlorian Westphal #ifdef CONFIG_SYSCTL
627b597470SFlorian Westphal 	struct ctl_table_header	*sysctl_header;
637b597470SFlorian Westphal #endif
641379940bSFlorian Westphal #ifdef CONFIG_NF_CONNTRACK_EVENTS
659027ce0bSFlorian Westphal 	struct nf_conntrack_net_ecache ecache;
661379940bSFlorian Westphal #endif
67a0ae2562SFlorian Westphal };
68a0ae2562SFlorian Westphal 
699fb9cbb1SYasuyuki Kozakai #include <linux/types.h>
709fb9cbb1SYasuyuki Kozakai #include <linux/skbuff.h>
719fb9cbb1SYasuyuki Kozakai 
729fb9cbb1SYasuyuki Kozakai #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
73f8eb24a8SPatrick McHardy #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
74f8eb24a8SPatrick McHardy 
75ea781f19SEric Dumazet struct nf_conn {
76f330a7fdSFlorian Westphal 	/* Usage count in here is 1 for hash table, 1 per skb,
77b476b72aSJesper Dangaard Brouer 	 * plus 1 for any connection(s) we are `master' for
78b476b72aSJesper Dangaard Brouer 	 *
79a9e419dcSFlorian Westphal 	 * Hint, SKB address this struct and refcnt via skb->_nfct and
80b476b72aSJesper Dangaard Brouer 	 * helpers nf_conntrack_get() and nf_conntrack_put().
81b476b72aSJesper Dangaard Brouer 	 * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
826ae7989cSFlorian Westphal 	 * except that the latter uses internal indirection and does not
836ae7989cSFlorian Westphal 	 * result in a conntrack module dependency.
84b476b72aSJesper Dangaard Brouer 	 * beware nf_ct_get() is different and don't inc refcnt.
85b476b72aSJesper Dangaard Brouer 	 */
869fb9cbb1SYasuyuki Kozakai 	struct nf_conntrack ct_general;
879fb9cbb1SYasuyuki Kozakai 
88440f0d58SPatrick McHardy 	spinlock_t	lock;
8987e389b4SFlorian Westphal 	/* jiffies32 when this ct is considered dead */
9087e389b4SFlorian Westphal 	u32 timeout;
91440f0d58SPatrick McHardy 
926c8dee98SFlorian Westphal #ifdef CONFIG_NF_CONNTRACK_ZONES
936c8dee98SFlorian Westphal 	struct nf_conntrack_zone zone;
946c8dee98SFlorian Westphal #endif
959fb9cbb1SYasuyuki Kozakai 	/* XXX should I move this to the tail ? - Y.K */
969fb9cbb1SYasuyuki Kozakai 	/* These are my tuples; original and reply */
979fb9cbb1SYasuyuki Kozakai 	struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
989fb9cbb1SYasuyuki Kozakai 
999fb9cbb1SYasuyuki Kozakai 	/* Have we seen traffic both ways yet? (bitset) */
1009fb9cbb1SYasuyuki Kozakai 	unsigned long status;
1019fb9cbb1SYasuyuki Kozakai 
1020c5c9fb5SEric W. Biederman 	possible_net_t ct_net;
1030c5c9fb5SEric W. Biederman 
1045173bc67SFlorian Westphal #if IS_ENABLED(CONFIG_NF_NAT)
105e1bf1687SFlorian Westphal 	struct hlist_node	nat_bysource;
1065173bc67SFlorian Westphal #endif
107c41884ceSFlorian Westphal 	/* all members below initialized via memset */
1082c407acaSArnd Bergmann 	struct { } __nfct_init_offset;
109c41884ceSFlorian Westphal 
110c41884ceSFlorian Westphal 	/* If we were expected by an expectation, this will be it */
111c41884ceSFlorian Westphal 	struct nf_conn *master;
112c41884ceSFlorian Westphal 
1139fb9cbb1SYasuyuki Kozakai #if defined(CONFIG_NF_CONNTRACK_MARK)
1149fb9cbb1SYasuyuki Kozakai 	u_int32_t mark;
1159fb9cbb1SYasuyuki Kozakai #endif
1169fb9cbb1SYasuyuki Kozakai 
1177c9728c3SJames Morris #ifdef CONFIG_NF_CONNTRACK_SECMARK
1187c9728c3SJames Morris 	u_int32_t secmark;
1197c9728c3SJames Morris #endif
1207c9728c3SJames Morris 
121ecfab2c9SYasuyuki Kozakai 	/* Extensions */
122ecfab2c9SYasuyuki Kozakai 	struct nf_ct_ext *ext;
123e5fc9e7aSChangli Gao 
124e5fc9e7aSChangli Gao 	/* Storage reserved for other modules, must be the last member */
125e5fc9e7aSChangli Gao 	union nf_conntrack_proto proto;
1269fb9cbb1SYasuyuki Kozakai };
1279fb9cbb1SYasuyuki Kozakai 
1289fb9cbb1SYasuyuki Kozakai static inline struct nf_conn *
nf_ct_to_nf_conn(const struct nf_conntrack * nfct)129*2954fe60SFlorian Westphal nf_ct_to_nf_conn(const struct nf_conntrack *nfct)
130*2954fe60SFlorian Westphal {
131*2954fe60SFlorian Westphal 	return container_of(nfct, struct nf_conn, ct_general);
132*2954fe60SFlorian Westphal }
133*2954fe60SFlorian Westphal 
134*2954fe60SFlorian Westphal static inline struct nf_conn *
nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash * hash)1359fb9cbb1SYasuyuki Kozakai nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash)
1369fb9cbb1SYasuyuki Kozakai {
1379fb9cbb1SYasuyuki Kozakai 	return container_of(hash, struct nf_conn,
1389fb9cbb1SYasuyuki Kozakai 			    tuplehash[hash->tuple.dst.dir]);
1399fb9cbb1SYasuyuki Kozakai }
1409fb9cbb1SYasuyuki Kozakai 
nf_ct_l3num(const struct nf_conn * ct)1415e8fbe2aSPatrick McHardy static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct)
1425e8fbe2aSPatrick McHardy {
1435e8fbe2aSPatrick McHardy 	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
1445e8fbe2aSPatrick McHardy }
1455e8fbe2aSPatrick McHardy 
nf_ct_protonum(const struct nf_conn * ct)1465e8fbe2aSPatrick McHardy static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
1475e8fbe2aSPatrick McHardy {
1485e8fbe2aSPatrick McHardy 	return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
1495e8fbe2aSPatrick McHardy }
1505e8fbe2aSPatrick McHardy 
151f2f3e38cSPablo Neira Ayuso #define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
152f2f3e38cSPablo Neira Ayuso 
1539fb9cbb1SYasuyuki Kozakai /* get master conntrack via master expectation */
1549fb9cbb1SYasuyuki Kozakai #define master_ct(conntr) (conntr->master)
1559fb9cbb1SYasuyuki Kozakai 
1565a1fb391SAlexey Dobriyan extern struct net init_net;
1575a1fb391SAlexey Dobriyan 
nf_ct_net(const struct nf_conn * ct)1585a1fb391SAlexey Dobriyan static inline struct net *nf_ct_net(const struct nf_conn *ct)
1595a1fb391SAlexey Dobriyan {
160c2d9ba9bSEric Dumazet 	return read_pnet(&ct->ct_net);
1615a1fb391SAlexey Dobriyan }
1625a1fb391SAlexey Dobriyan 
1639fb9cbb1SYasuyuki Kozakai /* Alter reply tuple (maybe alter helper). */
1644e77be46SJoe Perches void nf_conntrack_alter_reply(struct nf_conn *ct,
1659fb9cbb1SYasuyuki Kozakai 			      const struct nf_conntrack_tuple *newreply);
1669fb9cbb1SYasuyuki Kozakai 
1679fb9cbb1SYasuyuki Kozakai /* Is this tuple taken? (ignoring any belonging to the given
1689fb9cbb1SYasuyuki Kozakai    conntrack). */
1694e77be46SJoe Perches int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
1709fb9cbb1SYasuyuki Kozakai 			     const struct nf_conn *ignored_conntrack);
1719fb9cbb1SYasuyuki Kozakai 
1729fb9cbb1SYasuyuki Kozakai /* Return conntrack_info and tuple hash for given skb. */
1739fb9cbb1SYasuyuki Kozakai static inline struct nf_conn *
nf_ct_get(const struct sk_buff * skb,enum ip_conntrack_info * ctinfo)1749fb9cbb1SYasuyuki Kozakai nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
1759fb9cbb1SYasuyuki Kozakai {
176261db6c2SJeremy Sowden 	unsigned long nfct = skb_get_nfct(skb);
177a9e419dcSFlorian Westphal 
178261db6c2SJeremy Sowden 	*ctinfo = nfct & NFCT_INFOMASK;
179261db6c2SJeremy Sowden 	return (struct nf_conn *)(nfct & NFCT_PTRMASK);
1809fb9cbb1SYasuyuki Kozakai }
1819fb9cbb1SYasuyuki Kozakai 
1826ae7989cSFlorian Westphal void nf_ct_destroy(struct nf_conntrack *nfct);
1836ae7989cSFlorian Westphal 
184*2954fe60SFlorian Westphal void nf_conntrack_tcp_set_closing(struct nf_conn *ct);
185*2954fe60SFlorian Westphal 
1869fb9cbb1SYasuyuki Kozakai /* decrement reference count on a conntrack */
nf_ct_put(struct nf_conn * ct)1879fb9cbb1SYasuyuki Kozakai static inline void nf_ct_put(struct nf_conn *ct)
1889fb9cbb1SYasuyuki Kozakai {
1896ae7989cSFlorian Westphal 	if (ct && refcount_dec_and_test(&ct->ct_general.use))
1906ae7989cSFlorian Westphal 		nf_ct_destroy(&ct->ct_general);
1919fb9cbb1SYasuyuki Kozakai }
1929fb9cbb1SYasuyuki Kozakai 
193ecb2421bSFlorian Westphal /* load module; enable/disable conntrack in this namespace */
194ecb2421bSFlorian Westphal int nf_ct_netns_get(struct net *net, u8 nfproto);
195ecb2421bSFlorian Westphal void nf_ct_netns_put(struct net *net, u8 nfproto);
196ecb2421bSFlorian Westphal 
197ea781f19SEric Dumazet /*
198ea781f19SEric Dumazet  * Allocate a hashtable of hlist_head (if nulls == 0),
199ea781f19SEric Dumazet  * or hlist_nulls_head (if nulls == 1)
200ea781f19SEric Dumazet  */
2014e77be46SJoe Perches void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls);
202ea781f19SEric Dumazet 
2034e77be46SJoe Perches int nf_conntrack_hash_check_insert(struct nf_conn *ct);
20402982c27SFlorian Westphal bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report);
205c1d10adbSPablo Neira Ayuso 
2064e77be46SJoe Perches bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
207a31f1adcSEric W. Biederman 		       u_int16_t l3num, struct net *net,
208a31f1adcSEric W. Biederman 		       struct nf_conntrack_tuple *tuple);
2099fb9cbb1SYasuyuki Kozakai 
2104e77be46SJoe Perches void __nf_ct_refresh_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
2119fb9cbb1SYasuyuki Kozakai 			  const struct sk_buff *skb,
212cc169213SFlorian Westphal 			  u32 extra_jiffies, bool do_acct);
2139fb9cbb1SYasuyuki Kozakai 
2149fb9cbb1SYasuyuki Kozakai /* Refresh conntrack for this many jiffies and do accounting */
nf_ct_refresh_acct(struct nf_conn * ct,enum ip_conntrack_info ctinfo,const struct sk_buff * skb,u32 extra_jiffies)2159fb9cbb1SYasuyuki Kozakai static inline void nf_ct_refresh_acct(struct nf_conn *ct,
2169fb9cbb1SYasuyuki Kozakai 				      enum ip_conntrack_info ctinfo,
2179fb9cbb1SYasuyuki Kozakai 				      const struct sk_buff *skb,
218cc169213SFlorian Westphal 				      u32 extra_jiffies)
2199fb9cbb1SYasuyuki Kozakai {
220cc169213SFlorian Westphal 	__nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, true);
2219fb9cbb1SYasuyuki Kozakai }
2229fb9cbb1SYasuyuki Kozakai 
2239fb9cbb1SYasuyuki Kozakai /* Refresh conntrack for this many jiffies */
nf_ct_refresh(struct nf_conn * ct,const struct sk_buff * skb,u32 extra_jiffies)2249fb9cbb1SYasuyuki Kozakai static inline void nf_ct_refresh(struct nf_conn *ct,
2259fb9cbb1SYasuyuki Kozakai 				 const struct sk_buff *skb,
226cc169213SFlorian Westphal 				 u32 extra_jiffies)
2279fb9cbb1SYasuyuki Kozakai {
228cc169213SFlorian Westphal 	__nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, false);
2299fb9cbb1SYasuyuki Kozakai }
2309fb9cbb1SYasuyuki Kozakai 
231718d4ad9SFabian Hugelshofer /* kill conntrack and do accounting */
232ad66713fSFlorian Westphal bool nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
233ad66713fSFlorian Westphal 		     const struct sk_buff *skb);
234718d4ad9SFabian Hugelshofer 
235718d4ad9SFabian Hugelshofer /* kill conntrack without accounting */
nf_ct_kill(struct nf_conn * ct)2364c889498SDavid S. Miller static inline bool nf_ct_kill(struct nf_conn *ct)
237718d4ad9SFabian Hugelshofer {
238ad66713fSFlorian Westphal 	return nf_ct_delete(ct, 0, 0);
239718d4ad9SFabian Hugelshofer }
24051091764SPatrick McHardy 
2418169ff58SPablo Neira Ayuso struct nf_ct_iter_data {
2428169ff58SPablo Neira Ayuso 	struct net *net;
2438169ff58SPablo Neira Ayuso 	void *data;
2448169ff58SPablo Neira Ayuso 	u32 portid;
2458169ff58SPablo Neira Ayuso 	int report;
2468169ff58SPablo Neira Ayuso };
2478169ff58SPablo Neira Ayuso 
2489fb9cbb1SYasuyuki Kozakai /* Iterate over all conntracks: if iter returns true, it's deleted. */
2498169ff58SPablo Neira Ayuso void nf_ct_iterate_cleanup_net(int (*iter)(struct nf_conn *i, void *data),
2508169ff58SPablo Neira Ayuso 			       const struct nf_ct_iter_data *iter_data);
251308ac914SDaniel Borkmann 
2522843fb69SFlorian Westphal /* also set unconfirmed conntracks as dying. Only use in module exit path. */
2532843fb69SFlorian Westphal void nf_ct_iterate_destroy(int (*iter)(struct nf_conn *i, void *data),
2542843fb69SFlorian Westphal 			   void *data);
2552843fb69SFlorian Westphal 
256308ac914SDaniel Borkmann struct nf_conntrack_zone;
257308ac914SDaniel Borkmann 
2584e77be46SJoe Perches void nf_conntrack_free(struct nf_conn *ct);
259308ac914SDaniel Borkmann struct nf_conn *nf_conntrack_alloc(struct net *net,
260308ac914SDaniel Borkmann 				   const struct nf_conntrack_zone *zone,
2615a1fb391SAlexey Dobriyan 				   const struct nf_conntrack_tuple *orig,
262b891c5a8SPablo Neira Ayuso 				   const struct nf_conntrack_tuple *repl,
263b891c5a8SPablo Neira Ayuso 				   gfp_t gfp);
2649fb9cbb1SYasuyuki Kozakai 
nf_ct_is_template(const struct nf_conn * ct)265b2a15a60SPatrick McHardy static inline int nf_ct_is_template(const struct nf_conn *ct)
266b2a15a60SPatrick McHardy {
267b2a15a60SPatrick McHardy 	return test_bit(IPS_TEMPLATE_BIT, &ct->status);
268b2a15a60SPatrick McHardy }
269b2a15a60SPatrick McHardy 
2709fb9cbb1SYasuyuki Kozakai /* It's confirmed if it is, or has been in the hash table. */
nf_ct_is_confirmed(const struct nf_conn * ct)271d51ed836SFlorian Westphal static inline int nf_ct_is_confirmed(const struct nf_conn *ct)
2729fb9cbb1SYasuyuki Kozakai {
2739fb9cbb1SYasuyuki Kozakai 	return test_bit(IPS_CONFIRMED_BIT, &ct->status);
2749fb9cbb1SYasuyuki Kozakai }
2759fb9cbb1SYasuyuki Kozakai 
nf_ct_is_dying(const struct nf_conn * ct)276d51ed836SFlorian Westphal static inline int nf_ct_is_dying(const struct nf_conn *ct)
2779fb9cbb1SYasuyuki Kozakai {
2789fb9cbb1SYasuyuki Kozakai 	return test_bit(IPS_DYING_BIT, &ct->status);
2799fb9cbb1SYasuyuki Kozakai }
2809fb9cbb1SYasuyuki Kozakai 
28142c1edd3SJulian Anastasov /* Packet is received from loopback */
nf_is_loopback_packet(const struct sk_buff * skb)28242c1edd3SJulian Anastasov static inline bool nf_is_loopback_packet(const struct sk_buff *skb)
28342c1edd3SJulian Anastasov {
28442c1edd3SJulian Anastasov 	return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK;
28542c1edd3SJulian Anastasov }
28642c1edd3SJulian Anastasov 
287f330a7fdSFlorian Westphal #define nfct_time_stamp ((u32)(jiffies))
288f330a7fdSFlorian Westphal 
289c8607e02SFlorian Westphal /* jiffies until ct expires, 0 if already expired */
nf_ct_expires(const struct nf_conn * ct)290c8607e02SFlorian Westphal static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
291c8607e02SFlorian Westphal {
292802a7dc5SEric Dumazet 	s32 timeout = READ_ONCE(ct->timeout) - nfct_time_stamp;
293c8607e02SFlorian Westphal 
294613a0c67SJiapeng Chong 	return max(timeout, 0);
295c8607e02SFlorian Westphal }
296c8607e02SFlorian Westphal 
nf_ct_is_expired(const struct nf_conn * ct)297f330a7fdSFlorian Westphal static inline bool nf_ct_is_expired(const struct nf_conn *ct)
298f330a7fdSFlorian Westphal {
299802a7dc5SEric Dumazet 	return (__s32)(READ_ONCE(ct->timeout) - nfct_time_stamp) <= 0;
300f330a7fdSFlorian Westphal }
301f330a7fdSFlorian Westphal 
302f330a7fdSFlorian Westphal /* use after obtaining a reference count */
nf_ct_should_gc(const struct nf_conn * ct)303f330a7fdSFlorian Westphal static inline bool nf_ct_should_gc(const struct nf_conn *ct)
304f330a7fdSFlorian Westphal {
305f330a7fdSFlorian Westphal 	return nf_ct_is_expired(ct) && nf_ct_is_confirmed(ct) &&
306f330a7fdSFlorian Westphal 	       !nf_ct_is_dying(ct);
307f330a7fdSFlorian Westphal }
308f330a7fdSFlorian Westphal 
30973f9407bSRoi Dayan #define	NF_CT_DAY	(86400 * HZ)
31073f9407bSRoi Dayan 
31173f9407bSRoi Dayan /* Set an arbitrary timeout large enough not to ever expire, this save
31273f9407bSRoi Dayan  * us a check for the IPS_OFFLOAD_BIT from the packet path via
31373f9407bSRoi Dayan  * nf_ct_is_expired().
31473f9407bSRoi Dayan  */
nf_ct_offload_timeout(struct nf_conn * ct)31573f9407bSRoi Dayan static inline void nf_ct_offload_timeout(struct nf_conn *ct)
31673f9407bSRoi Dayan {
31773f9407bSRoi Dayan 	if (nf_ct_expires(ct) < NF_CT_DAY / 2)
318802a7dc5SEric Dumazet 		WRITE_ONCE(ct->timeout, nfct_time_stamp + NF_CT_DAY);
31973f9407bSRoi Dayan }
32073f9407bSRoi Dayan 
32134641c6dSPaul Gortmaker struct kernel_param;
32234641c6dSPaul Gortmaker 
323e4dca7b7SKees Cook int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp);
3243183ab89SFlorian Westphal int nf_conntrack_hash_resize(unsigned int hashsize);
32592e47ba8SLiping Zhang 
32692e47ba8SLiping Zhang extern struct hlist_nulls_head *nf_conntrack_hash;
3279fb9cbb1SYasuyuki Kozakai extern unsigned int nf_conntrack_htable_size;
3288201d923SAhmed S. Darwish extern seqcount_spinlock_t nf_conntrack_generation;
329e478075cSHagen Paul Pfeifer extern unsigned int nf_conntrack_max;
3309fb9cbb1SYasuyuki Kozakai 
33192e47ba8SLiping Zhang /* must be called with rcu read lock held */
33292e47ba8SLiping Zhang static inline void
nf_conntrack_get_ht(struct hlist_nulls_head ** hash,unsigned int * hsize)33392e47ba8SLiping Zhang nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize)
33492e47ba8SLiping Zhang {
33592e47ba8SLiping Zhang 	struct hlist_nulls_head *hptr;
33692e47ba8SLiping Zhang 	unsigned int sequence, hsz;
33792e47ba8SLiping Zhang 
33892e47ba8SLiping Zhang 	do {
33992e47ba8SLiping Zhang 		sequence = read_seqcount_begin(&nf_conntrack_generation);
34092e47ba8SLiping Zhang 		hsz = nf_conntrack_htable_size;
34192e47ba8SLiping Zhang 		hptr = nf_conntrack_hash;
34292e47ba8SLiping Zhang 	} while (read_seqcount_retry(&nf_conntrack_generation, sequence));
34392e47ba8SLiping Zhang 
34492e47ba8SLiping Zhang 	*hash = hptr;
34592e47ba8SLiping Zhang 	*hsize = hsz;
34692e47ba8SLiping Zhang }
34792e47ba8SLiping Zhang 
348308ac914SDaniel Borkmann struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
349308ac914SDaniel Borkmann 				 const struct nf_conntrack_zone *zone,
350308ac914SDaniel Borkmann 				 gfp_t flags);
3519cf94eabSDaniel Borkmann void nf_ct_tmpl_free(struct nf_conn *tmpl);
352e53376beSPablo Neira Ayuso 
3533c791076SFlorian Westphal u32 nf_ct_get_id(const struct nf_conn *ct);
354c53bd0e9SFlorian Westphal u32 nf_conntrack_count(const struct net *net);
3553c791076SFlorian Westphal 
356c74454faSFlorian Westphal static inline void
nf_ct_set(struct sk_buff * skb,struct nf_conn * ct,enum ip_conntrack_info info)357c74454faSFlorian Westphal nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info)
358c74454faSFlorian Westphal {
359261db6c2SJeremy Sowden 	skb_set_nfct(skb, (unsigned long)ct | info);
360c74454faSFlorian Westphal }
361c74454faSFlorian Westphal 
3620418b989SPablo Neira Ayuso extern unsigned int nf_conntrack_net_id;
3630418b989SPablo Neira Ayuso 
nf_ct_pernet(const struct net * net)3640418b989SPablo Neira Ayuso static inline struct nf_conntrack_net *nf_ct_pernet(const struct net *net)
3650418b989SPablo Neira Ayuso {
3660418b989SPablo Neira Ayuso 	return net_generic(net, nf_conntrack_net_id);
3670418b989SPablo Neira Ayuso }
3680418b989SPablo Neira Ayuso 
36967fc5d7fSXin Long int nf_ct_skb_network_trim(struct sk_buff *skb, int family);
3700785407eSXin Long int nf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
3710785407eSXin Long 			   u16 zone, u8 family, u8 *proto, u16 *mru);
37267fc5d7fSXin Long 
373ac3a546aSEric Dumazet #define NF_CT_STAT_INC(net, count)	  __this_cpu_inc((net)->ct.stat->count)
374ac3a546aSEric Dumazet #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
375242922a0SFlorian Westphal #define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
3769fb9cbb1SYasuyuki Kozakai 
3774dc06f96SPablo Neira Ayuso #define MODULE_ALIAS_NFCT_HELPER(helper) \
3784dc06f96SPablo Neira Ayuso         MODULE_ALIAS("nfct-helper-" helper)
3794dc06f96SPablo Neira Ayuso 
3809fb9cbb1SYasuyuki Kozakai #endif /* _NF_CONNTRACK_H */
381