19fb9cbb1SYasuyuki Kozakai /* 29fb9cbb1SYasuyuki Kozakai * Connection state tracking for netfilter. This is separated from, 39fb9cbb1SYasuyuki Kozakai * but required by, the (future) NAT layer; it can also be used by an iptables 49fb9cbb1SYasuyuki Kozakai * extension. 59fb9cbb1SYasuyuki Kozakai * 69fb9cbb1SYasuyuki Kozakai * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> 79fb9cbb1SYasuyuki Kozakai * - generalize L3 protocol dependent part. 89fb9cbb1SYasuyuki Kozakai * 99fb9cbb1SYasuyuki Kozakai * Derived from include/linux/netfiter_ipv4/ip_conntrack.h 109fb9cbb1SYasuyuki Kozakai */ 119fb9cbb1SYasuyuki Kozakai 129fb9cbb1SYasuyuki Kozakai #ifndef _NF_CONNTRACK_H 139fb9cbb1SYasuyuki Kozakai #define _NF_CONNTRACK_H 149fb9cbb1SYasuyuki Kozakai 159fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_common.h> 169fb9cbb1SYasuyuki Kozakai 179fb9cbb1SYasuyuki Kozakai #include <linux/bitops.h> 189fb9cbb1SYasuyuki Kozakai #include <linux/compiler.h> 1960063497SArun Sharma #include <linux/atomic.h> 209fb9cbb1SYasuyuki Kozakai 219fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_tcp.h> 222bc78049SPatrick McHardy #include <linux/netfilter/nf_conntrack_dccp.h> 239fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_sctp.h> 24f09943feSPatrick McHardy #include <linux/netfilter/nf_conntrack_proto_gre.h> 259fb9cbb1SYasuyuki Kozakai #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 269fb9cbb1SYasuyuki Kozakai 279fb9cbb1SYasuyuki Kozakai #include <net/netfilter/nf_conntrack_tuple.h> 289fb9cbb1SYasuyuki Kozakai 299fb9cbb1SYasuyuki Kozakai /* per conntrack: protocol private data */ 309fb9cbb1SYasuyuki Kozakai union nf_conntrack_proto { 319fb9cbb1SYasuyuki Kozakai /* insert conntrack proto private data here */ 322bc78049SPatrick McHardy struct nf_ct_dccp dccp; 339fb9cbb1SYasuyuki Kozakai struct ip_ct_sctp sctp; 349fb9cbb1SYasuyuki Kozakai struct ip_ct_tcp tcp; 35f09943feSPatrick McHardy struct nf_ct_gre gre; 369fb9cbb1SYasuyuki Kozakai }; 379fb9cbb1SYasuyuki Kozakai 389fb9cbb1SYasuyuki Kozakai union nf_conntrack_expect_proto { 399fb9cbb1SYasuyuki Kozakai /* insert expect proto private data here */ 409fb9cbb1SYasuyuki Kozakai }; 419fb9cbb1SYasuyuki Kozakai 429fb9cbb1SYasuyuki Kozakai #include <linux/types.h> 439fb9cbb1SYasuyuki Kozakai #include <linux/skbuff.h> 44d7fe0f24SAl Viro #include <linux/timer.h> 459fb9cbb1SYasuyuki Kozakai 469fb9cbb1SYasuyuki Kozakai #ifdef CONFIG_NETFILTER_DEBUG 4755871d04SPatrick McHardy #define NF_CT_ASSERT(x) WARN_ON(!(x)) 489fb9cbb1SYasuyuki Kozakai #else 499fb9cbb1SYasuyuki Kozakai #define NF_CT_ASSERT(x) 509fb9cbb1SYasuyuki Kozakai #endif 519fb9cbb1SYasuyuki Kozakai 529fb9cbb1SYasuyuki Kozakai struct nf_conntrack_helper; 539fb9cbb1SYasuyuki Kozakai 546002f266SPatrick McHardy /* Must be kept in sync with the classes defined by helpers */ 559d288dffSPatrick McHardy #define NF_CT_MAX_EXPECT_CLASSES 4 566002f266SPatrick McHardy 57dc808fe2SHarald Welte /* nf_conn feature for connections that have a helper */ 58dc808fe2SHarald Welte struct nf_conn_help { 59dc808fe2SHarald Welte /* Helper. if any */ 600906a372SArnd Bergmann struct nf_conntrack_helper __rcu *helper; 61dc808fe2SHarald Welte 62b560580aSPatrick McHardy struct hlist_head expectations; 63b560580aSPatrick McHardy 64dc808fe2SHarald Welte /* Current number of expected connections */ 656002f266SPatrick McHardy u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; 661afc5679SPablo Neira Ayuso 671afc5679SPablo Neira Ayuso /* private helper information. */ 681afc5679SPablo Neira Ayuso char data[]; 69dc808fe2SHarald Welte }; 70dc808fe2SHarald Welte 719fb9cbb1SYasuyuki Kozakai #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 72f8eb24a8SPatrick McHardy #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 73f8eb24a8SPatrick McHardy 74ea781f19SEric Dumazet struct nf_conn { 759fb9cbb1SYasuyuki Kozakai /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, 76b476b72aSJesper Dangaard Brouer * plus 1 for any connection(s) we are `master' for 77b476b72aSJesper Dangaard Brouer * 78b476b72aSJesper Dangaard Brouer * Hint, SKB address this struct and refcnt via skb->nfct and 79b476b72aSJesper Dangaard Brouer * helpers nf_conntrack_get() and nf_conntrack_put(). 80b476b72aSJesper Dangaard Brouer * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt, 81b476b72aSJesper Dangaard Brouer * beware nf_ct_get() is different and don't inc refcnt. 82b476b72aSJesper Dangaard Brouer */ 839fb9cbb1SYasuyuki Kozakai struct nf_conntrack ct_general; 849fb9cbb1SYasuyuki Kozakai 85440f0d58SPatrick McHardy spinlock_t lock; 86b7779d06SJesper Dangaard Brouer u16 cpu; 87440f0d58SPatrick McHardy 886c8dee98SFlorian Westphal #ifdef CONFIG_NF_CONNTRACK_ZONES 896c8dee98SFlorian Westphal struct nf_conntrack_zone zone; 906c8dee98SFlorian Westphal #endif 919fb9cbb1SYasuyuki Kozakai /* XXX should I move this to the tail ? - Y.K */ 929fb9cbb1SYasuyuki Kozakai /* These are my tuples; original and reply */ 939fb9cbb1SYasuyuki Kozakai struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; 949fb9cbb1SYasuyuki Kozakai 959fb9cbb1SYasuyuki Kozakai /* Have we seen traffic both ways yet? (bitset) */ 969fb9cbb1SYasuyuki Kozakai unsigned long status; 979fb9cbb1SYasuyuki Kozakai 989fb9cbb1SYasuyuki Kozakai /* Timer function; drops refcnt when it goes off. */ 999fb9cbb1SYasuyuki Kozakai struct timer_list timeout; 1009fb9cbb1SYasuyuki Kozakai 1010c5c9fb5SEric W. Biederman possible_net_t ct_net; 1020c5c9fb5SEric W. Biederman 103c41884ceSFlorian Westphal /* all members below initialized via memset */ 104c41884ceSFlorian Westphal u8 __nfct_init_offset[0]; 105c41884ceSFlorian Westphal 106c41884ceSFlorian Westphal /* If we were expected by an expectation, this will be it */ 107c41884ceSFlorian Westphal struct nf_conn *master; 108c41884ceSFlorian Westphal 1099fb9cbb1SYasuyuki Kozakai #if defined(CONFIG_NF_CONNTRACK_MARK) 1109fb9cbb1SYasuyuki Kozakai u_int32_t mark; 1119fb9cbb1SYasuyuki Kozakai #endif 1129fb9cbb1SYasuyuki Kozakai 1137c9728c3SJames Morris #ifdef CONFIG_NF_CONNTRACK_SECMARK 1147c9728c3SJames Morris u_int32_t secmark; 1157c9728c3SJames Morris #endif 1167c9728c3SJames Morris 117ecfab2c9SYasuyuki Kozakai /* Extensions */ 118ecfab2c9SYasuyuki Kozakai struct nf_ct_ext *ext; 119e5fc9e7aSChangli Gao 120e5fc9e7aSChangli Gao /* Storage reserved for other modules, must be the last member */ 121e5fc9e7aSChangli Gao union nf_conntrack_proto proto; 1229fb9cbb1SYasuyuki Kozakai }; 1239fb9cbb1SYasuyuki Kozakai 1249fb9cbb1SYasuyuki Kozakai static inline struct nf_conn * 1259fb9cbb1SYasuyuki Kozakai nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) 1269fb9cbb1SYasuyuki Kozakai { 1279fb9cbb1SYasuyuki Kozakai return container_of(hash, struct nf_conn, 1289fb9cbb1SYasuyuki Kozakai tuplehash[hash->tuple.dst.dir]); 1299fb9cbb1SYasuyuki Kozakai } 1309fb9cbb1SYasuyuki Kozakai 1315e8fbe2aSPatrick McHardy static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct) 1325e8fbe2aSPatrick McHardy { 1335e8fbe2aSPatrick McHardy return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 1345e8fbe2aSPatrick McHardy } 1355e8fbe2aSPatrick McHardy 1365e8fbe2aSPatrick McHardy static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct) 1375e8fbe2aSPatrick McHardy { 1385e8fbe2aSPatrick McHardy return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 1395e8fbe2aSPatrick McHardy } 1405e8fbe2aSPatrick McHardy 141f2f3e38cSPablo Neira Ayuso #define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple) 142f2f3e38cSPablo Neira Ayuso 1439fb9cbb1SYasuyuki Kozakai /* get master conntrack via master expectation */ 1449fb9cbb1SYasuyuki Kozakai #define master_ct(conntr) (conntr->master) 1459fb9cbb1SYasuyuki Kozakai 1465a1fb391SAlexey Dobriyan extern struct net init_net; 1475a1fb391SAlexey Dobriyan 1485a1fb391SAlexey Dobriyan static inline struct net *nf_ct_net(const struct nf_conn *ct) 1495a1fb391SAlexey Dobriyan { 150c2d9ba9bSEric Dumazet return read_pnet(&ct->ct_net); 1515a1fb391SAlexey Dobriyan } 1525a1fb391SAlexey Dobriyan 1539fb9cbb1SYasuyuki Kozakai /* Alter reply tuple (maybe alter helper). */ 1544e77be46SJoe Perches void nf_conntrack_alter_reply(struct nf_conn *ct, 1559fb9cbb1SYasuyuki Kozakai const struct nf_conntrack_tuple *newreply); 1569fb9cbb1SYasuyuki Kozakai 1579fb9cbb1SYasuyuki Kozakai /* Is this tuple taken? (ignoring any belonging to the given 1589fb9cbb1SYasuyuki Kozakai conntrack). */ 1594e77be46SJoe Perches int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 1609fb9cbb1SYasuyuki Kozakai const struct nf_conn *ignored_conntrack); 1619fb9cbb1SYasuyuki Kozakai 1629fb9cbb1SYasuyuki Kozakai /* Return conntrack_info and tuple hash for given skb. */ 1639fb9cbb1SYasuyuki Kozakai static inline struct nf_conn * 1649fb9cbb1SYasuyuki Kozakai nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) 1659fb9cbb1SYasuyuki Kozakai { 1669fb9cbb1SYasuyuki Kozakai *ctinfo = skb->nfctinfo; 1679fb9cbb1SYasuyuki Kozakai return (struct nf_conn *)skb->nfct; 1689fb9cbb1SYasuyuki Kozakai } 1699fb9cbb1SYasuyuki Kozakai 1709fb9cbb1SYasuyuki Kozakai /* decrement reference count on a conntrack */ 1719fb9cbb1SYasuyuki Kozakai static inline void nf_ct_put(struct nf_conn *ct) 1729fb9cbb1SYasuyuki Kozakai { 1739fb9cbb1SYasuyuki Kozakai NF_CT_ASSERT(ct); 1749fb9cbb1SYasuyuki Kozakai nf_conntrack_put(&ct->ct_general); 1759fb9cbb1SYasuyuki Kozakai } 1769fb9cbb1SYasuyuki Kozakai 177b9f78f9fSPablo Neira Ayuso /* Protocol module loading */ 1784e77be46SJoe Perches int nf_ct_l3proto_try_module_get(unsigned short l3proto); 1794e77be46SJoe Perches void nf_ct_l3proto_module_put(unsigned short l3proto); 180b9f78f9fSPablo Neira Ayuso 181ea781f19SEric Dumazet /* 182ea781f19SEric Dumazet * Allocate a hashtable of hlist_head (if nulls == 0), 183ea781f19SEric Dumazet * or hlist_nulls_head (if nulls == 1) 184ea781f19SEric Dumazet */ 1854e77be46SJoe Perches void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls); 186ea781f19SEric Dumazet 1874e77be46SJoe Perches void nf_ct_free_hashtable(void *hash, unsigned int size); 188ac565e5fSPatrick McHardy 1894e77be46SJoe Perches int nf_conntrack_hash_check_insert(struct nf_conn *ct); 19002982c27SFlorian Westphal bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report); 191c1d10adbSPablo Neira Ayuso 1924e77be46SJoe Perches bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff, 193a31f1adcSEric W. Biederman u_int16_t l3num, struct net *net, 194a31f1adcSEric W. Biederman struct nf_conntrack_tuple *tuple); 1954e77be46SJoe Perches bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 1969fb9cbb1SYasuyuki Kozakai const struct nf_conntrack_tuple *orig); 1979fb9cbb1SYasuyuki Kozakai 1984e77be46SJoe Perches void __nf_ct_refresh_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo, 1999fb9cbb1SYasuyuki Kozakai const struct sk_buff *skb, 2004e77be46SJoe Perches unsigned long extra_jiffies, int do_acct); 2019fb9cbb1SYasuyuki Kozakai 2029fb9cbb1SYasuyuki Kozakai /* Refresh conntrack for this many jiffies and do accounting */ 2039fb9cbb1SYasuyuki Kozakai static inline void nf_ct_refresh_acct(struct nf_conn *ct, 2049fb9cbb1SYasuyuki Kozakai enum ip_conntrack_info ctinfo, 2059fb9cbb1SYasuyuki Kozakai const struct sk_buff *skb, 2069fb9cbb1SYasuyuki Kozakai unsigned long extra_jiffies) 2079fb9cbb1SYasuyuki Kozakai { 2089fb9cbb1SYasuyuki Kozakai __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1); 2099fb9cbb1SYasuyuki Kozakai } 2109fb9cbb1SYasuyuki Kozakai 2119fb9cbb1SYasuyuki Kozakai /* Refresh conntrack for this many jiffies */ 2129fb9cbb1SYasuyuki Kozakai static inline void nf_ct_refresh(struct nf_conn *ct, 2139fb9cbb1SYasuyuki Kozakai const struct sk_buff *skb, 2149fb9cbb1SYasuyuki Kozakai unsigned long extra_jiffies) 2159fb9cbb1SYasuyuki Kozakai { 2169fb9cbb1SYasuyuki Kozakai __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0); 2179fb9cbb1SYasuyuki Kozakai } 2189fb9cbb1SYasuyuki Kozakai 2194e77be46SJoe Perches bool __nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo, 2204e77be46SJoe Perches const struct sk_buff *skb, int do_acct); 221718d4ad9SFabian Hugelshofer 222718d4ad9SFabian Hugelshofer /* kill conntrack and do accounting */ 2234c889498SDavid S. Miller static inline bool nf_ct_kill_acct(struct nf_conn *ct, 224718d4ad9SFabian Hugelshofer enum ip_conntrack_info ctinfo, 225718d4ad9SFabian Hugelshofer const struct sk_buff *skb) 226718d4ad9SFabian Hugelshofer { 2274c889498SDavid S. Miller return __nf_ct_kill_acct(ct, ctinfo, skb, 1); 228718d4ad9SFabian Hugelshofer } 229718d4ad9SFabian Hugelshofer 230718d4ad9SFabian Hugelshofer /* kill conntrack without accounting */ 2314c889498SDavid S. Miller static inline bool nf_ct_kill(struct nf_conn *ct) 232718d4ad9SFabian Hugelshofer { 2334c889498SDavid S. Miller return __nf_ct_kill_acct(ct, 0, NULL, 0); 234718d4ad9SFabian Hugelshofer } 23551091764SPatrick McHardy 2369fb9cbb1SYasuyuki Kozakai /* These are for NAT. Icky. */ 2372d89c68aSPatrick McHardy extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct, 238f9dd09c7SJozsef Kadlecsik enum ip_conntrack_dir dir, 239f9dd09c7SJozsef Kadlecsik u32 seq); 2409fb9cbb1SYasuyuki Kozakai 2419fb9cbb1SYasuyuki Kozakai /* Fake conntrack entry for untracked connections */ 242b3c5163fSEric Dumazet DECLARE_PER_CPU(struct nf_conn, nf_conntrack_untracked); 2435bfddbd4SEric Dumazet static inline struct nf_conn *nf_ct_untracked_get(void) 2445bfddbd4SEric Dumazet { 245903ceff7SChristoph Lameter return raw_cpu_ptr(&nf_conntrack_untracked); 2465bfddbd4SEric Dumazet } 2474e77be46SJoe Perches void nf_ct_untracked_status_or(unsigned long bits); 2485bfddbd4SEric Dumazet 2499fb9cbb1SYasuyuki Kozakai /* Iterate over all conntracks: if iter returns true, it's deleted. */ 2504e77be46SJoe Perches void nf_ct_iterate_cleanup(struct net *net, 251c655bc68SFlorian Westphal int (*iter)(struct nf_conn *i, void *data), 252c655bc68SFlorian Westphal void *data, u32 portid, int report); 253308ac914SDaniel Borkmann 254308ac914SDaniel Borkmann struct nf_conntrack_zone; 255308ac914SDaniel Borkmann 2564e77be46SJoe Perches void nf_conntrack_free(struct nf_conn *ct); 257308ac914SDaniel Borkmann struct nf_conn *nf_conntrack_alloc(struct net *net, 258308ac914SDaniel Borkmann const struct nf_conntrack_zone *zone, 2595a1fb391SAlexey Dobriyan const struct nf_conntrack_tuple *orig, 260b891c5a8SPablo Neira Ayuso const struct nf_conntrack_tuple *repl, 261b891c5a8SPablo Neira Ayuso gfp_t gfp); 2629fb9cbb1SYasuyuki Kozakai 263b2a15a60SPatrick McHardy static inline int nf_ct_is_template(const struct nf_conn *ct) 264b2a15a60SPatrick McHardy { 265b2a15a60SPatrick McHardy return test_bit(IPS_TEMPLATE_BIT, &ct->status); 266b2a15a60SPatrick McHardy } 267b2a15a60SPatrick McHardy 2689fb9cbb1SYasuyuki Kozakai /* It's confirmed if it is, or has been in the hash table. */ 2699fb9cbb1SYasuyuki Kozakai static inline int nf_ct_is_confirmed(struct nf_conn *ct) 2709fb9cbb1SYasuyuki Kozakai { 2719fb9cbb1SYasuyuki Kozakai return test_bit(IPS_CONFIRMED_BIT, &ct->status); 2729fb9cbb1SYasuyuki Kozakai } 2739fb9cbb1SYasuyuki Kozakai 2749fb9cbb1SYasuyuki Kozakai static inline int nf_ct_is_dying(struct nf_conn *ct) 2759fb9cbb1SYasuyuki Kozakai { 2769fb9cbb1SYasuyuki Kozakai return test_bit(IPS_DYING_BIT, &ct->status); 2779fb9cbb1SYasuyuki Kozakai } 2789fb9cbb1SYasuyuki Kozakai 2795bfddbd4SEric Dumazet static inline int nf_ct_is_untracked(const struct nf_conn *ct) 280587aa641SPatrick McHardy { 2815bfddbd4SEric Dumazet return test_bit(IPS_UNTRACKED_BIT, &ct->status); 282587aa641SPatrick McHardy } 283587aa641SPatrick McHardy 28442c1edd3SJulian Anastasov /* Packet is received from loopback */ 28542c1edd3SJulian Anastasov static inline bool nf_is_loopback_packet(const struct sk_buff *skb) 28642c1edd3SJulian Anastasov { 28742c1edd3SJulian Anastasov return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK; 28842c1edd3SJulian Anastasov } 28942c1edd3SJulian Anastasov 29034641c6dSPaul Gortmaker struct kernel_param; 29134641c6dSPaul Gortmaker 2924e77be46SJoe Perches int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); 2939fb9cbb1SYasuyuki Kozakai extern unsigned int nf_conntrack_htable_size; 294e478075cSHagen Paul Pfeifer extern unsigned int nf_conntrack_max; 2959fb9cbb1SYasuyuki Kozakai 296308ac914SDaniel Borkmann struct nf_conn *nf_ct_tmpl_alloc(struct net *net, 297308ac914SDaniel Borkmann const struct nf_conntrack_zone *zone, 298308ac914SDaniel Borkmann gfp_t flags); 2999cf94eabSDaniel Borkmann void nf_ct_tmpl_free(struct nf_conn *tmpl); 300e53376beSPablo Neira Ayuso 301ac3a546aSEric Dumazet #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) 302ac3a546aSEric Dumazet #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) 3039fb9cbb1SYasuyuki Kozakai 3044dc06f96SPablo Neira Ayuso #define MODULE_ALIAS_NFCT_HELPER(helper) \ 3054dc06f96SPablo Neira Ayuso MODULE_ALIAS("nfct-helper-" helper) 3064dc06f96SPablo Neira Ayuso 3079fb9cbb1SYasuyuki Kozakai #endif /* _NF_CONNTRACK_H */ 308