diff options
author | Harald Welte <laforge@netfilter.org> | 2005-08-09 22:58:27 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2005-08-29 18:38:07 -0400 |
commit | 608c8e4f7b6e61cc783283e9dff8a465a5ad59bb (patch) | |
tree | 55ca8bed99789cd6af07f6cc6ee99b0cf718a611 /net/ipv6 | |
parent | 838ab6364956d9bdcefe84712de1621cf20a40b3 (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>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 93 |
1 files changed, 52 insertions, 41 deletions
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>"); | |||
26 | MODULE_DESCRIPTION("IP6 tables LOG target module"); | 26 | MODULE_DESCRIPTION("IP6 tables LOG target module"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | 28 | ||
29 | static unsigned int nflog = 1; | ||
30 | module_param(nflog, int, 0400); | ||
31 | MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); | ||
32 | |||
33 | struct in_device; | 29 | struct 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; | |||
44 | static DEFINE_SPINLOCK(log_lock); | 40 | static DEFINE_SPINLOCK(log_lock); |
45 | 41 | ||
46 | /* One level of recursion won't kill us */ | 42 | /* One level of recursion won't kill us */ |
47 | static void dump_packet(const struct ip6t_log_info *info, | 43 | static 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 | ||
362 | static 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 | |||
360 | static void | 372 | static void |
361 | ip6t_log_packet(unsigned int hooknum, | 373 | ip6t_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 | ||
427 | static void | ||
428 | ip6t_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 | ||
443 | static int ip6t_log_checkentry(const char *tablename, | 445 | static 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 | ||
480 | static struct nf_logger ip6t_logger = { | ||
481 | .name = "ip6t_LOG", | ||
482 | .logfn = &ip6t_log_packet, | ||
483 | .me = THIS_MODULE, | ||
484 | }; | ||
485 | |||
478 | static int __init init(void) | 486 | static 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 | ||
488 | static void __exit fini(void) | 500 | static 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 | ||