ip_conntrack.h
上传用户:szlgq88
上传日期:2009-04-28
资源大小:48287k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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