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