diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-06-19 10:37:58 (GMT) |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-06-25 17:28:43 (GMT) |
commit | 27fd8d90c996caa480ed6777eaaf21d9e5166cc3 (patch) | |
tree | f8df4f5b01873a7d6f9c98f7f5f033e547987c5a /net/netfilter/nf_log.c | |
parent | 5962815a6a56566318a60dc53ff8789b7e6ec71f (diff) | |
download | linux-27fd8d90c996caa480ed6777eaaf21d9e5166cc3.tar.xz |
netfilter: nf_log: move log buffering to core logging
This patch moves Eric Dumazet's log buffer implementation from the
xt_log.h header file to the core net/netfilter/nf_log.c. This also
includes the renaming of the structure and functions to avoid possible
undesired namespace clashes.
This change allows us to use it from the arp and bridge packet logging
implementation in follow up patches.
Diffstat (limited to 'net/netfilter/nf_log.c')
-rw-r--r-- | net/netfilter/nf_log.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 7a29a3a..0b6b2c8 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -157,6 +157,63 @@ void nf_log_packet(struct net *net, } EXPORT_SYMBOL(nf_log_packet); +#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) + +struct nf_log_buf { + unsigned int count; + char buf[S_SIZE + 1]; +}; +static struct nf_log_buf emergency, *emergency_ptr = &emergency; + +__printf(2, 3) int nf_log_buf_add(struct nf_log_buf *m, const char *f, ...) +{ + va_list args; + int len; + + if (likely(m->count < S_SIZE)) { + va_start(args, f); + len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); + va_end(args); + if (likely(m->count + len < S_SIZE)) { + m->count += len; + return 0; + } + } + m->count = S_SIZE; + printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); + return -1; +} +EXPORT_SYMBOL_GPL(nf_log_buf_add); + +struct nf_log_buf *nf_log_buf_open(void) +{ + struct nf_log_buf *m = kmalloc(sizeof(*m), GFP_ATOMIC); + + if (unlikely(!m)) { + local_bh_disable(); + do { + m = xchg(&emergency_ptr, NULL); + } while (!m); + } + m->count = 0; + return m; +} +EXPORT_SYMBOL_GPL(nf_log_buf_open); + +void nf_log_buf_close(struct nf_log_buf *m) +{ + m->buf[m->count] = 0; + printk("%s\n", m->buf); + + if (likely(m != &emergency)) + kfree(m); + else { + emergency_ptr = m; + local_bh_enable(); + } +} +EXPORT_SYMBOL_GPL(nf_log_buf_close); + #ifdef CONFIG_PROC_FS static void *seq_start(struct seq_file *seq, loff_t *pos) { |