1 #ifndef _IP_CONNTRACK_H 2 #define _IP_CONNTRACK_H 3 4 #include <linux/netfilter/nf_conntrack_common.h> 5 6 #ifdef __KERNEL__ 7 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 8 #include <linux/bitops.h> 9 #include <linux/compiler.h> 10 #include <asm/atomic.h> 11 12 #include <linux/netfilter_ipv4/ip_conntrack_tcp.h> 13 #include <linux/netfilter_ipv4/ip_conntrack_icmp.h> 14 #include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> 15 #include <linux/netfilter_ipv4/ip_conntrack_sctp.h> 16 17 /* per conntrack: protocol private data */ 18 union ip_conntrack_proto { 19 /* insert conntrack proto private data here */ 20 struct ip_ct_gre gre; 21 struct ip_ct_sctp sctp; 22 struct ip_ct_tcp tcp; 23 struct ip_ct_icmp icmp; 24 }; 25 26 union ip_conntrack_expect_proto { 27 /* insert expect proto private data here */ 28 }; 29 30 /* Add protocol helper include file here */ 31 #include <linux/netfilter_ipv4/ip_conntrack_h323.h> 32 #include <linux/netfilter_ipv4/ip_conntrack_pptp.h> 33 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h> 34 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h> 35 #include <linux/netfilter_ipv4/ip_conntrack_irc.h> 36 37 /* per conntrack: application helper private data */ 38 union ip_conntrack_help { 39 /* insert conntrack helper private data (master) here */ 40 struct ip_ct_h323_master ct_h323_info; 41 struct ip_ct_pptp_master ct_pptp_info; 42 struct ip_ct_ftp_master ct_ftp_info; 43 struct ip_ct_irc_master ct_irc_info; 44 }; 45 46 #ifdef CONFIG_IP_NF_NAT_NEEDED 47 #include <linux/netfilter_ipv4/ip_nat.h> 48 #include <linux/netfilter_ipv4/ip_nat_pptp.h> 49 50 /* per conntrack: nat application helper private data */ 51 union ip_conntrack_nat_help { 52 /* insert nat helper private data here */ 53 struct ip_nat_pptp nat_pptp_info; 54 }; 55 #endif 56 57 #include <linux/types.h> 58 #include <linux/skbuff.h> 59 60 #ifdef CONFIG_NETFILTER_DEBUG 61 #define IP_NF_ASSERT(x) \ 62 do { \ 63 if (!(x)) \ 64 /* Wooah! I'm tripping my conntrack in a frenzy of \ 65 netplay... */ \ 66 printk("NF_IP_ASSERT: %s:%i(%s)\n", \ 67 __FILE__, __LINE__, __FUNCTION__); \ 68 } while(0) 69 #else 70 #define IP_NF_ASSERT(x) 71 #endif 72 73 struct ip_conntrack_helper; 74 75 struct ip_conntrack 76 { 77 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, 78 plus 1 for any connection(s) we are `master' for */ 79 struct nf_conntrack ct_general; 80 81 /* Have we seen traffic both ways yet? (bitset) */ 82 unsigned long status; 83 84 /* Timer function; drops refcnt when it goes off. */ 85 struct timer_list timeout; 86 87 #ifdef CONFIG_IP_NF_CT_ACCT 88 /* Accounting Information (same cache line as other written members) */ 89 struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; 90 #endif 91 /* If we were expected by an expectation, this will be it */ 92 struct ip_conntrack *master; 93 94 /* Current number of expected connections */ 95 unsigned int expecting; 96 97 /* Unique ID that identifies this conntrack*/ 98 unsigned int id; 99 100 /* Helper, if any. */ 101 struct ip_conntrack_helper *helper; 102 103 /* Storage reserved for other modules: */ 104 union ip_conntrack_proto proto; 105 106 union ip_conntrack_help help; 107 108 #ifdef CONFIG_IP_NF_NAT_NEEDED 109 struct { 110 struct ip_nat_info info; 111 union ip_conntrack_nat_help help; 112 #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ 113 defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) 114 int masq_index; 115 #endif 116 } nat; 117 #endif /* CONFIG_IP_NF_NAT_NEEDED */ 118 119 #if defined(CONFIG_IP_NF_CONNTRACK_MARK) 120 u_int32_t mark; 121 #endif 122 123 #ifdef CONFIG_IP_NF_CONNTRACK_SECMARK 124 u_int32_t secmark; 125 #endif 126 127 /* Traversed often, so hopefully in different cacheline to top */ 128 /* These are my tuples; original and reply */ 129 struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; 130 }; 131 132 struct ip_conntrack_expect 133 { 134 /* Internal linked list (global expectation list) */ 135 struct list_head list; 136 137 /* We expect this tuple, with the following mask */ 138 struct ip_conntrack_tuple tuple, mask; 139 140 /* Function to call after setup and insertion */ 141 void (*expectfn)(struct ip_conntrack *new, 142 struct ip_conntrack_expect *this); 143 144 /* The conntrack of the master connection */ 145 struct ip_conntrack *master; 146 147 /* Timer function; deletes the expectation. */ 148 struct timer_list timeout; 149 150 /* Usage count. */ 151 atomic_t use; 152 153 /* Unique ID */ 154 unsigned int id; 155 156 /* Flags */ 157 unsigned int flags; 158 159 #ifdef CONFIG_IP_NF_NAT_NEEDED 160 u_int32_t saved_ip; 161 /* This is the original per-proto part, used to map the 162 * expected connection the way the recipient expects. */ 163 union ip_conntrack_manip_proto saved_proto; 164 /* Direction relative to the master connection. */ 165 enum ip_conntrack_dir dir; 166 #endif 167 }; 168 169 #define IP_CT_EXPECT_PERMANENT 0x1 170 171 static inline struct ip_conntrack * 172 tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash) 173 { 174 return container_of(hash, struct ip_conntrack, 175 tuplehash[hash->tuple.dst.dir]); 176 } 177 178 /* get master conntrack via master expectation */ 179 #define master_ct(conntr) (conntr->master) 180 181 /* Alter reply tuple (maybe alter helper). */ 182 extern void 183 ip_conntrack_alter_reply(struct ip_conntrack *conntrack, 184 const struct ip_conntrack_tuple *newreply); 185 186 /* Is this tuple taken? (ignoring any belonging to the given 187 conntrack). */ 188 extern int 189 ip_conntrack_tuple_taken(const struct ip_conntrack_tuple *tuple, 190 const struct ip_conntrack *ignored_conntrack); 191 192 /* Return conntrack_info and tuple hash for given skb. */ 193 static inline struct ip_conntrack * 194 ip_conntrack_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo) 195 { 196 *ctinfo = skb->nfctinfo; 197 return (struct ip_conntrack *)skb->nfct; 198 } 199 200 /* decrement reference count on a conntrack */ 201 static inline void 202 ip_conntrack_put(struct ip_conntrack *ct) 203 { 204 IP_NF_ASSERT(ct); 205 nf_conntrack_put(&ct->ct_general); 206 } 207 208 extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, 209 const struct ip_conntrack_tuple *orig); 210 211 extern void __ip_ct_refresh_acct(struct ip_conntrack *ct, 212 enum ip_conntrack_info ctinfo, 213 const struct sk_buff *skb, 214 unsigned long extra_jiffies, 215 int do_acct); 216 217 /* Refresh conntrack for this many jiffies and do accounting */ 218 static inline void ip_ct_refresh_acct(struct ip_conntrack *ct, 219 enum ip_conntrack_info ctinfo, 220 const struct sk_buff *skb, 221 unsigned long extra_jiffies) 222 { 223 __ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1); 224 } 225 226 /* Refresh conntrack for this many jiffies */ 227 static inline void ip_ct_refresh(struct ip_conntrack *ct, 228 const struct sk_buff *skb, 229 unsigned long extra_jiffies) 230 { 231 __ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0); 232 } 233 234 /* These are for NAT. Icky. */ 235 /* Update TCP window tracking data when NAT mangles the packet */ 236 extern void ip_conntrack_tcp_update(struct sk_buff *skb, 237 struct ip_conntrack *conntrack, 238 enum ip_conntrack_dir dir); 239 240 /* Call me when a conntrack is destroyed. */ 241 extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack); 242 243 /* Fake conntrack entry for untracked connections */ 244 extern struct ip_conntrack ip_conntrack_untracked; 245 246 /* Returns new sk_buff, or NULL */ 247 struct sk_buff * 248 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user); 249 250 /* Iterate over all conntracks: if iter returns true, it's deleted. */ 251 extern void 252 ip_ct_iterate_cleanup(int (*iter)(struct ip_conntrack *i, void *data), 253 void *data); 254 255 extern struct ip_conntrack_helper * 256 __ip_conntrack_helper_find_byname(const char *); 257 extern struct ip_conntrack_helper * 258 ip_conntrack_helper_find_get(const struct ip_conntrack_tuple *tuple); 259 extern void ip_conntrack_helper_put(struct ip_conntrack_helper *helper); 260 261 extern struct ip_conntrack_protocol * 262 __ip_conntrack_proto_find(u_int8_t protocol); 263 extern struct ip_conntrack_protocol * 264 ip_conntrack_proto_find_get(u_int8_t protocol); 265 extern void ip_conntrack_proto_put(struct ip_conntrack_protocol *proto); 266 267 extern void ip_ct_remove_expectations(struct ip_conntrack *ct); 268 269 extern struct ip_conntrack *ip_conntrack_alloc(struct ip_conntrack_tuple *, 270 struct ip_conntrack_tuple *); 271 272 extern void ip_conntrack_free(struct ip_conntrack *ct); 273 274 extern void ip_conntrack_hash_insert(struct ip_conntrack *ct); 275 276 extern struct ip_conntrack_expect * 277 __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple); 278 279 extern struct ip_conntrack_expect * 280 ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple); 281 282 extern struct ip_conntrack_tuple_hash * 283 __ip_conntrack_find(const struct ip_conntrack_tuple *tuple, 284 const struct ip_conntrack *ignored_conntrack); 285 286 extern void ip_conntrack_flush(void); 287 288 /* It's confirmed if it is, or has been in the hash table. */ 289 static inline int is_confirmed(struct ip_conntrack *ct) 290 { 291 return test_bit(IPS_CONFIRMED_BIT, &ct->status); 292 } 293 294 static inline int is_dying(struct ip_conntrack *ct) 295 { 296 return test_bit(IPS_DYING_BIT, &ct->status); 297 } 298 299 extern unsigned int ip_conntrack_htable_size; 300 extern int ip_conntrack_checksum; 301 302 #define CONNTRACK_STAT_INC(count) (__get_cpu_var(ip_conntrack_stat).count++) 303 304 #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 305 #include <linux/notifier.h> 306 #include <linux/interrupt.h> 307 308 struct ip_conntrack_ecache { 309 struct ip_conntrack *ct; 310 unsigned int events; 311 }; 312 DECLARE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); 313 314 #define CONNTRACK_ECACHE(x) (__get_cpu_var(ip_conntrack_ecache).x) 315 316 extern struct atomic_notifier_head ip_conntrack_chain; 317 extern struct atomic_notifier_head ip_conntrack_expect_chain; 318 319 static inline int ip_conntrack_register_notifier(struct notifier_block *nb) 320 { 321 return atomic_notifier_chain_register(&ip_conntrack_chain, nb); 322 } 323 324 static inline int ip_conntrack_unregister_notifier(struct notifier_block *nb) 325 { 326 return atomic_notifier_chain_unregister(&ip_conntrack_chain, nb); 327 } 328 329 static inline int 330 ip_conntrack_expect_register_notifier(struct notifier_block *nb) 331 { 332 return atomic_notifier_chain_register(&ip_conntrack_expect_chain, nb); 333 } 334 335 static inline int 336 ip_conntrack_expect_unregister_notifier(struct notifier_block *nb) 337 { 338 return atomic_notifier_chain_unregister(&ip_conntrack_expect_chain, 339 nb); 340 } 341 342 extern void ip_ct_deliver_cached_events(const struct ip_conntrack *ct); 343 extern void __ip_ct_event_cache_init(struct ip_conntrack *ct); 344 345 static inline void 346 ip_conntrack_event_cache(enum ip_conntrack_events event, 347 const struct sk_buff *skb) 348 { 349 struct ip_conntrack *ct = (struct ip_conntrack *)skb->nfct; 350 struct ip_conntrack_ecache *ecache; 351 352 local_bh_disable(); 353 ecache = &__get_cpu_var(ip_conntrack_ecache); 354 if (ct != ecache->ct) 355 __ip_ct_event_cache_init(ct); 356 ecache->events |= event; 357 local_bh_enable(); 358 } 359 360 static inline void ip_conntrack_event(enum ip_conntrack_events event, 361 struct ip_conntrack *ct) 362 { 363 if (is_confirmed(ct) && !is_dying(ct)) 364 atomic_notifier_call_chain(&ip_conntrack_chain, event, ct); 365 } 366 367 static inline void 368 ip_conntrack_expect_event(enum ip_conntrack_expect_events event, 369 struct ip_conntrack_expect *exp) 370 { 371 atomic_notifier_call_chain(&ip_conntrack_expect_chain, event, exp); 372 } 373 #else /* CONFIG_IP_NF_CONNTRACK_EVENTS */ 374 static inline void ip_conntrack_event_cache(enum ip_conntrack_events event, 375 const struct sk_buff *skb) {} 376 static inline void ip_conntrack_event(enum ip_conntrack_events event, 377 struct ip_conntrack *ct) {} 378 static inline void ip_ct_deliver_cached_events(const struct ip_conntrack *ct) {} 379 static inline void 380 ip_conntrack_expect_event(enum ip_conntrack_expect_events event, 381 struct ip_conntrack_expect *exp) {} 382 #endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */ 383 384 #ifdef CONFIG_IP_NF_NAT_NEEDED 385 static inline int ip_nat_initialized(struct ip_conntrack *conntrack, 386 enum ip_nat_manip_type manip) 387 { 388 if (manip == IP_NAT_MANIP_SRC) 389 return test_bit(IPS_SRC_NAT_DONE_BIT, &conntrack->status); 390 return test_bit(IPS_DST_NAT_DONE_BIT, &conntrack->status); 391 } 392 #endif /* CONFIG_IP_NF_NAT_NEEDED */ 393 394 #endif /* __KERNEL__ */ 395 #endif /* _IP_CONNTRACK_H */ 396