1/* 2 * Connection state tracking for netfilter. This is separated from, 3 * but required by, the (future) NAT layer; it can also be used by an iptables 4 * extension. 5 * 6 * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> 7 * - generalize L3 protocol dependent part. 8 * 9 * Derived from include/linux/netfiter_ipv4/ip_conntrack.h 10 */ 11 12#ifndef _NF_CONNTRACK_H 13#define _NF_CONNTRACK_H 14 15#include <linux/netfilter/nf_conntrack_common.h> 16 17#include <linux/bitops.h> 18#include <linux/compiler.h> 19#include <linux/atomic.h> 20 21#include <linux/netfilter/nf_conntrack_tcp.h> 22#include <linux/netfilter/nf_conntrack_dccp.h> 23#include <linux/netfilter/nf_conntrack_sctp.h> 24#include <linux/netfilter/nf_conntrack_proto_gre.h> 25#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 26 27#include <net/netfilter/nf_conntrack_tuple.h> 28 29/* per conntrack: protocol private data */ 30union nf_conntrack_proto { 31 /* insert conntrack proto private data here */ 32 struct nf_ct_dccp dccp; 33 struct ip_ct_sctp sctp; 34 struct ip_ct_tcp tcp; 35 struct nf_ct_gre gre; 36}; 37 38union nf_conntrack_expect_proto { 39 /* insert expect proto private data here */ 40}; 41 42#include <linux/types.h> 43#include <linux/skbuff.h> 44#include <linux/timer.h> 45 46#ifdef CONFIG_NETFILTER_DEBUG 47#define NF_CT_ASSERT(x) WARN_ON(!(x)) 48#else 49#define NF_CT_ASSERT(x) 50#endif 51 52struct nf_conntrack_helper; 53 54/* Must be kept in sync with the classes defined by helpers */ 55#define NF_CT_MAX_EXPECT_CLASSES 4 56 57/* nf_conn feature for connections that have a helper */ 58struct nf_conn_help { 59 /* Helper. if any */ 60 struct nf_conntrack_helper __rcu *helper; 61 62 struct hlist_head expectations; 63 64 /* Current number of expected connections */ 65 u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; 66 67 /* private helper information. */ 68 char data[]; 69}; 70 71#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 72#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 73 74struct nf_conn { 75 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, 76 * plus 1 for any connection(s) we are `master' for 77 * 78 * Hint, SKB address this struct and refcnt via skb->nfct and 79 * helpers nf_conntrack_get() and nf_conntrack_put(). 80 * Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt, 81 * beware nf_ct_get() is different and don't inc refcnt. 82 */ 83 struct nf_conntrack ct_general; 84 85 spinlock_t lock; 86 u16 cpu; 87 88 /* XXX should I move this to the tail ? - Y.K */ 89 /* These are my tuples; original and reply */ 90 struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; 91 92 /* Have we seen traffic both ways yet? (bitset) */ 93 unsigned long status; 94 95 /* If we were expected by an expectation, this will be it */ 96 struct nf_conn *master; 97 98 /* Timer function; drops refcnt when it goes off. */ 99 struct timer_list timeout; 100 101#if defined(CONFIG_NF_CONNTRACK_MARK) 102 u_int32_t mark; 103#endif 104 105#ifdef CONFIG_NF_CONNTRACK_SECMARK 106 u_int32_t secmark; 107#endif 108 109 /* Extensions */ 110 struct nf_ct_ext *ext; 111#ifdef CONFIG_NET_NS 112 struct net *ct_net; 113#endif 114 115 /* Storage reserved for other modules, must be the last member */ 116 union nf_conntrack_proto proto; 117}; 118 119static inline struct nf_conn * 120nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) 121{ 122 return container_of(hash, struct nf_conn, 123 tuplehash[hash->tuple.dst.dir]); 124} 125 126static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct) 127{ 128 return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 129} 130 131static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct) 132{ 133 return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 134} 135 136#define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple) 137 138/* get master conntrack via master expectation */ 139#define master_ct(conntr) (conntr->master) 140 141extern struct net init_net; 142 143static inline struct net *nf_ct_net(const struct nf_conn *ct) 144{ 145 return read_pnet(&ct->ct_net); 146} 147 148/* Alter reply tuple (maybe alter helper). */ 149void nf_conntrack_alter_reply(struct nf_conn *ct, 150 const struct nf_conntrack_tuple *newreply); 151 152/* Is this tuple taken? (ignoring any belonging to the given 153 conntrack). */ 154int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 155 const struct nf_conn *ignored_conntrack); 156 157/* Return conntrack_info and tuple hash for given skb. */ 158static inline struct nf_conn * 159nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) 160{ 161 *ctinfo = skb->nfctinfo; 162 return (struct nf_conn *)skb->nfct; 163} 164 165/* decrement reference count on a conntrack */ 166static inline void nf_ct_put(struct nf_conn *ct) 167{ 168 NF_CT_ASSERT(ct); 169 nf_conntrack_put(&ct->ct_general); 170} 171 172/* Protocol module loading */ 173int nf_ct_l3proto_try_module_get(unsigned short l3proto); 174void nf_ct_l3proto_module_put(unsigned short l3proto); 175 176/* 177 * Allocate a hashtable of hlist_head (if nulls == 0), 178 * or hlist_nulls_head (if nulls == 1) 179 */ 180void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls); 181 182void nf_ct_free_hashtable(void *hash, unsigned int size); 183 184struct nf_conntrack_tuple_hash * 185__nf_conntrack_find(struct net *net, u16 zone, 186 const struct nf_conntrack_tuple *tuple); 187 188int nf_conntrack_hash_check_insert(struct nf_conn *ct); 189bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report); 190 191void nf_conntrack_flush_report(struct net *net, u32 portid, int report); 192 193bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff, 194 u_int16_t l3num, struct nf_conntrack_tuple *tuple); 195bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 196 const struct nf_conntrack_tuple *orig); 197 198void __nf_ct_refresh_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo, 199 const struct sk_buff *skb, 200 unsigned long extra_jiffies, int do_acct); 201 202/* Refresh conntrack for this many jiffies and do accounting */ 203static inline void nf_ct_refresh_acct(struct nf_conn *ct, 204 enum ip_conntrack_info ctinfo, 205 const struct sk_buff *skb, 206 unsigned long extra_jiffies) 207{ 208 __nf_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1); 209} 210 211/* Refresh conntrack for this many jiffies */ 212static inline void nf_ct_refresh(struct nf_conn *ct, 213 const struct sk_buff *skb, 214 unsigned long extra_jiffies) 215{ 216 __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0); 217} 218 219bool __nf_ct_kill_acct(struct nf_conn *ct, enum ip_conntrack_info ctinfo, 220 const struct sk_buff *skb, int do_acct); 221 222/* kill conntrack and do accounting */ 223static inline bool nf_ct_kill_acct(struct nf_conn *ct, 224 enum ip_conntrack_info ctinfo, 225 const struct sk_buff *skb) 226{ 227 return __nf_ct_kill_acct(ct, ctinfo, skb, 1); 228} 229 230/* kill conntrack without accounting */ 231static inline bool nf_ct_kill(struct nf_conn *ct) 232{ 233 return __nf_ct_kill_acct(ct, 0, NULL, 0); 234} 235 236/* These are for NAT. Icky. */ 237extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct, 238 enum ip_conntrack_dir dir, 239 u32 seq); 240 241/* Fake conntrack entry for untracked connections */ 242DECLARE_PER_CPU(struct nf_conn, nf_conntrack_untracked); 243static inline struct nf_conn *nf_ct_untracked_get(void) 244{ 245 return raw_cpu_ptr(&nf_conntrack_untracked); 246} 247void nf_ct_untracked_status_or(unsigned long bits); 248 249/* Iterate over all conntracks: if iter returns true, it's deleted. */ 250void nf_ct_iterate_cleanup(struct net *net, 251 int (*iter)(struct nf_conn *i, void *data), 252 void *data, u32 portid, int report); 253void nf_conntrack_free(struct nf_conn *ct); 254struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, 255 const struct nf_conntrack_tuple *orig, 256 const struct nf_conntrack_tuple *repl, 257 gfp_t gfp); 258 259static inline int nf_ct_is_template(const struct nf_conn *ct) 260{ 261 return test_bit(IPS_TEMPLATE_BIT, &ct->status); 262} 263 264/* It's confirmed if it is, or has been in the hash table. */ 265static inline int nf_ct_is_confirmed(struct nf_conn *ct) 266{ 267 return test_bit(IPS_CONFIRMED_BIT, &ct->status); 268} 269 270static inline int nf_ct_is_dying(struct nf_conn *ct) 271{ 272 return test_bit(IPS_DYING_BIT, &ct->status); 273} 274 275static inline int nf_ct_is_untracked(const struct nf_conn *ct) 276{ 277 return test_bit(IPS_UNTRACKED_BIT, &ct->status); 278} 279 280/* Packet is received from loopback */ 281static inline bool nf_is_loopback_packet(const struct sk_buff *skb) 282{ 283 return skb->dev && skb->skb_iif && skb->dev->flags & IFF_LOOPBACK; 284} 285 286struct kernel_param; 287 288int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp); 289extern unsigned int nf_conntrack_htable_size; 290extern unsigned int nf_conntrack_max; 291extern unsigned int nf_conntrack_hash_rnd; 292void init_nf_conntrack_hash_rnd(void); 293 294void nf_conntrack_tmpl_insert(struct net *net, struct nf_conn *tmpl); 295 296#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) 297#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) 298 299#define MODULE_ALIAS_NFCT_HELPER(helper) \ 300 MODULE_ALIAS("nfct-helper-" helper) 301 302#endif /* _NF_CONNTRACK_H */ 303