diff options
Diffstat (limited to 'net/ipv4/netfilter/ipt_ULOG.c')
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 641dbc4..180a9ea 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -35,6 +35,10 @@ * each nlgroup you are using, so the total kernel memory usage increases * by that factor. * + * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since + * nlbufsiz is used with alloc_skb, which adds another + * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead. + * * flushtimeout: * Specify, after how many hundredths of a second the queue should be * flushed even if it is not full yet. @@ -76,7 +80,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) -static unsigned int nlbufsiz = 4096; +static unsigned int nlbufsiz = NLMSG_GOODSIZE; module_param(nlbufsiz, uint, 0400); MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); @@ -143,22 +147,26 @@ static void ulog_timer(unsigned long data) static struct sk_buff *ulog_alloc_skb(unsigned int size) { struct sk_buff *skb; + unsigned int n; /* alloc skb which should be big enough for a whole * multipart message. WARNING: has to be <= 131000 * due to slab allocator restrictions */ - skb = alloc_skb(nlbufsiz, GFP_ATOMIC); + n = max(size, nlbufsiz); + skb = alloc_skb(n, GFP_ATOMIC); if (!skb) { - PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", - nlbufsiz); + PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n); - /* try to allocate only as much as we need for - * current packet */ + if (n > size) { + /* try to allocate only as much as we need for + * current packet */ - skb = alloc_skb(size, GFP_ATOMIC); - if (!skb) - PRINTR("ipt_ULOG: can't even allocate %ub\n", size); + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) + PRINTR("ipt_ULOG: can't even allocate %ub\n", + size); + } } return skb; |