nf_conntrack_ecache.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* Event cache for netfilter. */
  2. /* (C) 1999-2001 Paul `Rusty' Russell
  3. * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
  4. * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/types.h>
  11. #include <linux/netfilter.h>
  12. #include <linux/skbuff.h>
  13. #include <linux/vmalloc.h>
  14. #include <linux/stddef.h>
  15. #include <linux/err.h>
  16. #include <linux/percpu.h>
  17. #include <linux/notifier.h>
  18. #include <linux/kernel.h>
  19. #include <linux/netdevice.h>
  20. #include <net/netfilter/nf_conntrack.h>
  21. #include <net/netfilter/nf_conntrack_core.h>
  22. ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
  23. EXPORT_SYMBOL_GPL(nf_conntrack_chain);
  24. ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
  25. EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
  26. DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
  27. EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
  28. /* deliver cached events and clear cache entry - must be called with locally
  29. * disabled softirqs */
  30. static inline void
  31. __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
  32. {
  33. if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
  34. && ecache->events)
  35. atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
  36. ecache->ct);
  37. ecache->events = 0;
  38. nf_ct_put(ecache->ct);
  39. ecache->ct = NULL;
  40. }
  41. /* Deliver all cached events for a particular conntrack. This is called
  42. * by code prior to async packet handling for freeing the skb */
  43. void nf_ct_deliver_cached_events(const struct nf_conn *ct)
  44. {
  45. struct nf_conntrack_ecache *ecache;
  46. local_bh_disable();
  47. ecache = &__get_cpu_var(nf_conntrack_ecache);
  48. if (ecache->ct == ct)
  49. __nf_ct_deliver_cached_events(ecache);
  50. local_bh_enable();
  51. }
  52. EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
  53. /* Deliver cached events for old pending events, if current conntrack != old */
  54. void __nf_ct_event_cache_init(struct nf_conn *ct)
  55. {
  56. struct nf_conntrack_ecache *ecache;
  57. /* take care of delivering potentially old events */
  58. ecache = &__get_cpu_var(nf_conntrack_ecache);
  59. BUG_ON(ecache->ct == ct);
  60. if (ecache->ct)
  61. __nf_ct_deliver_cached_events(ecache);
  62. /* initialize for this conntrack/packet */
  63. ecache->ct = ct;
  64. nf_conntrack_get(&ct->ct_general);
  65. }
  66. EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
  67. /* flush the event cache - touches other CPU's data and must not be called
  68. * while packets are still passing through the code */
  69. void nf_ct_event_cache_flush(void)
  70. {
  71. struct nf_conntrack_ecache *ecache;
  72. int cpu;
  73. for_each_possible_cpu(cpu) {
  74. ecache = &per_cpu(nf_conntrack_ecache, cpu);
  75. if (ecache->ct)
  76. nf_ct_put(ecache->ct);
  77. }
  78. }