Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Harald Welte and committed by
David S. Miller
608c8e4f 838ab636

+299 -125
+45 -3
include/linux/netfilter.h
··· 114 114 115 115 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; 116 116 117 - typedef 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 + 129 + struct 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 + 144 + typedef void nf_logfn(unsigned int pf, 145 + unsigned int hooknum, 118 146 const struct sk_buff *skb, 119 147 const struct net_device *in, 120 148 const struct net_device *out, 149 + const struct nf_loginfo *li, 121 150 const char *prefix); 122 151 152 + struct nf_logger { 153 + struct module *me; 154 + nf_logfn *logfn; 155 + char *name; 156 + }; 157 + 123 158 /* Function to register/unregister log function. */ 124 - int nf_log_register(int pf, nf_logfn *logfn); 125 - void nf_log_unregister(int pf, nf_logfn *logfn); 159 + int nf_log_register(int pf, struct nf_logger *logger); 160 + void nf_log_unregister_pf(int pf); 161 + void nf_log_unregister_logger(struct nf_logger *logger); 126 162 127 163 /* Calls the registered backend logging function */ 128 164 void nf_log_packet(int pf, ··· 166 130 const struct sk_buff *skb, 167 131 const struct net_device *in, 168 132 const struct net_device *out, 133 + struct nf_loginfo *li, 169 134 const char *fmt, ...); 170 135 171 136 /* Activate hook; either okfn or kfree_skb called, unless a hook ··· 257 220 258 221 extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer); 259 222 extern int nf_unregister_queue_rerouter(int pf); 223 + 224 + #ifdef CONFIG_PROC_FS 225 + #include <linux/proc_fs.h> 226 + extern struct proc_dir_entry *proc_net_netfilter; 227 + #endif 260 228 261 229 #else /* !CONFIG_NETFILTER */ 262 230 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+1
include/linux/netfilter_ipv4/ipt_LOG.h
··· 1 1 #ifndef _IPT_LOG_H 2 2 #define _IPT_LOG_H 3 3 4 + /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */ 4 5 #define IPT_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ 5 6 #define IPT_LOG_TCPOPT 0x02 /* Log TCP options */ 6 7 #define IPT_LOG_IPOPT 0x04 /* Log IP options */
+1
include/linux/netfilter_ipv6/ip6t_LOG.h
··· 1 1 #ifndef _IP6T_LOG_H 2 2 #define _IP6T_LOG_H 3 3 4 + /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */ 4 5 #define IP6T_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */ 5 6 #define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */ 6 7 #define IP6T_LOG_IPOPT 0x04 /* Log IP options */
+110 -17
net/core/netfilter.c
··· 22 22 #include <linux/if.h> 23 23 #include <linux/netdevice.h> 24 24 #include <linux/inetdevice.h> 25 + #include <linux/proc_fs.h> 25 26 #include <net/sock.h> 26 27 27 28 /* In this code, we can be waiting indefinitely for userspace to ··· 536 535 537 536 #define NF_LOG_PREFIXLEN 128 538 537 539 - static nf_logfn *nf_logging[NPROTO]; /* = NULL */ 540 - static int reported = 0; 538 + static struct nf_logger *nf_logging[NPROTO]; /* = NULL */ 541 539 static DEFINE_SPINLOCK(nf_log_lock); 542 540 543 - int nf_log_register(int pf, nf_logfn *logfn) 541 + int nf_log_register(int pf, struct nf_logger *logger) 544 542 { 545 543 int ret = -EBUSY; 546 544 ··· 547 547 * substituting pointer. */ 548 548 spin_lock(&nf_log_lock); 549 549 if (!nf_logging[pf]) { 550 - rcu_assign_pointer(nf_logging[pf], logfn); 550 + rcu_assign_pointer(nf_logging[pf], logger); 551 551 ret = 0; 552 552 } 553 553 spin_unlock(&nf_log_lock); 554 554 return ret; 555 555 } 556 556 557 - void nf_log_unregister(int pf, nf_logfn *logfn) 557 + void nf_log_unregister_pf(int pf) 558 558 { 559 559 spin_lock(&nf_log_lock); 560 - if (nf_logging[pf] == logfn) 561 - nf_logging[pf] = NULL; 560 + nf_logging[pf] = NULL; 562 561 spin_unlock(&nf_log_lock); 563 562 564 563 /* Give time to concurrent readers. */ 565 564 synchronize_net(); 566 - } 565 + } 566 + 567 + void 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 568 581 void nf_log_packet(int pf, 569 582 unsigned int hooknum, 570 583 const struct sk_buff *skb, 571 584 const struct net_device *in, 572 585 const struct net_device *out, 586 + struct nf_loginfo *loginfo, 573 587 const char *fmt, ...) 574 588 { 575 589 va_list args; 576 590 char prefix[NF_LOG_PREFIXLEN]; 577 - nf_logfn *logfn; 591 + struct nf_logger *logger; 578 592 579 593 rcu_read_lock(); 580 - logfn = rcu_dereference(nf_logging[pf]); 581 - if (logfn) { 594 + logger = rcu_dereference(nf_logging[pf]); 595 + if (logger) { 582 596 va_start(args, fmt); 583 597 vsnprintf(prefix, sizeof(prefix), fmt, args); 584 598 va_end(args); 585 599 /* We must read logging before nf_logfn[pf] */ 586 - logfn(hooknum, skb, in, out, prefix); 587 - } else if (!reported) { 588 - printk(KERN_WARNING "nf_log_packet: can\'t log yet, " 589 - "no backend logging module loaded in!\n"); 590 - reported++; 600 + logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); 601 + } else if (net_ratelimit()) { 602 + printk(KERN_WARNING "nf_log_packet: can\'t log since " 603 + "no backend logging module loaded in! Please either " 604 + "load one, or disable logging explicitly\n"); 591 605 } 592 606 rcu_read_unlock(); 593 607 } 594 608 EXPORT_SYMBOL(nf_log_register); 595 - EXPORT_SYMBOL(nf_log_unregister); 609 + EXPORT_SYMBOL(nf_log_unregister_pf); 610 + EXPORT_SYMBOL(nf_log_unregister_logger); 596 611 EXPORT_SYMBOL(nf_log_packet); 612 + 613 + #ifdef CONFIG_PROC_FS 614 + struct proc_dir_entry *proc_net_netfilter; 615 + EXPORT_SYMBOL(proc_net_netfilter); 616 + 617 + static 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 + 627 + static 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 + 637 + static void seq_stop(struct seq_file *s, void *v) 638 + { 639 + rcu_read_unlock(); 640 + } 641 + 642 + static 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 + 655 + static struct seq_operations nflog_seq_ops = { 656 + .start = seq_start, 657 + .next = seq_next, 658 + .stop = seq_stop, 659 + .show = seq_show, 660 + }; 661 + 662 + static int nflog_open(struct inode *inode, struct file *file) 663 + { 664 + return seq_open(file, &nflog_seq_ops); 665 + } 666 + 667 + static 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 + 597 677 598 678 /* This does not belong here, but locally generated errors need it if connection 599 679 tracking in use: without this, connection may not be in hash table, and hence ··· 693 613 void __init netfilter_init(void) 694 614 { 695 615 int i, h; 616 + #ifdef CONFIG_PROC_FS 617 + struct proc_dir_entry *pde; 618 + #endif 696 619 697 620 queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter), 698 621 GFP_KERNEL); ··· 707 624 for (h = 0; h < NF_MAX_HOOKS; h++) 708 625 INIT_LIST_HEAD(&nf_hooks[i][h]); 709 626 } 627 + 628 + #ifdef CONFIG_PROC_FS 629 + proc_net_netfilter = proc_mkdir("netfilter", proc_net); 630 + if (!proc_net_netfilter) 631 + panic("cannot create netfilter proc entry"); 632 + pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter); 633 + if (!pde) 634 + panic("cannot create /proc/net/netfilter/nf_log"); 635 + pde->proc_fops = &nflog_file_ops; 636 + #endif 710 637 } 711 638 712 639 EXPORT_SYMBOL(ip_ct_attach);
+4 -4
net/ipv4/netfilter/ip_conntrack_proto_icmp.c
··· 217 217 icmph = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_ih), &_ih); 218 218 if (icmph == NULL) { 219 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 221 "ip_ct_icmp: short packet "); 222 222 return -NF_ACCEPT; 223 223 } ··· 231 231 if (!(u16)csum_fold(skb->csum)) 232 232 break; 233 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 235 "ip_ct_icmp: bad HW ICMP checksum "); 236 236 return -NF_ACCEPT; 237 237 case CHECKSUM_NONE: 238 238 if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { 239 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 241 "ip_ct_icmp: bad ICMP checksum "); 242 242 return -NF_ACCEPT; 243 243 } ··· 254 254 */ 255 255 if (icmph->type > NR_ICMP_TYPES) { 256 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 258 "ip_ct_icmp: invalid ICMP type "); 259 259 return -NF_ACCEPT; 260 260 }
+11 -10
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
··· 716 716 res = 1; 717 717 } else { 718 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 720 "ip_ct_tcp: %s ", 721 721 before(seq, sender->td_maxend + 1) ? 722 722 after(end, sender->td_end - receiver->td_maxwin - 1) ? ··· 815 815 sizeof(_tcph), &_tcph); 816 816 if (th == NULL) { 817 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 819 "ip_ct_tcp: short packet "); 820 820 return -NF_ACCEPT; 821 821 } ··· 823 823 /* Not whole TCP header or malformed packet */ 824 824 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { 825 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 827 "ip_ct_tcp: truncated/malformed packet "); 828 828 return -NF_ACCEPT; 829 829 } ··· 840 840 skb->ip_summed == CHECKSUM_HW ? skb->csum 841 841 : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { 842 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 844 "ip_ct_tcp: bad TCP checksum "); 845 845 return -NF_ACCEPT; 846 846 } ··· 849 849 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR)); 850 850 if (!tcp_valid_flags[tcpflags]) { 851 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 853 "ip_ct_tcp: invalid TCP flag combination "); 854 854 return -NF_ACCEPT; 855 855 } ··· 897 897 */ 898 898 write_unlock_bh(&tcp_lock); 899 899 if (LOG_INVALID(IPPROTO_TCP)) 900 - nf_log_packet(PF_INET, 0, skb, NULL, NULL, 901 - "ip_ct_tcp: killing out of sync session "); 900 + nf_log_packet(PF_INET, 0, skb, NULL, NULL, 901 + NULL, "ip_ct_tcp: " 902 + "killing out of sync session "); 902 903 if (del_timer(&conntrack->timeout)) 903 904 conntrack->timeout.function((unsigned long) 904 905 conntrack); ··· 913 912 914 913 write_unlock_bh(&tcp_lock); 915 914 if (LOG_INVALID(IPPROTO_TCP)) 916 - nf_log_packet(PF_INET, 0, skb, NULL, NULL, 915 + nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 917 916 "ip_ct_tcp: invalid packet ignored "); 918 917 return NF_ACCEPT; 919 918 case TCP_CONNTRACK_MAX: ··· 923 922 old_state); 924 923 write_unlock_bh(&tcp_lock); 925 924 if (LOG_INVALID(IPPROTO_TCP)) 926 - nf_log_packet(PF_INET, 0, skb, NULL, NULL, 925 + nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 927 926 "ip_ct_tcp: invalid state "); 928 927 return -NF_ACCEPT; 929 928 case TCP_CONNTRACK_SYN_SENT: ··· 944 943 write_unlock_bh(&tcp_lock); 945 944 if (LOG_INVALID(IPPROTO_TCP)) 946 945 nf_log_packet(PF_INET, 0, skb, NULL, NULL, 947 - "ip_ct_tcp: invalid SYN"); 946 + NULL, "ip_ct_tcp: invalid SYN"); 948 947 return -NF_ACCEPT; 949 948 } 950 949 case TCP_CONNTRACK_CLOSE:
+3 -3
net/ipv4/netfilter/ip_conntrack_proto_udp.c
··· 98 98 hdr = skb_header_pointer(skb, iph->ihl*4, sizeof(_hdr), &_hdr); 99 99 if (hdr == NULL) { 100 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 102 "ip_ct_udp: short packet "); 103 103 return -NF_ACCEPT; 104 104 } ··· 106 106 /* Truncated/malformed packets */ 107 107 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { 108 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 110 "ip_ct_udp: truncated/malformed packet "); 111 111 return -NF_ACCEPT; 112 112 } ··· 126 126 skb->ip_summed == CHECKSUM_HW ? skb->csum 127 127 : skb_checksum(skb, iph->ihl*4, udplen, 0))) { 128 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 130 "ip_ct_udp: bad UDP checksum "); 131 131 return -NF_ACCEPT; 132 132 }
+48 -38
net/ipv4/netfilter/ipt_LOG.c
··· 27 27 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 28 28 MODULE_DESCRIPTION("iptables syslog logging module"); 29 29 30 - static unsigned int nflog = 1; 31 - module_param(nflog, int, 0400); 32 - MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); 33 - 34 30 #if 0 35 31 #define DEBUGP printk 36 32 #else ··· 37 41 static DEFINE_SPINLOCK(log_lock); 38 42 39 43 /* One level of recursion won't kill us */ 40 - static void dump_packet(const struct ipt_log_info *info, 44 + static void dump_packet(const struct nf_loginfo *info, 41 45 const struct sk_buff *skb, 42 46 unsigned int iphoff) 43 47 { 44 48 struct iphdr _iph, *ih; 49 + unsigned int logflags; 50 + 51 + if (info->type == NF_LOG_TYPE_LOG) 52 + logflags = info->u.log.logflags; 53 + else 54 + logflags = NF_LOG_MASK; 45 55 46 56 ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); 47 57 if (ih == NULL) { ··· 78 76 if (ntohs(ih->frag_off) & IP_OFFSET) 79 77 printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); 80 78 81 - if ((info->logflags & IPT_LOG_IPOPT) 79 + if ((logflags & IPT_LOG_IPOPT) 82 80 && ih->ihl * 4 > sizeof(struct iphdr)) { 83 81 unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op; 84 82 unsigned int i, optsize; ··· 121 119 printk("SPT=%u DPT=%u ", 122 120 ntohs(th->source), ntohs(th->dest)); 123 121 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 124 - if (info->logflags & IPT_LOG_TCPSEQ) 122 + if (logflags & IPT_LOG_TCPSEQ) 125 123 printk("SEQ=%u ACK=%u ", 126 124 ntohl(th->seq), ntohl(th->ack_seq)); 127 125 /* Max length: 13 "WINDOW=65535 " */ ··· 148 146 /* Max length: 11 "URGP=65535 " */ 149 147 printk("URGP=%u ", ntohs(th->urg_ptr)); 150 148 151 - if ((info->logflags & IPT_LOG_TCPOPT) 149 + if ((logflags & IPT_LOG_TCPOPT) 152 150 && th->doff * 4 > sizeof(struct tcphdr)) { 153 151 unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; 154 152 unsigned char *op; ··· 330 328 } 331 329 332 330 /* Max length: 15 "UID=4294967295 " */ 333 - if ((info->logflags & IPT_LOG_UID) && !iphoff && skb->sk) { 331 + if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { 334 332 read_lock_bh(&skb->sk->sk_callback_lock); 335 333 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 336 334 printk("UID=%u ", skb->sk->sk_socket->file->f_uid); ··· 351 349 /* maxlen = 230+ 91 + 230 + 252 = 803 */ 352 350 } 353 351 352 + struct nf_loginfo default_loginfo = { 353 + .type = NF_LOG_TYPE_LOG, 354 + .u = { 355 + .log = { 356 + .level = 0, 357 + .logflags = NF_LOG_MASK, 358 + }, 359 + }, 360 + }; 361 + 354 362 static void 355 - ipt_log_packet(unsigned int hooknum, 363 + ipt_log_packet(unsigned int pf, 364 + unsigned int hooknum, 356 365 const struct sk_buff *skb, 357 366 const struct net_device *in, 358 367 const struct net_device *out, 359 - const struct ipt_log_info *loginfo, 360 - const char *level_string, 368 + const struct nf_loginfo *loginfo, 361 369 const char *prefix) 362 370 { 371 + if (!loginfo) 372 + loginfo = &default_loginfo; 373 + 363 374 spin_lock_bh(&log_lock); 364 - printk(level_string); 365 - printk("%sIN=%s OUT=%s ", 366 - prefix == NULL ? loginfo->prefix : prefix, 375 + printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, 376 + prefix, 367 377 in ? in->name : "", 368 378 out ? out->name : ""); 369 379 #ifdef CONFIG_BRIDGE_NETFILTER ··· 419 405 void *userinfo) 420 406 { 421 407 const struct ipt_log_info *loginfo = targinfo; 422 - char level_string[4] = "< >"; 408 + struct nf_loginfo li; 423 409 424 - level_string[1] = '0' + (loginfo->level % 8); 425 - ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); 410 + li.type = NF_LOG_TYPE_LOG; 411 + li.u.log.level = loginfo->level; 412 + li.u.log.logflags = loginfo->logflags; 413 + 414 + nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); 426 415 427 416 return IPT_CONTINUE; 428 - } 429 - 430 - static void 431 - ipt_logfn(unsigned int hooknum, 432 - const struct sk_buff *skb, 433 - const struct net_device *in, 434 - const struct net_device *out, 435 - const char *prefix) 436 - { 437 - struct ipt_log_info loginfo = { 438 - .level = 0, 439 - .logflags = IPT_LOG_MASK, 440 - .prefix = "" 441 - }; 442 - 443 - ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); 444 417 } 445 418 446 419 static int ipt_log_checkentry(const char *tablename, ··· 465 464 .me = THIS_MODULE, 466 465 }; 467 466 467 + static struct nf_logger ipt_log_logger ={ 468 + .name = "ipt_LOG", 469 + .logfn = &ipt_log_packet, 470 + .me = THIS_MODULE, 471 + }; 472 + 468 473 static int __init init(void) 469 474 { 470 475 if (ipt_register_target(&ipt_log_reg)) 471 476 return -EINVAL; 472 - if (nflog) 473 - nf_log_register(PF_INET, &ipt_logfn); 477 + if (nf_log_register(PF_INET, &ipt_log_logger) < 0) { 478 + printk(KERN_WARNING "ipt_LOG: not logging via system console " 479 + "since somebody else already registered for PF_INET\n"); 480 + /* we cannot make module load fail here, since otherwise 481 + * iptables userspace would abort */ 482 + } 474 483 475 484 return 0; 476 485 } 477 486 478 487 static void __exit fini(void) 479 488 { 480 - if (nflog) 481 - nf_log_unregister(PF_INET, &ipt_logfn); 489 + nf_log_unregister_logger(&ipt_log_logger); 482 490 ipt_unregister_target(&ipt_log_reg); 483 491 } 484 492
+24 -9
net/ipv4/netfilter/ipt_ULOG.c
··· 304 304 return IPT_CONTINUE; 305 305 } 306 306 307 - static void ipt_logfn(unsigned int hooknum, 307 + static void ipt_logfn(unsigned int pf, 308 + unsigned int hooknum, 308 309 const struct sk_buff *skb, 309 310 const struct net_device *in, 310 311 const struct net_device *out, 312 + const struct nf_loginfo *li, 311 313 const char *prefix) 312 314 { 313 - struct ipt_ulog_info loginfo = { 314 - .nl_group = ULOG_DEFAULT_NLGROUP, 315 - .copy_range = 0, 316 - .qthreshold = ULOG_DEFAULT_QTHRESHOLD, 317 - .prefix = "" 318 - }; 315 + struct ipt_ulog_info loginfo; 316 + 317 + if (!li || li->type != NF_LOG_TYPE_ULOG) { 318 + loginfo.nl_group = ULOG_DEFAULT_NLGROUP; 319 + loginfo.copy_range = 0; 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 329 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 321 330 } ··· 364 355 .me = THIS_MODULE, 365 356 }; 366 357 358 + static struct nf_logger ipt_ulog_logger = { 359 + .name = "ipt_ULOG", 360 + .logfn = &ipt_logfn, 361 + .me = THIS_MODULE, 362 + }; 363 + 367 364 static int __init init(void) 368 365 { 369 366 int i; ··· 397 382 return -EINVAL; 398 383 } 399 384 if (nflog) 400 - nf_log_register(PF_INET, &ipt_logfn); 385 + nf_log_register(PF_INET, &ipt_ulog_logger); 401 386 402 387 return 0; 403 388 } ··· 410 395 DEBUGP("ipt_ULOG: cleanup_module\n"); 411 396 412 397 if (nflog) 413 - nf_log_unregister(PF_INET, &ipt_logfn); 398 + nf_log_unregister_logger(&ipt_ulog_logger); 414 399 ipt_unregister_target(&ipt_ulog_reg); 415 400 sock_release(nflognl->sk_socket); 416 401
+52 -41
net/ipv6/netfilter/ip6t_LOG.c
··· 26 26 MODULE_DESCRIPTION("IP6 tables LOG target module"); 27 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 29 struct in_device; 34 30 #include <net/route.h> 35 31 #include <linux/netfilter_ipv6/ip6t_LOG.h> ··· 40 44 static DEFINE_SPINLOCK(log_lock); 41 45 42 46 /* One level of recursion won't kill us */ 43 - static void dump_packet(const struct ip6t_log_info *info, 47 + static void dump_packet(const struct nf_loginfo *info, 44 48 const struct sk_buff *skb, unsigned int ip6hoff, 45 49 int recurse) 46 50 { ··· 49 53 struct ipv6hdr _ip6h, *ih; 50 54 unsigned int ptr; 51 55 unsigned int hdrlen = 0; 56 + unsigned int logflags; 57 + 58 + if (info->type == NF_LOG_TYPE_LOG) 59 + logflags = info->u.log.logflags; 60 + else 61 + logflags = NF_LOG_MASK; 52 62 53 63 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); 54 64 if (ih == NULL) { ··· 86 84 } 87 85 88 86 /* Max length: 48 "OPT (...) " */ 89 - if (info->logflags & IP6T_LOG_IPOPT) 87 + if (logflags & IP6T_LOG_IPOPT) 90 88 printk("OPT ( "); 91 89 92 90 switch (currenthdr) { ··· 121 119 case IPPROTO_ROUTING: 122 120 case IPPROTO_HOPOPTS: 123 121 if (fragment) { 124 - if (info->logflags & IP6T_LOG_IPOPT) 122 + if (logflags & IP6T_LOG_IPOPT) 125 123 printk(")"); 126 124 return; 127 125 } ··· 129 127 break; 130 128 /* Max Length */ 131 129 case IPPROTO_AH: 132 - if (info->logflags & IP6T_LOG_IPOPT) { 130 + if (logflags & IP6T_LOG_IPOPT) { 133 131 struct ip_auth_hdr _ahdr, *ah; 134 132 135 133 /* Max length: 3 "AH " */ ··· 160 158 hdrlen = (hp->hdrlen+2)<<2; 161 159 break; 162 160 case IPPROTO_ESP: 163 - if (info->logflags & IP6T_LOG_IPOPT) { 161 + if (logflags & IP6T_LOG_IPOPT) { 164 162 struct ip_esp_hdr _esph, *eh; 165 163 166 164 /* Max length: 4 "ESP " */ ··· 192 190 printk("Unknown Ext Hdr %u", currenthdr); 193 191 return; 194 192 } 195 - if (info->logflags & IP6T_LOG_IPOPT) 193 + if (logflags & IP6T_LOG_IPOPT) 196 194 printk(") "); 197 195 198 196 currenthdr = hp->nexthdr; ··· 220 218 printk("SPT=%u DPT=%u ", 221 219 ntohs(th->source), ntohs(th->dest)); 222 220 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ 223 - if (info->logflags & IP6T_LOG_TCPSEQ) 221 + if (logflags & IP6T_LOG_TCPSEQ) 224 222 printk("SEQ=%u ACK=%u ", 225 223 ntohl(th->seq), ntohl(th->ack_seq)); 226 224 /* Max length: 13 "WINDOW=65535 " */ ··· 247 245 /* Max length: 11 "URGP=65535 " */ 248 246 printk("URGP=%u ", ntohs(th->urg_ptr)); 249 247 250 - if ((info->logflags & IP6T_LOG_TCPOPT) 248 + if ((logflags & IP6T_LOG_TCPOPT) 251 249 && th->doff * 4 > sizeof(struct tcphdr)) { 252 250 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 253 251 unsigned int i; ··· 351 349 } 352 350 353 351 /* Max length: 15 "UID=4294967295 " */ 354 - if ((info->logflags & IP6T_LOG_UID) && recurse && skb->sk) { 352 + if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { 355 353 read_lock_bh(&skb->sk->sk_callback_lock); 356 354 if (skb->sk->sk_socket && skb->sk->sk_socket->file) 357 355 printk("UID=%u ", skb->sk->sk_socket->file->f_uid); ··· 359 357 } 360 358 } 361 359 360 + static struct nf_loginfo default_loginfo = { 361 + .type = NF_LOG_TYPE_LOG, 362 + .u = { 363 + .log = { 364 + .level = 0, 365 + .logflags = NF_LOG_MASK, 366 + }, 367 + }, 368 + }; 369 + 362 370 static void 363 - ip6t_log_packet(unsigned int hooknum, 371 + ip6t_log_packet(unsigned int pf, 372 + unsigned int hooknum, 364 373 const struct sk_buff *skb, 365 374 const struct net_device *in, 366 375 const struct net_device *out, 367 - const struct ip6t_log_info *loginfo, 368 - const char *level_string, 376 + const struct nf_loginfo *loginfo, 369 377 const char *prefix) 370 378 { 379 + if (!loginfo) 380 + loginfo = &default_loginfo; 381 + 371 382 spin_lock_bh(&log_lock); 372 - printk(level_string); 373 - printk("%sIN=%s OUT=%s ", 374 - prefix == NULL ? loginfo->prefix : prefix, 383 + printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, 384 + prefix, 375 385 in ? in->name : "", 376 386 out ? out->name : ""); 377 387 if (in && !out) { ··· 430 416 void *userinfo) 431 417 { 432 418 const struct ip6t_log_info *loginfo = targinfo; 433 - char level_string[4] = "< >"; 419 + struct nf_loginfo li; 434 420 435 - level_string[1] = '0' + (loginfo->level % 8); 436 - ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); 421 + li.type = NF_LOG_TYPE_LOG; 422 + li.u.log.level = loginfo->level; 423 + li.u.log.logflags = loginfo->logflags; 424 + 425 + nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix); 437 426 438 427 return IP6T_CONTINUE; 439 428 } 440 429 441 - static void 442 - ip6t_logfn(unsigned int hooknum, 443 - const struct sk_buff *skb, 444 - const struct net_device *in, 445 - const struct net_device *out, 446 - const char *prefix) 447 - { 448 - struct ip6t_log_info loginfo = { 449 - .level = 0, 450 - .logflags = IP6T_LOG_MASK, 451 - .prefix = "" 452 - }; 453 - 454 - ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); 455 - } 456 430 457 431 static int ip6t_log_checkentry(const char *tablename, 458 432 const struct ip6t_entry *e, ··· 477 475 .me = THIS_MODULE, 478 476 }; 479 477 478 + static struct nf_logger ip6t_logger = { 479 + .name = "ip6t_LOG", 480 + .logfn = &ip6t_log_packet, 481 + .me = THIS_MODULE, 482 + }; 483 + 480 484 static int __init init(void) 481 485 { 482 486 if (ip6t_register_target(&ip6t_log_reg)) 483 487 return -EINVAL; 484 - if (nflog) 485 - nf_log_register(PF_INET6, &ip6t_logfn); 488 + if (nf_log_register(PF_INET6, &ip6t_logger) < 0) { 489 + printk(KERN_WARNING "ip6t_LOG: not logging via system console " 490 + "since somebody else already registered for PF_INET6\n"); 491 + /* we cannot make module load fail here, since otherwise 492 + * ip6tables userspace would abort */ 493 + } 486 494 487 495 return 0; 488 496 } 489 497 490 498 static void __exit fini(void) 491 499 { 492 - if (nflog) 493 - nf_log_unregister(PF_INET6, &ip6t_logfn); 500 + nf_log_unregister_logger(&ip6t_logger); 494 501 ip6t_unregister_target(&ip6t_log_reg); 495 502 } 496 503