X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fipt_ULOG.c;h=6f2cefbe16cd8ccfcd3987b33e4b4e18ad1cc5cd;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c352df54aa1fc315cedd8dfe555681f4973d1749;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index c352df54a..6f2cefbe1 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -1,7 +1,7 @@ /* * netfilter module for userspace packet logging daemons * - * (C) 2000-2002 by Harald Welte + * (C) 2000-2004 by Harald Welte * * 2000/09/22 ulog-cprange feature added * 2001/01/04 in-kernel queue as proposed by Sebastian Zander @@ -13,6 +13,8 @@ * 2002/07/07 remove broken nflog_rcv() function -HW * 2002/08/29 fix shifted/unshifted nlgroup bug -HW * 2002/10/30 fix uninitialized mac_len field - + * 2004/10/25 fix erroneous calculation of 'len' parameter to NLMSG_PUT + * resulting in bogus 'error during NLMSG_PUT' messages. * * (C) 1999-2001 Paul `Rusty' Russell * (C) 2002-2004 Netfilter Core Team @@ -34,8 +36,8 @@ * by that factor. * * flushtimeout: - * Specify, after how many clock ticks (intel: 100 per second) the queue - * should be flushed even if it is not full yet. + * Specify, after how many hundredths of a second the queue should be + * flushed even if it is not full yet. * * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp */ @@ -50,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -74,15 +77,15 @@ MODULE_DESCRIPTION("iptables userspace logging module"); #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) static unsigned int nlbufsiz = 4096; -MODULE_PARM(nlbufsiz, "i"); +module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */ MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); -static unsigned int flushtimeout = 10 * HZ; -MODULE_PARM(flushtimeout, "i"); -MODULE_PARM_DESC(flushtimeout, "buffer flush timeout"); +static unsigned int flushtimeout = 10; +module_param(flushtimeout, int, 0600); +MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)"); static unsigned int nflog = 1; -MODULE_PARM(nflog, "i"); +module_param(nflog, int, 0400); MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); /* global data structures */ @@ -97,8 +100,7 @@ typedef struct { static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS]; /* array of buffers */ static struct sock *nflognl; /* our socket */ -static size_t qlen; /* current length of multipart-nlmsg */ -DECLARE_LOCK(ulog_lock); /* spinlock */ +static DECLARE_LOCK(ulog_lock); /* spinlock */ /* send one ulog_buff_t to userspace */ static void ulog_send(unsigned int nlgroupnum) @@ -116,7 +118,7 @@ static void ulog_send(unsigned int nlgroupnum) NETLINK_CB(ub->skb).dst_groups = (1 << nlgroupnum); DEBUGP("ipt_ULOG: throwing %d packets to netlink mask %u\n", - ub->qlen, nlgroup); + ub->qlen, nlgroupnum); netlink_broadcast(nflognl, ub->skb, 0, (1 << nlgroupnum), GFP_ATOMIC); ub->qlen = 0; @@ -126,7 +128,7 @@ static void ulog_send(unsigned int nlgroupnum) } -/* timer function to flush queue in ULOG_FLUSH_INTERVAL time */ +/* timer function to flush queue in flushtimeout time */ static void ulog_timer(unsigned long data) { DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n"); @@ -138,7 +140,7 @@ static void ulog_timer(unsigned long data) UNLOCK_BH(&ulog_lock); } -struct sk_buff *ulog_alloc_skb(unsigned int size) +static struct sk_buff *ulog_alloc_skb(unsigned int size) { struct sk_buff *skb; @@ -212,7 +214,7 @@ static void ipt_ulog_packet(unsigned int hooknum, /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, - size - sizeof(*nlh)); + sizeof(*pm)+copy_len); ub->qlen++; pm = NLMSG_DATA(nlh); @@ -261,20 +263,21 @@ static void ipt_ulog_packet(unsigned int hooknum, ub->lastnlh->nlmsg_flags |= NLM_F_MULTI; } - /* if threshold is reached, send message to userspace */ - if (qlen >= loginfo->qthreshold) { - if (loginfo->qthreshold > 1) - nlh->nlmsg_type = NLMSG_DONE; - } - ub->lastnlh = nlh; /* if timer isn't already running, start it */ if (!timer_pending(&ub->timer)) { - ub->timer.expires = jiffies + flushtimeout; + ub->timer.expires = jiffies + flushtimeout * HZ / 100; add_timer(&ub->timer); } + /* if threshold is reached, send message to userspace */ + if (ub->qlen >= loginfo->qthreshold) { + if (loginfo->qthreshold > 1) + nlh->nlmsg_type = NLMSG_DONE; + ulog_send(groupnum); + } + UNLOCK_BH(&ulog_lock); return;