nf_log.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #include <linux/module.h>
  4. #include <linux/proc_fs.h>
  5. #include <linux/skbuff.h>
  6. #include <linux/netfilter.h>
  7. #include <linux/seq_file.h>
  8. #include <net/protocol.h>
  9. #include "nf_internals.h"
  10. /* Internal logging interface, which relies on the real
  11. LOG target modules */
  12. #define NF_LOG_PREFIXLEN 128
  13. static struct nf_logger *nf_loggers[NPROTO];
  14. static DEFINE_MUTEX(nf_log_mutex);
  15. /* return EBUSY if somebody else is registered, EEXIST if the same logger
  16. * is registred, 0 on success. */
  17. int nf_log_register(int pf, struct nf_logger *logger)
  18. {
  19. int ret;
  20. if (pf >= NPROTO)
  21. return -EINVAL;
  22. /* Any setup of logging members must be done before
  23. * substituting pointer. */
  24. ret = mutex_lock_interruptible(&nf_log_mutex);
  25. if (ret < 0)
  26. return ret;
  27. if (!nf_loggers[pf])
  28. rcu_assign_pointer(nf_loggers[pf], logger);
  29. else if (nf_loggers[pf] == logger)
  30. ret = -EEXIST;
  31. else
  32. ret = -EBUSY;
  33. mutex_unlock(&nf_log_mutex);
  34. return ret;
  35. }
  36. EXPORT_SYMBOL(nf_log_register);
  37. void nf_log_unregister_pf(int pf)
  38. {
  39. if (pf >= NPROTO)
  40. return;
  41. mutex_lock(&nf_log_mutex);
  42. rcu_assign_pointer(nf_loggers[pf], NULL);
  43. mutex_unlock(&nf_log_mutex);
  44. /* Give time to concurrent readers. */
  45. synchronize_rcu();
  46. }
  47. EXPORT_SYMBOL(nf_log_unregister_pf);
  48. void nf_log_unregister(struct nf_logger *logger)
  49. {
  50. int i;
  51. mutex_lock(&nf_log_mutex);
  52. for (i = 0; i < NPROTO; i++) {
  53. if (nf_loggers[i] == logger)
  54. rcu_assign_pointer(nf_loggers[i], NULL);
  55. }
  56. mutex_unlock(&nf_log_mutex);
  57. synchronize_rcu();
  58. }
  59. EXPORT_SYMBOL(nf_log_unregister);
  60. void nf_log_packet(int pf,
  61. unsigned int hooknum,
  62. const struct sk_buff *skb,
  63. const struct net_device *in,
  64. const struct net_device *out,
  65. struct nf_loginfo *loginfo,
  66. const char *fmt, ...)
  67. {
  68. va_list args;
  69. char prefix[NF_LOG_PREFIXLEN];
  70. struct nf_logger *logger;
  71. rcu_read_lock();
  72. logger = rcu_dereference(nf_loggers[pf]);
  73. if (logger) {
  74. va_start(args, fmt);
  75. vsnprintf(prefix, sizeof(prefix), fmt, args);
  76. va_end(args);
  77. /* We must read logging before nf_logfn[pf] */
  78. logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix);
  79. } else if (net_ratelimit()) {
  80. printk(KERN_WARNING "nf_log_packet: can\'t log since "
  81. "no backend logging module loaded in! Please either "
  82. "load one, or disable logging explicitly\n");
  83. }
  84. rcu_read_unlock();
  85. }
  86. EXPORT_SYMBOL(nf_log_packet);
  87. #ifdef CONFIG_PROC_FS
  88. static void *seq_start(struct seq_file *seq, loff_t *pos)
  89. {
  90. rcu_read_lock();
  91. if (*pos >= NPROTO)
  92. return NULL;
  93. return pos;
  94. }
  95. static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
  96. {
  97. (*pos)++;
  98. if (*pos >= NPROTO)
  99. return NULL;
  100. return pos;
  101. }
  102. static void seq_stop(struct seq_file *s, void *v)
  103. {
  104. rcu_read_unlock();
  105. }
  106. static int seq_show(struct seq_file *s, void *v)
  107. {
  108. loff_t *pos = v;
  109. const struct nf_logger *logger;
  110. logger = rcu_dereference(nf_loggers[*pos]);
  111. if (!logger)
  112. return seq_printf(s, "%2lld NONE\n", *pos);
  113. return seq_printf(s, "%2lld %s\n", *pos, logger->name);
  114. }
  115. static struct seq_operations nflog_seq_ops = {
  116. .start = seq_start,
  117. .next = seq_next,
  118. .stop = seq_stop,
  119. .show = seq_show,
  120. };
  121. static int nflog_open(struct inode *inode, struct file *file)
  122. {
  123. return seq_open(file, &nflog_seq_ops);
  124. }
  125. static const struct file_operations nflog_file_ops = {
  126. .owner = THIS_MODULE,
  127. .open = nflog_open,
  128. .read = seq_read,
  129. .llseek = seq_lseek,
  130. .release = seq_release,
  131. };
  132. #endif /* PROC_FS */
  133. int __init netfilter_log_init(void)
  134. {
  135. #ifdef CONFIG_PROC_FS
  136. struct proc_dir_entry *pde;
  137. pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
  138. if (!pde)
  139. return -1;
  140. pde->proc_fops = &nflog_file_ops;
  141. #endif
  142. return 0;
  143. }