aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@netfilter.org>2005-08-09 22:58:27 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:38:07 -0400
commit608c8e4f7b6e61cc783283e9dff8a465a5ad59bb (patch)
tree55ca8bed99789cd6af07f6cc6ee99b0cf718a611
parent838ab6364956d9bdcefe84712de1621cf20a40b3 (diff)
[NETFILTER]: Extend netfilter logging API
This patch is in preparation to nfnetlink_log: - loggers now have to register struct nf_logger instead of nf_logfn - nf_log_unregister() replaced by nf_log_unregister_pf() and nf_log_unregister_logger() - add comment to ip[6]t_LOG.h to assure nobody redefines flags - add /proc/net/netfilter/nf_log to tell user which logger is currently registered for which address family - if user has configured logging, but no logging backend (logger) is available, always spit a message to syslog, not just the first time. - split ip[6]t_LOG.c into two parts: Backend: Always try to register as logger for the respective address family Frontend: Always log via nf_log_packet() API - modify all users of nf_log_packet() to accomodate additional argument Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter.h48
-rw-r--r--include/linux/netfilter_ipv4/ipt_LOG.h1
-rw-r--r--include/linux/netfilter_ipv6/ip6t_LOG.h1
-rw-r--r--net/core/netfilter.c127
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c21
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_udp.c6
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c86
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c33
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c93
10 files changed, 299 insertions, 125 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 711e05f33d68..815583af06c2 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -114,15 +114,51 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
114 114
115extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; 115extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
116 116
117typedef void nf_logfn(unsigned int hooknum, 117/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
118 * disappear once iptables is replaced with pkttables. Please DO NOT use them
119 * for any new code! */
120#define NF_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */
121#define NF_LOG_TCPOPT 0x02 /* Log TCP options */
122#define NF_LOG_IPOPT 0x04 /* Log IP options */
123#define NF_LOG_UID 0x08 /* Log UID owning local socket */
124#define NF_LOG_MASK 0x0f
125
126#define NF_LOG_TYPE_LOG 0x01
127#define NF_LOG_TYPE_ULOG 0x02
128
129struct nf_loginfo {
130 u_int8_t type;
131 union {
132 struct {
133 u_int32_t copy_len;
134 u_int16_t group;
135 u_int16_t qthreshold;
136 } ulog;
137 struct {
138 u_int8_t level;
139 u_int8_t logflags;
140 } log;
141 } u;
142};
143
144typedef void nf_logfn(unsigned int pf,
145 unsigned int hooknum,
118 const struct sk_buff *skb, 146 const struct sk_buff *skb,
119 const struct net_device *in, 147 const struct net_device *in,
120 const struct net_device *out, 148 const struct net_device *out,
149 const struct nf_loginfo *li,
121 const char *prefix); 150 const char *prefix);
122 151
152struct nf_logger {
153 struct module *me;
154 nf_logfn *logfn;
155 char *name;
156};
157
123/* Function to register/unregister log function. */ 158/* Function to register/unregister log function. */
124int nf_log_register(int pf, nf_logfn *logfn); 159int nf_log_register(int pf, struct nf_logger *logger);
125void nf_log_unregister(int pf, nf_logfn *logfn); 160void nf_log_unregister_pf(int pf);
161void nf_log_unregister_logger(struct nf_logger *logger);
126 162
127/* Calls the registered backend logging function */ 163/* Calls the registered backend logging function */
128void nf_log_packet(int pf, 164void nf_log_packet(int pf,
@@ -130,6 +166,7 @@ void nf_log_packet(int pf,
130 const struct sk_buff *skb, 166 const struct sk_buff *skb,
131 const struct net_device *in, 167 const struct net_device *in,
132 const struct net_device *out, 168 const struct net_device *out,
169 struct nf_loginfo *li,
133 const char *fmt, ...); 170 const char *fmt, ...);
134 171
135/* Activate hook; either okfn or kfree_skb called, unless a hook 172/* Activate hook; either okfn or kfree_skb called, unless a hook
@@ -221,6 +258,11 @@ struct nf_queue_rerouter {
221extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); 258extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer);
222extern int nf_unregister_queue_rerouter(int pf); 259extern int nf_unregister_queue_rerouter(int pf);
223 260
261#ifdef CONFIG_PROC_FS
262#include <linux/proc_fs.h>
263extern struct proc_dir_entry *proc_net_netfilter;
264#endif
265
224#else /* !CONFIG_NETFILTER */ 266#else /* !CONFIG_NETFILTER */
225#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) 267#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
226static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} 268static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h
index d25f782e57d1..22d16177319b 100644
--- a/include/linux/netfilter_ipv4/ipt_LOG.h
+++ b/include/linux/netfilter_ipv4/ipt_LOG.h
@@ -1,6 +1,7 @@
1#ifndef _IPT_LOG_H 1#ifndef _IPT_LOG_H
2#define _IPT_LOG_H 2#define _IPT_LOG_H
3 3
4/* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */
4#define IPT_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ 5#define IPT_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */
5#define IPT_LOG_TCPOPT 0x02 /* Log TCP options */ 6#define IPT_LOG_TCPOPT 0x02 /* Log TCP options */
6#define IPT_LOG_IPOPT 0x04 /* Log IP options */ 7#define IPT_LOG_IPOPT 0x04 /* Log IP options */
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h
index 42996a43bb39..9008ff5c40ae 100644
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h
+++ b/include/linux/netfilter_ipv6/ip6t_LOG.h
@@ -1,6 +1,7 @@
1#ifndef _IP6T_LOG_H 1#ifndef _IP6T_LOG_H
2#define _IP6T_LOG_H 2#define _IP6T_LOG_H
3 3
4/* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */
4#define IP6T_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ 5#define IP6T_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */
5#define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */ 6#define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */
6#define IP6T_LOG_IPOPT 0x04 /* Log IP options */ 7#define IP6T_LOG_IPOPT 0x04 /* Log IP options */
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index 3e38084ac2bd..98cc61e79fea 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -22,6 +22,7 @@
22#include <linux/if.h> 22#include <linux/if.h>
23#include <linux/netdevice.h> 23#include <linux/netdevice.h>
24#include <linux/inetdevice.h> 24#include <linux/inetdevice.h>
25#include <linux/proc_fs.h>
25#include <net/sock.h> 26#include <net/sock.h>
26 27
27/* In this code, we can be waiting indefinitely for userspace to 28/* In this code, we can be waiting indefinitely for userspace to
@@ -535,11 +536,10 @@ EXPORT_SYMBOL(skb_make_writable);
535 536
536#define NF_LOG_PREFIXLEN 128 537#define NF_LOG_PREFIXLEN 128
537 538
538static nf_logfn *nf_logging[NPROTO]; /* = NULL */ 539static struct nf_logger *nf_logging[NPROTO]; /* = NULL */
539static int reported = 0;
540static DEFINE_SPINLOCK(nf_log_lock); 540static DEFINE_SPINLOCK(nf_log_lock);
541 541
542int nf_log_register(int pf, nf_logfn *logfn) 542int nf_log_register(int pf, struct nf_logger *logger)
543{ 543{
544 int ret = -EBUSY; 544 int ret = -EBUSY;
545 545
@@ -547,54 +547,134 @@ int nf_log_register(int pf, nf_logfn *logfn)
547 * substituting pointer. */ 547 * substituting pointer. */
548 spin_lock(&nf_log_lock); 548 spin_lock(&nf_log_lock);
549 if (!nf_logging[pf]) { 549 if (!nf_logging[pf]) {
550 rcu_assign_pointer(nf_logging[pf], logfn); 550 rcu_assign_pointer(nf_logging[pf], logger);
551 ret = 0; 551 ret = 0;
552 } 552 }
553 spin_unlock(&nf_log_lock); 553 spin_unlock(&nf_log_lock);
554 return ret; 554 return ret;
555} 555}
556 556
557void nf_log_unregister(int pf, nf_logfn *logfn) 557void nf_log_unregister_pf(int pf)
558{ 558{
559 spin_lock(&nf_log_lock); 559 spin_lock(&nf_log_lock);
560 if (nf_logging[pf] == logfn) 560 nf_logging[pf] = NULL;
561 nf_logging[pf] = NULL;
562 spin_unlock(&nf_log_lock); 561 spin_unlock(&nf_log_lock);
563 562
564 /* Give time to concurrent readers. */ 563 /* Give time to concurrent readers. */
565 synchronize_net(); 564 synchronize_net();
566} 565}
566
567void nf_log_unregister_logger(struct nf_logger *logger)
568{
569 int i;
570
571 spin_lock(&nf_log_lock);
572 for (i = 0; i < NPROTO; i++) {
573 if (nf_logging[i] == logger)
574 nf_logging[i] = NULL;
575 }
576 spin_unlock(&nf_log_lock);
577
578 synchronize_net();
579}
567 580
568void nf_log_packet(int pf, 581void nf_log_packet(int pf,
569 unsigned int hooknum, 582 unsigned int hooknum,
570 const struct sk_buff *skb, 583 const struct sk_buff *skb,
571 const struct net_device *in, 584 const struct net_device *in,
572 const struct net_device *out, 585 const struct net_device *out,
586 struct nf_loginfo *loginfo,
573 const char *fmt, ...) 587 const char *fmt, ...)
574{ 588{
575 va_list args; 589 va_list args;
576 char prefix[NF_LOG_PREFIXLEN]; 590 char prefix[NF_LOG_PREFIXLEN];
577 nf_logfn *logfn; 591 struct nf_logger *logger;
578 592
579 rcu_read_lock(); 593 rcu_read_lock();
580 logfn = rcu_dereference(nf_logging[pf]); 594 logger = rcu_dereference(nf_logging[pf]);
581 if (logfn) { 595 if (logger) {
582 va_start(args, fmt); 596 va_start(args, fmt);
583 vsnprintf(prefix, sizeof(prefix), fmt, args); 597 vsnprintf(prefix, sizeof(prefix), fmt, args);
584 va_end(args); 598 va_end(args);
585 /* We must read logging before nf_logfn[pf] */ 599 /* We must read logging before nf_logfn[pf] */
586 logfn(hooknum, skb, in, out, prefix); 600 logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix);
587 } else if (!reported) { 601 } else if (net_ratelimit()) {
588 printk(KERN_WARNING "nf_log_packet: can\'t log yet, " 602 printk(KERN_WARNING "nf_log_packet: can\'t log since "
589 "no backend logging module loaded in!\n"); 603 "no backend logging module loaded in! Please either "
590 reported++; 604 "load one, or disable logging explicitly\n");
591 } 605 }
592 rcu_read_unlock(); 606 rcu_read_unlock();
593} 607}
594EXPORT_SYMBOL(nf_log_register); 608EXPORT_SYMBOL(nf_log_register);
595EXPORT_SYMBOL(nf_log_unregister); 609EXPORT_SYMBOL(nf_log_unregister_pf);
610EXPORT_SYMBOL(nf_log_unregister_logger);
596EXPORT_SYMBOL(nf_log_packet); 611EXPORT_SYMBOL(nf_log_packet);
597 612
613#ifdef CONFIG_PROC_FS
614struct proc_dir_entry *proc_net_netfilter;
615EXPORT_SYMBOL(proc_net_netfilter);
616
617static void *seq_start(struct seq_file *seq, loff_t *pos)
618{
619 rcu_read_lock();
620
621 if (*pos >= NPROTO)
622 return NULL;
623
624 return pos;
625}
626
627static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
628{
629 (*pos)++;
630
631 if (*pos >= NPROTO)
632 return NULL;
633
634 return pos;
635}
636
637static void seq_stop(struct seq_file *s, void *v)
638{
639 rcu_read_unlock();
640}
641
642static int seq_show(struct seq_file *s, void *v)
643{
644 loff_t *pos = v;
645 const struct nf_logger *logger;
646
647 logger = rcu_dereference(nf_logging[*pos]);
648
649 if (!logger)
650 return seq_printf(s, "%2lld NONE\n", *pos);
651
652 return seq_printf(s, "%2lld %s\n", *pos, logger->name);
653}
654
655static struct seq_operations nflog_seq_ops = {
656 .start = seq_start,
657 .next = seq_next,
658 .stop = seq_stop,
659 .show = seq_show,
660};
661
662static int nflog_open(struct inode *inode, struct file *file)
663{
664 return seq_open(file, &nflog_seq_ops);
665}
666
667static struct file_operations nflog_file_ops = {
668 .owner = THIS_MODULE,
669 .open = nflog_open,
670 .read = seq_read,
671 .llseek = seq_lseek,
672 .release = seq_release,
673};
674
675#endif /* PROC_FS */
676
677
598/* This does not belong here, but locally generated errors need it if connection 678/* This does not belong here, but locally generated errors need it if connection
599 tracking in use: without this, connection may not be in hash table, and hence 679 tracking in use: without this, connection may not be in hash table, and hence
600 manufactured ICMP or RST packets will not be associated with it. */ 680 manufactured ICMP or RST packets will not be associated with it. */
@@ -613,6 +693,9 @@ void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
613void __init netfilter_init(void) 693void __init netfilter_init(void)
614{ 694{
615 int i, h; 695 int i, h;
696#ifdef CONFIG_PROC_FS
697 struct proc_dir_entry *pde;
698#endif
616 699
617 queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter), 700 queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter),
618 GFP_KERNEL); 701 GFP_KERNEL);
@@ -624,6 +707,16 @@ void __init netfilter_init(void)
624 for (h = 0; h < NF_MAX_HOOKS; h++) 707 for (h = 0; h < NF_MAX_HOOKS; h++)
625 INIT_LIST_HEAD(&nf_hooks[i][h]); 708 INIT_LIST_HEAD(&nf_hooks[i][h]);
626 } 709 }
710
711#ifdef CONFIG_PROC_FS
712 proc_net_netfilter = proc_mkdir("netfilter", proc_net);
713 if (!proc_net_netfilter)
714 panic("cannot create netfilter proc entry");
715 pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter);
716 if (!pde)
717 panic("cannot create /proc/net/netfilter/nf_log");
718 pde->proc_fops = &nflog_file_ops;
719#endif
627} 720}
628 721
629EXPORT_SYMBOL(ip_ct_attach); 722EXPORT_SYMBOL(ip_ct_attach);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 3f90cb9979ac..838d1d69b36e 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
217 icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih); 217 icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih);
218 if (icmph == NULL) { 218 if (icmph == NULL) {
219 if (LOG_INVALID(IPPROTO_ICMP)) 219 if (LOG_INVALID(IPPROTO_ICMP))
220 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 220 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
221 "ip_ct_icmp: short packet "); 221 "ip_ct_icmp: short packet ");
222 return -NF_ACCEPT; 222 return -NF_ACCEPT;
223 } 223 }
@@ -231,13 +231,13 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
231 if (!(u16)csum_fold(skb->csum)) 231 if (!(u16)csum_fold(skb->csum))
232 break; 232 break;
233 if (LOG_INVALID(IPPROTO_ICMP)) 233 if (LOG_INVALID(IPPROTO_ICMP))
234 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 234 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
235 "ip_ct_icmp: bad HW ICMP checksum "); 235 "ip_ct_icmp: bad HW ICMP checksum ");
236 return -NF_ACCEPT; 236 return -NF_ACCEPT;
237 case CHECKSUM_NONE: 237 case CHECKSUM_NONE:
238 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { 238 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) {
239 if (LOG_INVALID(IPPROTO_ICMP)) 239 if (LOG_INVALID(IPPROTO_ICMP))
240 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 240 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
241 "ip_ct_icmp: bad ICMP checksum "); 241 "ip_ct_icmp: bad ICMP checksum ");
242 return -NF_ACCEPT; 242 return -NF_ACCEPT;
243 } 243 }
@@ -254,7 +254,7 @@ checksum_skipped:
254 */ 254 */
255 if (icmph->type > NR_ICMP_TYPES) { 255 if (icmph->type > NR_ICMP_TYPES) {
256 if (LOG_INVALID(IPPROTO_ICMP)) 256 if (LOG_INVALID(IPPROTO_ICMP))
257 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 257 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
258 "ip_ct_icmp: invalid ICMP type "); 258 "ip_ct_icmp: invalid ICMP type ");
259 return -NF_ACCEPT; 259 return -NF_ACCEPT;
260 } 260 }
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index c2bce22d4031..f23ef1f88c46 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -716,7 +716,7 @@ static int tcp_in_window(struct ip_ct_tcp *state,
716 res = 1; 716 res = 1;
717 } else { 717 } else {
718 if (LOG_INVALID(IPPROTO_TCP)) 718 if (LOG_INVALID(IPPROTO_TCP))
719 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 719 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
720 "ip_ct_tcp: %s ", 720 "ip_ct_tcp: %s ",
721 before(seq, sender->td_maxend + 1) ? 721 before(seq, sender->td_maxend + 1) ?
722 after(end, sender->td_end - receiver->td_maxwin - 1) ? 722 after(end, sender->td_end - receiver->td_maxwin - 1) ?
@@ -815,7 +815,7 @@ static int tcp_error(struct sk_buff *skb,
815 sizeof(_tcph), &_tcph); 815 sizeof(_tcph), &_tcph);
816 if (th == NULL) { 816 if (th == NULL) {
817 if (LOG_INVALID(IPPROTO_TCP)) 817 if (LOG_INVALID(IPPROTO_TCP))
818 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 818 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
819 "ip_ct_tcp: short packet "); 819 "ip_ct_tcp: short packet ");
820 return -NF_ACCEPT; 820 return -NF_ACCEPT;
821 } 821 }
@@ -823,7 +823,7 @@ static int tcp_error(struct sk_buff *skb,
823 /* Not whole TCP header or malformed packet */ 823 /* Not whole TCP header or malformed packet */
824 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { 824 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
825 if (LOG_INVALID(IPPROTO_TCP)) 825 if (LOG_INVALID(IPPROTO_TCP))
826 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 826 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
827 "ip_ct_tcp: truncated/malformed packet "); 827 "ip_ct_tcp: truncated/malformed packet ");
828 return -NF_ACCEPT; 828 return -NF_ACCEPT;
829 } 829 }
@@ -840,7 +840,7 @@ static int tcp_error(struct sk_buff *skb,
840 skb->ip_summed == CHECKSUM_HW ? skb->csum 840 skb->ip_summed == CHECKSUM_HW ? skb->csum
841 : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { 841 : skb_checksum(skb, iph->ihl*4, tcplen, 0))) {
842 if (LOG_INVALID(IPPROTO_TCP)) 842 if (LOG_INVALID(IPPROTO_TCP))
843 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 843 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
844 "ip_ct_tcp: bad TCP checksum "); 844 "ip_ct_tcp: bad TCP checksum ");
845 return -NF_ACCEPT; 845 return -NF_ACCEPT;
846 } 846 }
@@ -849,7 +849,7 @@ static int tcp_error(struct sk_buff *skb,
849 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR)); 849 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR));
850 if (!tcp_valid_flags[tcpflags]) { 850 if (!tcp_valid_flags[tcpflags]) {
851 if (LOG_INVALID(IPPROTO_TCP)) 851 if (LOG_INVALID(IPPROTO_TCP))
852 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 852 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
853 "ip_ct_tcp: invalid TCP flag combination "); 853 "ip_ct_tcp: invalid TCP flag combination ");
854 return -NF_ACCEPT; 854 return -NF_ACCEPT;
855 } 855 }
@@ -897,8 +897,9 @@ static int tcp_packet(struct ip_conntrack *conntrack,
897 */ 897 */
898 write_unlock_bh(&tcp_lock); 898 write_unlock_bh(&tcp_lock);
899 if (LOG_INVALID(IPPROTO_TCP)) 899 if (LOG_INVALID(IPPROTO_TCP))
900 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 900 nf_log_packet(PF_INET, 0, skb, NULL, NULL,
901 "ip_ct_tcp: killing out of sync session "); 901 NULL, "ip_ct_tcp: "
902 "killing out of sync session ");
902 if (del_timer(&conntrack->timeout)) 903 if (del_timer(&conntrack->timeout))
903 conntrack->timeout.function((unsigned long) 904 conntrack->timeout.function((unsigned long)
904 conntrack); 905 conntrack);
@@ -912,7 +913,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
912 913
913 write_unlock_bh(&tcp_lock); 914 write_unlock_bh(&tcp_lock);
914 if (LOG_INVALID(IPPROTO_TCP)) 915 if (LOG_INVALID(IPPROTO_TCP))
915 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 916 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
916 "ip_ct_tcp: invalid packet ignored "); 917 "ip_ct_tcp: invalid packet ignored ");
917 return NF_ACCEPT; 918 return NF_ACCEPT;
918 case TCP_CONNTRACK_MAX: 919 case TCP_CONNTRACK_MAX:
@@ -922,7 +923,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
922 old_state); 923 old_state);
923 write_unlock_bh(&tcp_lock); 924 write_unlock_bh(&tcp_lock);
924 if (LOG_INVALID(IPPROTO_TCP)) 925 if (LOG_INVALID(IPPROTO_TCP))
925 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 926 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
926 "ip_ct_tcp: invalid state "); 927 "ip_ct_tcp: invalid state ");
927 return -NF_ACCEPT; 928 return -NF_ACCEPT;
928 case TCP_CONNTRACK_SYN_SENT: 929 case TCP_CONNTRACK_SYN_SENT:
@@ -943,7 +944,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
943 write_unlock_bh(&tcp_lock); 944 write_unlock_bh(&tcp_lock);
944 if (LOG_INVALID(IPPROTO_TCP)) 945 if (LOG_INVALID(IPPROTO_TCP))
945 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 946 nf_log_packet(PF_INET, 0, skb, NULL, NULL,
946 "ip_ct_tcp: invalid SYN"); 947 NULL, "ip_ct_tcp: invalid SYN");
947 return -NF_ACCEPT; 948 return -NF_ACCEPT;
948 } 949 }
949 case TCP_CONNTRACK_CLOSE: 950 case TCP_CONNTRACK_CLOSE:
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
index 14130169cbfd..f2dcac7c7660 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -98,7 +98,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
98 hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr); 98 hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr);
99 if (hdr == NULL) { 99 if (hdr == NULL) {
100 if (LOG_INVALID(IPPROTO_UDP)) 100 if (LOG_INVALID(IPPROTO_UDP))
101 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 101 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
102 "ip_ct_udp: short packet "); 102 "ip_ct_udp: short packet ");
103 return -NF_ACCEPT; 103 return -NF_ACCEPT;
104 } 104 }
@@ -106,7 +106,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
106 /* Truncated/malformed packets */ 106 /* Truncated/malformed packets */
107 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { 107 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
108 if (LOG_INVALID(IPPROTO_UDP)) 108 if (LOG_INVALID(IPPROTO_UDP))
109 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 109 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
110 "ip_ct_udp: truncated/malformed packet "); 110 "ip_ct_udp: truncated/malformed packet ");
111 return -NF_ACCEPT; 111 return -NF_ACCEPT;
112 } 112 }
@@ -126,7 +126,7 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
126 skb->ip_summed == CHECKSUM_HW ? skb->csum 126 skb->ip_summed == CHECKSUM_HW ? skb->csum
127 : skb_checksum(skb, iph->ihl*4, udplen, 0))) { 127 : skb_checksum(skb, iph->ihl*4, udplen, 0))) {
128 if (LOG_INVALID(IPPROTO_UDP)) 128 if (LOG_INVALID(IPPROTO_UDP))
129 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 129 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
130 "ip_ct_udp: bad UDP checksum "); 130 "ip_ct_udp: bad UDP checksum ");
131 return -NF_ACCEPT; 131 return -NF_ACCEPT;
132 } 132 }
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index ef08733d26da..92ed050fac69 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -27,10 +27,6 @@ MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
28MODULE_DESCRIPTION("iptables syslog logging module"); 28MODULE_DESCRIPTION("iptables syslog logging module");
29 29
30static unsigned int nflog = 1;
31module_param(nflog, int, 0400);
32MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
33
34#if 0 30#if 0
35#define DEBUGP printk 31#define DEBUGP printk
36#else 32#else
@@ -41,11 +37,17 @@ MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
41static DEFINE_SPINLOCK(log_lock); 37static DEFINE_SPINLOCK(log_lock);
42 38
43/* One level of recursion won't kill us */ 39/* One level of recursion won't kill us */
44static void dump_packet(const struct ipt_log_info *info, 40static void dump_packet(const struct nf_loginfo *info,
45 const struct sk_buff *skb, 41 const struct sk_buff *skb,
46 unsigned int iphoff) 42 unsigned int iphoff)
47{ 43{
48 struct iphdr _iph, *ih; 44 struct iphdr _iph, *ih;
45 unsigned int logflags;
46
47 if (info->type == NF_LOG_TYPE_LOG)
48 logflags = info->u.log.logflags;
49 else
50 logflags = NF_LOG_MASK;
49 51
50 ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); 52 ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
51 if (ih == NULL) { 53 if (ih == NULL) {
@@ -76,7 +78,7 @@ static void dump_packet(const struct ipt_log_info *info,
76 if (ntohs(ih->frag_off) & IP_OFFSET) 78 if (ntohs(ih->frag_off) & IP_OFFSET)
77 printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); 79 printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
78 80
79 if ((info->logflags & IPT_LOG_IPOPT) 81 if ((logflags & IPT_LOG_IPOPT)
80 && ih->ihl * 4 > sizeof(struct iphdr)) { 82 && ih->ihl * 4 > sizeof(struct iphdr)) {
81 unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; 83 unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op;
82 unsigned int i, optsize; 84 unsigned int i, optsize;
@@ -119,7 +121,7 @@ static void dump_packet(const struct ipt_log_info *info,
119 printk("SPT=%u DPT=%u ", 121 printk("SPT=%u DPT=%u ",
120 ntohs(th->source), ntohs(th->dest)); 122 ntohs(th->source), ntohs(th->dest));
121 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 123 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
122 if (info->logflags & IPT_LOG_TCPSEQ) 124 if (logflags & IPT_LOG_TCPSEQ)
123 printk("SEQ=%u ACK=%u ", 125 printk("SEQ=%u ACK=%u ",
124 ntohl(th->seq), ntohl(th->ack_seq)); 126 ntohl(th->seq), ntohl(th->ack_seq));
125 /* Max length: 13 "WINDOW=65535 " */ 127 /* Max length: 13 "WINDOW=65535 " */
@@ -146,7 +148,7 @@ static void dump_packet(const struct ipt_log_info *info,
146 /* Max length: 11 "URGP=65535 " */ 148 /* Max length: 11 "URGP=65535 " */
147 printk("URGP=%u ", ntohs(th->urg_ptr)); 149 printk("URGP=%u ", ntohs(th->urg_ptr));
148 150
149 if ((info->logflags & IPT_LOG_TCPOPT) 151 if ((logflags & IPT_LOG_TCPOPT)
150 && th->doff * 4 > sizeof(struct tcphdr)) { 152 && th->doff * 4 > sizeof(struct tcphdr)) {
151 unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; 153 unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
152 unsigned char *op; 154 unsigned char *op;
@@ -328,7 +330,7 @@ static void dump_packet(const struct ipt_log_info *info,
328 } 330 }
329 331
330 /* Max length: 15 "UID=4294967295 " */ 332 /* Max length: 15 "UID=4294967295 " */
331 if ((info->logflags & IPT_LOG_UID) && !iphoff && skb->sk) { 333 if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
332 read_lock_bh(&skb->sk->sk_callback_lock); 334 read_lock_bh(&skb->sk->sk_callback_lock);
333 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 335 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
334 printk("UID=%u ", skb->sk->sk_socket->file->f_uid); 336 printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
@@ -349,19 +351,31 @@ static void dump_packet(const struct ipt_log_info *info,
349 /* maxlen = 230+ 91 + 230 + 252 = 803 */ 351 /* maxlen = 230+ 91 + 230 + 252 = 803 */
350} 352}
351 353
354struct nf_loginfo default_loginfo = {
355 .type = NF_LOG_TYPE_LOG,
356 .u = {
357 .log = {
358 .level = 0,
359 .logflags = NF_LOG_MASK,
360 },
361 },
362};
363
352static void 364static void
353ipt_log_packet(unsigned int hooknum, 365ipt_log_packet(unsigned int pf,
366 unsigned int hooknum,
354 const struct sk_buff *skb, 367 const struct sk_buff *skb,
355 const struct net_device *in, 368 const struct net_device *in,
356 const struct net_device *out, 369 const struct net_device *out,
357 const struct ipt_log_info *loginfo, 370 const struct nf_loginfo *loginfo,
358 const char *level_string,
359 const char *prefix) 371 const char *prefix)
360{ 372{
373 if (!loginfo)
374 loginfo = &default_loginfo;
375
361 spin_lock_bh(&log_lock); 376 spin_lock_bh(&log_lock);
362 printk(level_string); 377 printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
363 printk("%sIN=%s OUT=%s ", 378 prefix,
364 prefix == NULL ? loginfo->prefix : prefix,
365 in ? in->name : "", 379 in ? in->name : "",
366 out ? out->name : ""); 380 out ? out->name : "");
367#ifdef CONFIG_BRIDGE_NETFILTER 381#ifdef CONFIG_BRIDGE_NETFILTER
@@ -405,28 +419,15 @@ ipt_log_target(struct sk_buff **pskb,
405 void *userinfo) 419 void *userinfo)
406{ 420{
407 const struct ipt_log_info *loginfo = targinfo; 421 const struct ipt_log_info *loginfo = targinfo;
408 char level_string[4] = "< >"; 422 struct nf_loginfo li;
409 423
410 level_string[1] = '0' + (loginfo->level % 8); 424 li.type = NF_LOG_TYPE_LOG;
411 ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); 425 li.u.log.level = loginfo->level;
426 li.u.log.logflags = loginfo->logflags;
412 427
413 return IPT_CONTINUE; 428 nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix);
414}
415 429
416static void 430 return IPT_CONTINUE;
417ipt_logfn(unsigned int hooknum,
418 const struct sk_buff *skb,
419 const struct net_device *in,
420 const struct net_device *out,
421 const char *prefix)
422{
423 struct ipt_log_info loginfo = {
424 .level = 0,
425 .logflags = IPT_LOG_MASK,
426 .prefix = ""
427 };
428
429 ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
430} 431}
431 432
432static int ipt_log_checkentry(const char *tablename, 433static int ipt_log_checkentry(const char *tablename,
@@ -464,20 +465,29 @@ static struct ipt_target ipt_log_reg = {
464 .me = THIS_MODULE, 465 .me = THIS_MODULE,
465}; 466};
466 467
468static struct nf_logger ipt_log_logger ={
469 .name = "ipt_LOG",
470 .logfn = &ipt_log_packet,
471 .me = THIS_MODULE,
472};
473
467static int __init init(void) 474static int __init init(void)
468{ 475{
469 if (ipt_register_target(&ipt_log_reg)) 476 if (ipt_register_target(&ipt_log_reg))
470 return -EINVAL; 477 return -EINVAL;
471 if (nflog) 478 if (nf_log_register(PF_INET, &ipt_log_logger) < 0) {
472 nf_log_register(PF_INET, &ipt_logfn); 479 printk(KERN_WARNING "ipt_LOG: not logging via system console "
480 "since somebody else already registered for PF_INET\n");
481 /* we cannot make module load fail here, since otherwise
482 * iptables userspace would abort */
483 }
473 484
474 return 0; 485 return 0;
475} 486}
476 487
477static void __exit fini(void) 488static void __exit fini(void)
478{ 489{
479 if (nflog) 490 nf_log_unregister_logger(&ipt_log_logger);
480 nf_log_unregister(PF_INET, &ipt_logfn);
481 ipt_unregister_target(&ipt_log_reg); 491 ipt_unregister_target(&ipt_log_reg);
482} 492}
483 493
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 4ea8371ab270..b86f06ec9762 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -304,18 +304,27 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
304 return IPT_CONTINUE; 304 return IPT_CONTINUE;
305} 305}
306 306
307static void ipt_logfn(unsigned int hooknum, 307static void ipt_logfn(unsigned int pf,
308 unsigned int hooknum,
308 const struct sk_buff *skb, 309 const struct sk_buff *skb,
309 const struct net_device *in, 310 const struct net_device *in,
310 const struct net_device *out, 311 const struct net_device *out,
312 const struct nf_loginfo *li,
311 const char *prefix) 313 const char *prefix)
312{ 314{
313 struct ipt_ulog_info loginfo = { 315 struct ipt_ulog_info loginfo;
314 .nl_group = ULOG_DEFAULT_NLGROUP, 316
315 .copy_range = 0, 317 if (!li || li->type != NF_LOG_TYPE_ULOG) {
316 .qthreshold = ULOG_DEFAULT_QTHRESHOLD, 318 loginfo.nl_group = ULOG_DEFAULT_NLGROUP;
317 .prefix = "" 319 loginfo.copy_range = 0;
318 }; 320 loginfo.qthreshold = ULOG_DEFAULT_QTHRESHOLD;
321 loginfo.prefix[0] = '\0';
322 } else {
323 loginfo.nl_group = li->u.ulog.group;
324 loginfo.copy_range = li->u.ulog.copy_len;
325 loginfo.qthreshold = li->u.ulog.qthreshold;
326 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
327 }
319 328
320 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 329 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
321} 330}
@@ -355,6 +364,12 @@ static struct ipt_target ipt_ulog_reg = {
355 .me = THIS_MODULE, 364 .me = THIS_MODULE,
356}; 365};
357 366
367static struct nf_logger ipt_ulog_logger = {
368 .name = "ipt_ULOG",
369 .logfn = &ipt_logfn,
370 .me = THIS_MODULE,
371};
372
358static int __init init(void) 373static int __init init(void)
359{ 374{
360 int i; 375 int i;
@@ -382,7 +397,7 @@ static int __init init(void)
382 return -EINVAL; 397 return -EINVAL;
383 } 398 }
384 if (nflog) 399 if (nflog)
385 nf_log_register(PF_INET, &ipt_logfn); 400 nf_log_register(PF_INET, &ipt_ulog_logger);
386 401
387 return 0; 402 return 0;
388} 403}
@@ -395,7 +410,7 @@ static void __exit fini(void)
395 DEBUGP("ipt_ULOG: cleanup_module\n"); 410 DEBUGP("ipt_ULOG: cleanup_module\n");
396 411
397 if (nflog) 412 if (nflog)
398 nf_log_unregister(PF_INET, &ipt_logfn); 413 nf_log_unregister_logger(&ipt_ulog_logger);
399 ipt_unregister_target(&ipt_ulog_reg); 414 ipt_unregister_target(&ipt_ulog_reg);
400 sock_release(nflognl->sk_socket); 415 sock_release(nflognl->sk_socket);
401 416
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index a692e26a4fa3..0cd1d1bd9033 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -26,10 +26,6 @@ MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
26MODULE_DESCRIPTION("IP6 tables LOG target module"); 26MODULE_DESCRIPTION("IP6 tables LOG target module");
27MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
28 28
29static unsigned int nflog = 1;
30module_param(nflog, int, 0400);
31MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
32
33struct in_device; 29struct in_device;
34#include <net/route.h> 30#include <net/route.h>
35#include <linux/netfilter_ipv6/ip6t_LOG.h> 31#include <linux/netfilter_ipv6/ip6t_LOG.h>
@@ -44,7 +40,7 @@ struct in_device;
44static DEFINE_SPINLOCK(log_lock); 40static DEFINE_SPINLOCK(log_lock);
45 41
46/* One level of recursion won't kill us */ 42/* One level of recursion won't kill us */
47static void dump_packet(const struct ip6t_log_info *info, 43static void dump_packet(const struct nf_loginfo *info,
48 const struct sk_buff *skb, unsigned int ip6hoff, 44 const struct sk_buff *skb, unsigned int ip6hoff,
49 int recurse) 45 int recurse)
50{ 46{
@@ -53,6 +49,12 @@ static void dump_packet(const struct ip6t_log_info *info,
53 struct ipv6hdr _ip6h, *ih; 49 struct ipv6hdr _ip6h, *ih;
54 unsigned int ptr; 50 unsigned int ptr;
55 unsigned int hdrlen = 0; 51 unsigned int hdrlen = 0;
52 unsigned int logflags;
53
54 if (info->type == NF_LOG_TYPE_LOG)
55 logflags = info->u.log.logflags;
56 else
57 logflags = NF_LOG_MASK;
56 58
57 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); 59 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
58 if (ih == NULL) { 60 if (ih == NULL) {
@@ -84,7 +86,7 @@ static void dump_packet(const struct ip6t_log_info *info,
84 } 86 }
85 87
86 /* Max length: 48 "OPT (...) " */ 88 /* Max length: 48 "OPT (...) " */
87 if (info->logflags & IP6T_LOG_IPOPT) 89 if (logflags & IP6T_LOG_IPOPT)
88 printk("OPT ( "); 90 printk("OPT ( ");
89 91
90 switch (currenthdr) { 92 switch (currenthdr) {
@@ -119,7 +121,7 @@ static void dump_packet(const struct ip6t_log_info *info,
119 case IPPROTO_ROUTING: 121 case IPPROTO_ROUTING:
120 case IPPROTO_HOPOPTS: 122 case IPPROTO_HOPOPTS:
121 if (fragment) { 123 if (fragment) {
122 if (info->logflags & IP6T_LOG_IPOPT) 124 if (logflags & IP6T_LOG_IPOPT)
123 printk(")"); 125 printk(")");
124 return; 126 return;
125 } 127 }
@@ -127,7 +129,7 @@ static void dump_packet(const struct ip6t_log_info *info,
127 break; 129 break;
128 /* Max Length */ 130 /* Max Length */
129 case IPPROTO_AH: 131 case IPPROTO_AH:
130 if (info->logflags & IP6T_LOG_IPOPT) { 132 if (logflags & IP6T_LOG_IPOPT) {
131 struct ip_auth_hdr _ahdr, *ah; 133 struct ip_auth_hdr _ahdr, *ah;
132 134
133 /* Max length: 3 "AH " */ 135 /* Max length: 3 "AH " */
@@ -158,7 +160,7 @@ static void dump_packet(const struct ip6t_log_info *info,
158 hdrlen = (hp->hdrlen+2)<<2; 160 hdrlen = (hp->hdrlen+2)<<2;
159 break; 161 break;
160 case IPPROTO_ESP: 162 case IPPROTO_ESP:
161 if (info->logflags & IP6T_LOG_IPOPT) { 163 if (logflags & IP6T_LOG_IPOPT) {
162 struct ip_esp_hdr _esph, *eh; 164 struct ip_esp_hdr _esph, *eh;
163 165
164 /* Max length: 4 "ESP " */ 166 /* Max length: 4 "ESP " */
@@ -190,7 +192,7 @@ static void dump_packet(const struct ip6t_log_info *info,
190 printk("Unknown Ext Hdr %u", currenthdr); 192 printk("Unknown Ext Hdr %u", currenthdr);
191 return; 193 return;
192 } 194 }
193 if (info->logflags & IP6T_LOG_IPOPT) 195 if (logflags & IP6T_LOG_IPOPT)
194 printk(") "); 196 printk(") ");
195 197
196 currenthdr = hp->nexthdr; 198 currenthdr = hp->nexthdr;
@@ -218,7 +220,7 @@ static void dump_packet(const struct ip6t_log_info *info,
218 printk("SPT=%u DPT=%u ", 220 printk("SPT=%u DPT=%u ",
219 ntohs(th->source), ntohs(th->dest)); 221 ntohs(th->source), ntohs(th->dest));
220 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 222 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
221 if (info->logflags & IP6T_LOG_TCPSEQ) 223 if (logflags & IP6T_LOG_TCPSEQ)
222 printk("SEQ=%u ACK=%u ", 224 printk("SEQ=%u ACK=%u ",
223 ntohl(th->seq), ntohl(th->ack_seq)); 225 ntohl(th->seq), ntohl(th->ack_seq));
224 /* Max length: 13 "WINDOW=65535 " */ 226 /* Max length: 13 "WINDOW=65535 " */
@@ -245,7 +247,7 @@ static void dump_packet(const struct ip6t_log_info *info,
245 /* Max length: 11 "URGP=65535 " */ 247 /* Max length: 11 "URGP=65535 " */
246 printk("URGP=%u ", ntohs(th->urg_ptr)); 248 printk("URGP=%u ", ntohs(th->urg_ptr));
247 249
248 if ((info->logflags & IP6T_LOG_TCPOPT) 250 if ((logflags & IP6T_LOG_TCPOPT)
249 && th->doff * 4 > sizeof(struct tcphdr)) { 251 && th->doff * 4 > sizeof(struct tcphdr)) {
250 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 252 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
251 unsigned int i; 253 unsigned int i;
@@ -349,7 +351,7 @@ static void dump_packet(const struct ip6t_log_info *info,
349 } 351 }
350 352
351 /* Max length: 15 "UID=4294967295 " */ 353 /* Max length: 15 "UID=4294967295 " */
352 if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) { 354 if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
353 read_lock_bh(&skb->sk->sk_callback_lock); 355 read_lock_bh(&skb->sk->sk_callback_lock);
354 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 356 if (skb->sk->sk_socket && skb->sk->sk_socket->file)
355 printk("UID=%u ", skb->sk->sk_socket->file->f_uid); 357 printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
@@ -357,19 +359,31 @@ static void dump_packet(const struct ip6t_log_info *info,
357 } 359 }
358} 360}
359 361
362static struct nf_loginfo default_loginfo = {
363 .type = NF_LOG_TYPE_LOG,
364 .u = {
365 .log = {
366 .level = 0,
367 .logflags = NF_LOG_MASK,
368 },
369 },
370};
371
360static void 372static void
361ip6t_log_packet(unsigned int hooknum, 373ip6t_log_packet(unsigned int pf,
374 unsigned int hooknum,
362 const struct sk_buff *skb, 375 const struct sk_buff *skb,
363 const struct net_device *in, 376 const struct net_device *in,
364 const struct net_device *out, 377 const struct net_device *out,
365 const struct ip6t_log_info *loginfo, 378 const struct nf_loginfo *loginfo,
366 const char *level_string,
367 const char *prefix) 379 const char *prefix)
368{ 380{
381 if (!loginfo)
382 loginfo = &default_loginfo;
383
369 spin_lock_bh(&log_lock); 384 spin_lock_bh(&log_lock);
370 printk(level_string); 385 printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
371 printk("%sIN=%s OUT=%s ", 386 prefix,
372 prefix == NULL ? loginfo->prefix : prefix,
373 in ? in->name : "", 387 in ? in->name : "",
374 out ? out->name : ""); 388 out ? out->name : "");
375 if (in && !out) { 389 if (in && !out) {
@@ -416,29 +430,17 @@ ip6t_log_target(struct sk_buff **pskb,
416 void *userinfo) 430 void *userinfo)
417{ 431{
418 const struct ip6t_log_info *loginfo = targinfo; 432 const struct ip6t_log_info *loginfo = targinfo;
419 char level_string[4] = "< >"; 433 struct nf_loginfo li;
434
435 li.type = NF_LOG_TYPE_LOG;
436 li.u.log.level = loginfo->level;
437 li.u.log.logflags = loginfo->logflags;
420 438
421 level_string[1] = '0' + (loginfo->level % 8); 439 nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix);
422 ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL);
423 440
424 return IP6T_CONTINUE; 441 return IP6T_CONTINUE;
425} 442}
426 443
427static void
428ip6t_logfn(unsigned int hooknum,
429 const struct sk_buff *skb,
430 const struct net_device *in,
431 const struct net_device *out,
432 const char *prefix)
433{
434 struct ip6t_log_info loginfo = {
435 .level = 0,
436 .logflags = IP6T_LOG_MASK,
437 .prefix = ""
438 };
439
440 ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix);
441}
442 444
443static int ip6t_log_checkentry(const char *tablename, 445static int ip6t_log_checkentry(const char *tablename,
444 const struct ip6t_entry *e, 446 const struct ip6t_entry *e,
@@ -475,20 +477,29 @@ static struct ip6t_target ip6t_log_reg = {
475 .me = THIS_MODULE, 477 .me = THIS_MODULE,
476}; 478};
477 479
480static struct nf_logger ip6t_logger = {
481 .name = "ip6t_LOG",
482 .logfn = &ip6t_log_packet,
483 .me = THIS_MODULE,
484};
485
478static int __init init(void) 486static int __init init(void)
479{ 487{
480 if (ip6t_register_target(&ip6t_log_reg)) 488 if (ip6t_register_target(&ip6t_log_reg))
481 return -EINVAL; 489 return -EINVAL;
482 if (nflog) 490 if (nf_log_register(PF_INET6, &ip6t_logger) < 0) {
483 nf_log_register(PF_INET6, &ip6t_logfn); 491 printk(KERN_WARNING "ip6t_LOG: not logging via system console "
492 "since somebody else already registered for PF_INET6\n");
493 /* we cannot make module load fail here, since otherwise
494 * ip6tables userspace would abort */
495 }
484 496
485 return 0; 497 return 0;
486} 498}
487 499
488static void __exit fini(void) 500static void __exit fini(void)
489{ 501{
490 if (nflog) 502 nf_log_unregister_logger(&ip6t_logger);
491 nf_log_unregister(PF_INET6, &ip6t_logfn);
492 ip6t_unregister_target(&ip6t_log_reg); 503 ip6t_unregister_target(&ip6t_log_reg);
493} 504}
494 505