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 #ifdef __KERNEL__ 189fb9cbb1SYasuyuki Kozakai #include <linux/bitops.h> 199fb9cbb1SYasuyuki Kozakai #include <linux/compiler.h> 209fb9cbb1SYasuyuki Kozakai #include <asm/atomic.h> 219fb9cbb1SYasuyuki Kozakai 229fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_tcp.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/ipv4/nf_conntrack_icmp.h> 269fb9cbb1SYasuyuki Kozakai #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 279fb9cbb1SYasuyuki Kozakai 289fb9cbb1SYasuyuki Kozakai #include <net/netfilter/nf_conntrack_tuple.h> 299fb9cbb1SYasuyuki Kozakai 309fb9cbb1SYasuyuki Kozakai /* per conntrack: protocol private data */ 319fb9cbb1SYasuyuki Kozakai union nf_conntrack_proto { 329fb9cbb1SYasuyuki Kozakai /* insert conntrack proto private data here */ 339fb9cbb1SYasuyuki Kozakai struct ip_ct_sctp sctp; 349fb9cbb1SYasuyuki Kozakai struct ip_ct_tcp tcp; 359fb9cbb1SYasuyuki Kozakai struct ip_ct_icmp icmp; 369fb9cbb1SYasuyuki Kozakai struct nf_ct_icmpv6 icmpv6; 37f09943feSPatrick McHardy struct nf_ct_gre gre; 389fb9cbb1SYasuyuki Kozakai }; 399fb9cbb1SYasuyuki Kozakai 409fb9cbb1SYasuyuki Kozakai union nf_conntrack_expect_proto { 419fb9cbb1SYasuyuki Kozakai /* insert expect proto private data here */ 429fb9cbb1SYasuyuki Kozakai }; 439fb9cbb1SYasuyuki Kozakai 449fb9cbb1SYasuyuki Kozakai /* Add protocol helper include file here */ 459fb9cbb1SYasuyuki Kozakai #include <linux/netfilter/nf_conntrack_ftp.h> 46f09943feSPatrick McHardy #include <linux/netfilter/nf_conntrack_pptp.h> 47f587de0eSPatrick McHardy #include <linux/netfilter/nf_conntrack_h323.h> 486fecd198SMichal Schmidt #include <linux/netfilter/nf_conntrack_sane.h> 499fb9cbb1SYasuyuki Kozakai 509fb9cbb1SYasuyuki Kozakai /* per conntrack: application helper private data */ 519fb9cbb1SYasuyuki Kozakai union nf_conntrack_help { 529fb9cbb1SYasuyuki Kozakai /* insert conntrack helper private data (master) here */ 5355a73324SJozsef Kadlecsik struct nf_ct_ftp_master ct_ftp_info; 54f09943feSPatrick McHardy struct nf_ct_pptp_master ct_pptp_info; 55f587de0eSPatrick McHardy struct nf_ct_h323_master ct_h323_info; 566fecd198SMichal Schmidt struct nf_ct_sane_master ct_sane_info; 579fb9cbb1SYasuyuki Kozakai }; 589fb9cbb1SYasuyuki Kozakai 599fb9cbb1SYasuyuki Kozakai #include <linux/types.h> 609fb9cbb1SYasuyuki Kozakai #include <linux/skbuff.h> 61d7fe0f24SAl Viro #include <linux/timer.h> 629fb9cbb1SYasuyuki Kozakai 639fb9cbb1SYasuyuki Kozakai #ifdef CONFIG_NETFILTER_DEBUG 649fb9cbb1SYasuyuki Kozakai #define NF_CT_ASSERT(x) \ 659fb9cbb1SYasuyuki Kozakai do { \ 669fb9cbb1SYasuyuki Kozakai if (!(x)) \ 679fb9cbb1SYasuyuki Kozakai /* Wooah! I'm tripping my conntrack in a frenzy of \ 689fb9cbb1SYasuyuki Kozakai netplay... */ \ 699fb9cbb1SYasuyuki Kozakai printk("NF_CT_ASSERT: %s:%i(%s)\n", \ 709fb9cbb1SYasuyuki Kozakai __FILE__, __LINE__, __FUNCTION__); \ 719fb9cbb1SYasuyuki Kozakai } while(0) 729fb9cbb1SYasuyuki Kozakai #else 739fb9cbb1SYasuyuki Kozakai #define NF_CT_ASSERT(x) 749fb9cbb1SYasuyuki Kozakai #endif 759fb9cbb1SYasuyuki Kozakai 769fb9cbb1SYasuyuki Kozakai struct nf_conntrack_helper; 779fb9cbb1SYasuyuki Kozakai 78dc808fe2SHarald Welte /* nf_conn feature for connections that have a helper */ 79dc808fe2SHarald Welte struct nf_conn_help { 80dc808fe2SHarald Welte /* Helper. if any */ 81dc808fe2SHarald Welte struct nf_conntrack_helper *helper; 82dc808fe2SHarald Welte 83dc808fe2SHarald Welte union nf_conntrack_help help; 84dc808fe2SHarald Welte 85dc808fe2SHarald Welte /* Current number of expected connections */ 86dc808fe2SHarald Welte unsigned int expecting; 87dc808fe2SHarald Welte }; 88dc808fe2SHarald Welte 89dc808fe2SHarald Welte 909fb9cbb1SYasuyuki Kozakai #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 91f8eb24a8SPatrick McHardy #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 92f8eb24a8SPatrick McHardy 939fb9cbb1SYasuyuki Kozakai struct nf_conn 949fb9cbb1SYasuyuki Kozakai { 959fb9cbb1SYasuyuki Kozakai /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, 969fb9cbb1SYasuyuki Kozakai plus 1 for any connection(s) we are `master' for */ 979fb9cbb1SYasuyuki Kozakai struct nf_conntrack ct_general; 989fb9cbb1SYasuyuki Kozakai 999fb9cbb1SYasuyuki Kozakai /* XXX should I move this to the tail ? - Y.K */ 1009fb9cbb1SYasuyuki Kozakai /* These are my tuples; original and reply */ 1019fb9cbb1SYasuyuki Kozakai struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; 1029fb9cbb1SYasuyuki Kozakai 1039fb9cbb1SYasuyuki Kozakai /* Have we seen traffic both ways yet? (bitset) */ 1049fb9cbb1SYasuyuki Kozakai unsigned long status; 1059fb9cbb1SYasuyuki Kozakai 106dc808fe2SHarald Welte /* If we were expected by an expectation, this will be it */ 107dc808fe2SHarald Welte struct nf_conn *master; 108dc808fe2SHarald Welte 1099fb9cbb1SYasuyuki Kozakai /* Timer function; drops refcnt when it goes off. */ 1109fb9cbb1SYasuyuki Kozakai struct timer_list timeout; 1119fb9cbb1SYasuyuki Kozakai 1129fb9cbb1SYasuyuki Kozakai #ifdef CONFIG_NF_CT_ACCT 1139fb9cbb1SYasuyuki Kozakai /* Accounting Information (same cache line as other written members) */ 1149fb9cbb1SYasuyuki Kozakai struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; 1159fb9cbb1SYasuyuki Kozakai #endif 1169fb9cbb1SYasuyuki Kozakai 117c1d10adbSPablo Neira Ayuso /* Unique ID that identifies this conntrack*/ 118c1d10adbSPablo Neira Ayuso unsigned int id; 119c1d10adbSPablo Neira Ayuso 1209fb9cbb1SYasuyuki Kozakai /* features - nat, helper, ... used by allocating system */ 1219fb9cbb1SYasuyuki Kozakai u_int32_t features; 1229fb9cbb1SYasuyuki Kozakai 1239fb9cbb1SYasuyuki Kozakai #if defined(CONFIG_NF_CONNTRACK_MARK) 1249fb9cbb1SYasuyuki Kozakai u_int32_t mark; 1259fb9cbb1SYasuyuki Kozakai #endif 1269fb9cbb1SYasuyuki Kozakai 1277c9728c3SJames Morris #ifdef CONFIG_NF_CONNTRACK_SECMARK 1287c9728c3SJames Morris u_int32_t secmark; 1297c9728c3SJames Morris #endif 1307c9728c3SJames Morris 131dc808fe2SHarald Welte /* Storage reserved for other modules: */ 132dc808fe2SHarald Welte union nf_conntrack_proto proto; 1339fb9cbb1SYasuyuki Kozakai 134dc808fe2SHarald Welte /* features dynamically at the end: helper, nat (both optional) */ 135dc808fe2SHarald Welte char data[0]; 1369fb9cbb1SYasuyuki Kozakai }; 1379fb9cbb1SYasuyuki Kozakai 1389fb9cbb1SYasuyuki Kozakai static inline struct nf_conn * 1399fb9cbb1SYasuyuki Kozakai nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) 1409fb9cbb1SYasuyuki Kozakai { 1419fb9cbb1SYasuyuki Kozakai return container_of(hash, struct nf_conn, 1429fb9cbb1SYasuyuki Kozakai tuplehash[hash->tuple.dst.dir]); 1439fb9cbb1SYasuyuki Kozakai } 1449fb9cbb1SYasuyuki Kozakai 1459fb9cbb1SYasuyuki Kozakai /* get master conntrack via master expectation */ 1469fb9cbb1SYasuyuki Kozakai #define master_ct(conntr) (conntr->master) 1479fb9cbb1SYasuyuki Kozakai 1489fb9cbb1SYasuyuki Kozakai /* Alter reply tuple (maybe alter helper). */ 1499fb9cbb1SYasuyuki Kozakai extern void 1509fb9cbb1SYasuyuki Kozakai nf_conntrack_alter_reply(struct nf_conn *conntrack, 1519fb9cbb1SYasuyuki Kozakai const struct nf_conntrack_tuple *newreply); 1529fb9cbb1SYasuyuki Kozakai 1539fb9cbb1SYasuyuki Kozakai /* Is this tuple taken? (ignoring any belonging to the given 1549fb9cbb1SYasuyuki Kozakai conntrack). */ 1559fb9cbb1SYasuyuki Kozakai extern int 1569fb9cbb1SYasuyuki Kozakai nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 1579fb9cbb1SYasuyuki Kozakai const struct nf_conn *ignored_conntrack); 1589fb9cbb1SYasuyuki Kozakai 1599fb9cbb1SYasuyuki Kozakai /* Return conntrack_info and tuple hash for given skb. */ 1609fb9cbb1SYasuyuki Kozakai static inline struct nf_conn * 1619fb9cbb1SYasuyuki Kozakai nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) 1629fb9cbb1SYasuyuki Kozakai { 1639fb9cbb1SYasuyuki Kozakai *ctinfo = skb->nfctinfo; 1649fb9cbb1SYasuyuki Kozakai return (struct nf_conn *)skb->nfct; 1659fb9cbb1SYasuyuki Kozakai } 1669fb9cbb1SYasuyuki Kozakai 1679fb9cbb1SYasuyuki Kozakai /* decrement reference count on a conntrack */ 1689fb9cbb1SYasuyuki Kozakai static inline void nf_ct_put(struct nf_conn *ct) 1699fb9cbb1SYasuyuki Kozakai { 1709fb9cbb1SYasuyuki Kozakai NF_CT_ASSERT(ct); 1719fb9cbb1SYasuyuki Kozakai nf_conntrack_put(&ct->ct_general); 1729fb9cbb1SYasuyuki Kozakai } 1739fb9cbb1SYasuyuki Kozakai 174b9f78f9fSPablo Neira Ayuso /* Protocol module loading */ 175b9f78f9fSPablo Neira Ayuso extern int nf_ct_l3proto_try_module_get(unsigned short l3proto); 176b9f78f9fSPablo Neira Ayuso extern void nf_ct_l3proto_module_put(unsigned short l3proto); 177b9f78f9fSPablo Neira Ayuso 178c1d10adbSPablo Neira Ayuso extern struct nf_conntrack_tuple_hash * 179c1d10adbSPablo Neira Ayuso __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, 180c1d10adbSPablo Neira Ayuso const struct nf_conn *ignored_conntrack); 181c1d10adbSPablo Neira Ayuso 182c1d10adbSPablo Neira Ayuso extern void nf_conntrack_hash_insert(struct nf_conn *ct); 183c1d10adbSPablo Neira Ayuso 184c1d10adbSPablo Neira Ayuso extern void nf_conntrack_flush(void); 185c1d10adbSPablo Neira Ayuso 186c1d10adbSPablo Neira Ayuso extern struct nf_conntrack_helper * 187c1d10adbSPablo Neira Ayuso nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple); 188c1d10adbSPablo Neira Ayuso extern void nf_ct_helper_put(struct nf_conntrack_helper *helper); 189c1d10adbSPablo Neira Ayuso 190c1d10adbSPablo Neira Ayuso extern struct nf_conntrack_helper * 191c1d10adbSPablo Neira Ayuso __nf_conntrack_helper_find_byname(const char *name); 192c1d10adbSPablo Neira Ayuso 1939fb9cbb1SYasuyuki Kozakai extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 1949fb9cbb1SYasuyuki Kozakai const struct nf_conntrack_tuple *orig); 1959fb9cbb1SYasuyuki Kozakai 1969fb9cbb1SYasuyuki Kozakai extern void __nf_ct_refresh_acct(struct nf_conn *ct, 1979fb9cbb1SYasuyuki Kozakai enum ip_conntrack_info ctinfo, 1989fb9cbb1SYasuyuki Kozakai const struct sk_buff *skb, 1999fb9cbb1SYasuyuki Kozakai unsigned long extra_jiffies, 2009fb9cbb1SYasuyuki Kozakai 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 2199fb9cbb1SYasuyuki Kozakai /* These are for NAT. Icky. */ 2209fb9cbb1SYasuyuki Kozakai /* Update TCP window tracking data when NAT mangles the packet */ 2219fb9cbb1SYasuyuki Kozakai extern void nf_conntrack_tcp_update(struct sk_buff *skb, 2229fb9cbb1SYasuyuki Kozakai unsigned int dataoff, 2239fb9cbb1SYasuyuki Kozakai struct nf_conn *conntrack, 2249fb9cbb1SYasuyuki Kozakai int dir); 2259fb9cbb1SYasuyuki Kozakai 2269fb9cbb1SYasuyuki Kozakai /* Call me when a conntrack is destroyed. */ 2279fb9cbb1SYasuyuki Kozakai extern void (*nf_conntrack_destroyed)(struct nf_conn *conntrack); 2289fb9cbb1SYasuyuki Kozakai 2299fb9cbb1SYasuyuki Kozakai /* Fake conntrack entry for untracked connections */ 2309fb9cbb1SYasuyuki Kozakai extern struct nf_conn nf_conntrack_untracked; 2319fb9cbb1SYasuyuki Kozakai 2329fb9cbb1SYasuyuki Kozakai extern int nf_ct_no_defrag; 2339fb9cbb1SYasuyuki Kozakai 2349fb9cbb1SYasuyuki Kozakai /* Iterate over all conntracks: if iter returns true, it's deleted. */ 2359fb9cbb1SYasuyuki Kozakai extern void 2369fb9cbb1SYasuyuki Kozakai nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data); 2379fb9cbb1SYasuyuki Kozakai extern void nf_conntrack_free(struct nf_conn *ct); 2389fb9cbb1SYasuyuki Kozakai extern struct nf_conn * 2399fb9cbb1SYasuyuki Kozakai nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 2409fb9cbb1SYasuyuki Kozakai const struct nf_conntrack_tuple *repl); 2419fb9cbb1SYasuyuki Kozakai 2429fb9cbb1SYasuyuki Kozakai /* It's confirmed if it is, or has been in the hash table. */ 2439fb9cbb1SYasuyuki Kozakai static inline int nf_ct_is_confirmed(struct nf_conn *ct) 2449fb9cbb1SYasuyuki Kozakai { 2459fb9cbb1SYasuyuki Kozakai return test_bit(IPS_CONFIRMED_BIT, &ct->status); 2469fb9cbb1SYasuyuki Kozakai } 2479fb9cbb1SYasuyuki Kozakai 2489fb9cbb1SYasuyuki Kozakai static inline int nf_ct_is_dying(struct nf_conn *ct) 2499fb9cbb1SYasuyuki Kozakai { 2509fb9cbb1SYasuyuki Kozakai return test_bit(IPS_DYING_BIT, &ct->status); 2519fb9cbb1SYasuyuki Kozakai } 2529fb9cbb1SYasuyuki Kozakai 2539fb9cbb1SYasuyuki Kozakai extern unsigned int nf_conntrack_htable_size; 25439a27a35SPatrick McHardy extern int nf_conntrack_checksum; 255f8eb24a8SPatrick McHardy extern atomic_t nf_conntrack_count; 256f8eb24a8SPatrick McHardy extern int nf_conntrack_max; 2579fb9cbb1SYasuyuki Kozakai 258f8eb24a8SPatrick McHardy DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); 2599fb9cbb1SYasuyuki Kozakai #define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++) 260c0e912d7SPatrick McHardy #define NF_CT_STAT_INC_ATOMIC(count) \ 261c0e912d7SPatrick McHardy do { \ 262c0e912d7SPatrick McHardy local_bh_disable(); \ 263c0e912d7SPatrick McHardy __get_cpu_var(nf_conntrack_stat).count++; \ 264c0e912d7SPatrick McHardy local_bh_enable(); \ 265c0e912d7SPatrick McHardy } while (0) 2669fb9cbb1SYasuyuki Kozakai 2679fb9cbb1SYasuyuki Kozakai /* no helper, no nat */ 2689fb9cbb1SYasuyuki Kozakai #define NF_CT_F_BASIC 0 2699fb9cbb1SYasuyuki Kozakai /* for helper */ 2709fb9cbb1SYasuyuki Kozakai #define NF_CT_F_HELP 1 2719fb9cbb1SYasuyuki Kozakai /* for nat. */ 2729fb9cbb1SYasuyuki Kozakai #define NF_CT_F_NAT 2 2739fb9cbb1SYasuyuki Kozakai #define NF_CT_F_NUM 4 2749fb9cbb1SYasuyuki Kozakai 2759fb9cbb1SYasuyuki Kozakai extern int 276dc808fe2SHarald Welte nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size); 2779fb9cbb1SYasuyuki Kozakai extern void 2789fb9cbb1SYasuyuki Kozakai nf_conntrack_unregister_cache(u_int32_t features); 2799fb9cbb1SYasuyuki Kozakai 280dc808fe2SHarald Welte /* valid combinations: 281dc808fe2SHarald Welte * basic: nf_conn, nf_conn .. nf_conn_help 2825b1158e9SJozsef Kadlecsik * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help 283dc808fe2SHarald Welte */ 2845b1158e9SJozsef Kadlecsik #ifdef CONFIG_NF_NAT_NEEDED 2855b1158e9SJozsef Kadlecsik static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct) 2865b1158e9SJozsef Kadlecsik { 2875b1158e9SJozsef Kadlecsik unsigned int offset = sizeof(struct nf_conn); 2885b1158e9SJozsef Kadlecsik 2895b1158e9SJozsef Kadlecsik if (!(ct->features & NF_CT_F_NAT)) 2905b1158e9SJozsef Kadlecsik return NULL; 2915b1158e9SJozsef Kadlecsik 2925b1158e9SJozsef Kadlecsik offset = ALIGN(offset, __alignof__(struct nf_conn_nat)); 2935b1158e9SJozsef Kadlecsik return (struct nf_conn_nat *) ((void *)ct + offset); 2945b1158e9SJozsef Kadlecsik } 2955b1158e9SJozsef Kadlecsik 2965b1158e9SJozsef Kadlecsik static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) 2975b1158e9SJozsef Kadlecsik { 2985b1158e9SJozsef Kadlecsik unsigned int offset = sizeof(struct nf_conn); 2995b1158e9SJozsef Kadlecsik 3005b1158e9SJozsef Kadlecsik if (!(ct->features & NF_CT_F_HELP)) 3015b1158e9SJozsef Kadlecsik return NULL; 3025b1158e9SJozsef Kadlecsik if (ct->features & NF_CT_F_NAT) { 3035b1158e9SJozsef Kadlecsik offset = ALIGN(offset, __alignof__(struct nf_conn_nat)); 3045b1158e9SJozsef Kadlecsik offset += sizeof(struct nf_conn_nat); 3055b1158e9SJozsef Kadlecsik } 3065b1158e9SJozsef Kadlecsik 3075b1158e9SJozsef Kadlecsik offset = ALIGN(offset, __alignof__(struct nf_conn_help)); 3085b1158e9SJozsef Kadlecsik return (struct nf_conn_help *) ((void *)ct + offset); 3095b1158e9SJozsef Kadlecsik } 3105b1158e9SJozsef Kadlecsik #else /* No NAT */ 311dc808fe2SHarald Welte static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) 312dc808fe2SHarald Welte { 313dc808fe2SHarald Welte unsigned int offset = sizeof(struct nf_conn); 314dc808fe2SHarald Welte 315dc808fe2SHarald Welte if (!(ct->features & NF_CT_F_HELP)) 316dc808fe2SHarald Welte return NULL; 317dc808fe2SHarald Welte 318f9aae958SPatrick McHardy offset = ALIGN(offset, __alignof__(struct nf_conn_help)); 319dc808fe2SHarald Welte return (struct nf_conn_help *) ((void *)ct + offset); 320dc808fe2SHarald Welte } 3215b1158e9SJozsef Kadlecsik #endif /* CONFIG_NF_NAT_NEEDED */ 3229fb9cbb1SYasuyuki Kozakai #endif /* __KERNEL__ */ 3239fb9cbb1SYasuyuki Kozakai #endif /* _NF_CONNTRACK_H */ 324