Răsfoiți Sursa

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

Linus Torvalds 19 ani în urmă
părinte
comite
98bd0c07b6

+ 2 - 2
include/linux/netfilter_ipv4/ipt_connbytes.h

@@ -1,10 +1,10 @@
 #ifndef _IPT_CONNBYTES_H
 #ifndef _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
 
 
-#include <net/netfilter/xt_connbytes.h>
+#include <linux/netfilter/xt_connbytes.h>
 #define ipt_connbytes_what xt_connbytes_what
 #define ipt_connbytes_what xt_connbytes_what
 
 
-#define IPT_CONNBYTES_PKTS	XT_CONNBYTES_PACKETS
+#define IPT_CONNBYTES_PKTS	XT_CONNBYTES_PKTS
 #define IPT_CONNBYTES_BYTES	XT_CONNBYTES_BYTES
 #define IPT_CONNBYTES_BYTES	XT_CONNBYTES_BYTES
 #define IPT_CONNBYTES_AVGPKT	XT_CONNBYTES_AVGPKT
 #define IPT_CONNBYTES_AVGPKT	XT_CONNBYTES_AVGPKT
 
 

+ 14 - 8
include/linux/netfilter_ipv4/ipt_policy.h

@@ -27,16 +27,22 @@ struct ipt_policy_spec
 			reqid:1;
 			reqid:1;
 };
 };
 
 
+union ipt_policy_addr
+{
+	struct in_addr	a4;
+	struct in6_addr	a6;
+};
+
 struct ipt_policy_elem
 struct ipt_policy_elem
 {
 {
-	u_int32_t	saddr;
-	u_int32_t	smask;
-	u_int32_t	daddr;
-	u_int32_t	dmask;
-	u_int32_t	spi;
-	u_int32_t	reqid;
-	u_int8_t	proto;
-	u_int8_t	mode;
+	union ipt_policy_addr	saddr;
+	union ipt_policy_addr	smask;
+	union ipt_policy_addr	daddr;
+	union ipt_policy_addr	dmask;
+	u_int32_t		spi;
+	u_int32_t		reqid;
+	u_int8_t		proto;
+	u_int8_t		mode;
 
 
 	struct ipt_policy_spec	match;
 	struct ipt_policy_spec	match;
 	struct ipt_policy_spec	invert;
 	struct ipt_policy_spec	invert;

+ 14 - 8
include/linux/netfilter_ipv6/ip6t_policy.h

@@ -27,16 +27,22 @@ struct ip6t_policy_spec
 			reqid:1;
 			reqid:1;
 };
 };
 
 
+union ip6t_policy_addr
+{
+	struct in_addr	a4;
+	struct in6_addr	a6;
+};
+
 struct ip6t_policy_elem
 struct ip6t_policy_elem
 {
 {
-	struct in6_addr	saddr;
-	struct in6_addr	smask;
-	struct in6_addr	daddr;
-	struct in6_addr	dmask;
-	u_int32_t	spi;
-	u_int32_t	reqid;
-	u_int8_t	proto;
-	u_int8_t	mode;
+	union ip6t_policy_addr	saddr;
+	union ip6t_policy_addr	smask;
+	union ip6t_policy_addr	daddr;
+	union ip6t_policy_addr	dmask;
+	u_int32_t		spi;
+	u_int32_t		reqid;
+	u_int8_t		proto;
+	u_int8_t		mode;
 
 
 	struct ip6t_policy_spec	match;
 	struct ip6t_policy_spec	match;
 	struct ip6t_policy_spec	invert;
 	struct ip6t_policy_spec	invert;

+ 9 - 6
include/net/netfilter/nf_conntrack_l3proto.h

@@ -88,12 +88,6 @@ extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX];
 extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
 extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto);
 extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 
 
-static inline struct nf_conntrack_l3proto *
-__nf_ct_l3proto_find(u_int16_t l3proto)
-{
-	return nf_ct_l3protos[l3proto];
-}
-
 extern struct nf_conntrack_l3proto *
 extern struct nf_conntrack_l3proto *
 nf_ct_l3proto_find_get(u_int16_t l3proto);
 nf_ct_l3proto_find_get(u_int16_t l3proto);
 
 
@@ -103,4 +97,13 @@ extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
 extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
 extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto;
+
+static inline struct nf_conntrack_l3proto *
+__nf_ct_l3proto_find(u_int16_t l3proto)
+{
+	if (unlikely(l3proto >= AF_MAX))
+		return &nf_conntrack_generic_l3proto;
+	return nf_ct_l3protos[l3proto];
+}
+
 #endif /*_NF_CONNTRACK_L3PROTO_H*/
 #endif /*_NF_CONNTRACK_L3PROTO_H*/

+ 6 - 4
net/bridge/netfilter/ebt_ulog.c

@@ -46,7 +46,7 @@
 #define PRINTR(format, args...) do { if (net_ratelimit()) \
 #define PRINTR(format, args...) do { if (net_ratelimit()) \
                                 printk(format , ## args); } while (0)
                                 printk(format , ## args); } while (0)
 
 
-static unsigned int nlbufsiz = 4096;
+static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0600);
 module_param(nlbufsiz, uint, 0600);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
                            "(defaults to 4096)");
                            "(defaults to 4096)");
@@ -98,12 +98,14 @@ static void ulog_timer(unsigned long data)
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
+	unsigned int n;
 
 
-	skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+	n = max(size, nlbufsiz);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
 	if (!skb) {
 		PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
 		PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
-		       "of size %ub!\n", nlbufsiz);
-		if (size < nlbufsiz) {
+		       "of size %ub!\n", n);
+		if (n > size) {
 			/* try to allocate only as much as we need for
 			/* try to allocate only as much as we need for
 			 * current packet */
 			 * current packet */
 			skb = alloc_skb(size, GFP_ATOMIC);
 			skb = alloc_skb(size, GFP_ATOMIC);

+ 7 - 0
net/bridge/netfilter/ebtables.c

@@ -934,6 +934,13 @@ static int do_replace(void __user *user, unsigned int len)
 		BUGPRINT("Entries_size never zero\n");
 		BUGPRINT("Entries_size never zero\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
+	/* overflow check */
+	if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+		return -ENOMEM;
+
 	countersize = COUNTER_OFFSET(tmp.nentries) * 
 	countersize = COUNTER_OFFSET(tmp.nentries) * 
 					(highest_possible_processor_id()+1);
 					(highest_possible_processor_id()+1);
 	newinfo = (struct ebt_table_info *)
 	newinfo = (struct ebt_table_info *)

+ 1 - 1
net/ipv4/icmp.c

@@ -524,7 +524,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
 					  iph->tos;
 					  iph->tos;
 
 
 	if (ip_options_echo(&icmp_param.replyopts, skb_in))
 	if (ip_options_echo(&icmp_param.replyopts, skb_in))
-		goto ende;
+		goto out_unlock;
 
 
 
 
 	/*
 	/*

+ 7 - 0
net/ipv4/netfilter/arp_tables.c

@@ -807,6 +807,13 @@ static int do_replace(void __user *user, unsigned int len)
 	if (len != sizeof(tmp) + tmp.size)
 	if (len != sizeof(tmp) + tmp.size)
 		return -ENOPROTOOPT;
 		return -ENOPROTOOPT;
 
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 	if (!newinfo)
 		return -ENOMEM;
 		return -ENOMEM;

+ 2 - 1
net/ipv4/netfilter/ip_conntrack_netlink.c

@@ -1216,7 +1216,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
 
 
 	b = skb->tail;
 	b = skb->tail;
 
 
-	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nfmsg = NLMSG_DATA(nlh);
 	nfmsg = NLMSG_DATA(nlh);
 
 
@@ -1567,6 +1567,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
 };
 };
 
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 
 static int __init ctnetlink_init(void)
 static int __init ctnetlink_init(void)
 {
 {

+ 1 - 0
net/ipv4/netfilter/ip_conntrack_tftp.c

@@ -71,6 +71,7 @@ static int tftp_help(struct sk_buff **pskb,
 
 
 		exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
 		exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
 		exp->mask.src.ip = 0xffffffff;
 		exp->mask.src.ip = 0xffffffff;
+		exp->mask.src.u.udp.port = 0;
 		exp->mask.dst.ip = 0xffffffff;
 		exp->mask.dst.ip = 0xffffffff;
 		exp->mask.dst.u.udp.port = 0xffff;
 		exp->mask.dst.u.udp.port = 0xffff;
 		exp->mask.dst.protonum = 0xff;
 		exp->mask.dst.protonum = 0xff;

+ 2 - 2
net/ipv4/netfilter/ip_nat_standalone.c

@@ -209,8 +209,8 @@ ip_nat_in(unsigned int hooknum,
 	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
 	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
 
-		if (ct->tuplehash[dir].tuple.src.ip !=
-		    ct->tuplehash[!dir].tuple.dst.ip) {
+		if (ct->tuplehash[dir].tuple.dst.ip !=
+		    ct->tuplehash[!dir].tuple.src.ip) {
 			dst_release((*pskb)->dst);
 			dst_release((*pskb)->dst);
 			(*pskb)->dst = NULL;
 			(*pskb)->dst = NULL;
 		}
 		}

+ 7 - 0
net/ipv4/netfilter/ip_tables.c

@@ -921,6 +921,13 @@ do_replace(void __user *user, unsigned int len)
 	if (len != sizeof(tmp) + tmp.size)
 	if (len != sizeof(tmp) + tmp.size)
 		return -ENOPROTOOPT;
 		return -ENOPROTOOPT;
 
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 	if (!newinfo)
 		return -ENOMEM;
 		return -ENOMEM;

+ 17 - 9
net/ipv4/netfilter/ipt_ULOG.c

@@ -35,6 +35,10 @@
  * each nlgroup you are using, so the total kernel memory usage increases
  * each nlgroup you are using, so the total kernel memory usage increases
  * by that factor.
  * 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:
  * flushtimeout:
  *   Specify, after how many hundredths of a second the queue should be
  *   Specify, after how many hundredths of a second the queue should be
  *   flushed even if it is not full yet.
  *   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)
 #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_param(nlbufsiz, uint, 0400);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
 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)
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
+	unsigned int n;
 
 
 	/* alloc skb which should be big enough for a whole
 	/* alloc skb which should be big enough for a whole
 	 * multipart message. WARNING: has to be <= 131000
 	 * multipart message. WARNING: has to be <= 131000
 	 * due to slab allocator restrictions */
 	 * due to slab allocator restrictions */
 
 
-	skb = alloc_skb(nlbufsiz, GFP_ATOMIC);
+	n = max(size, nlbufsiz);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
 	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;
 	return skb;

+ 7 - 4
net/ipv4/netfilter/ipt_policy.c

@@ -26,10 +26,13 @@ MODULE_LICENSE("GPL");
 static inline int
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
 match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
 {
 {
-#define MATCH(x,y)	(!e->match.x || ((e->x == (y)) ^ e->invert.x))
+#define MATCH_ADDR(x,y,z)	(!e->match.x ||				     \
+		                 ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
+				  ^ e->invert.x))
+#define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
 
-	return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
-	       MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+	return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
+	       MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
 	       MATCH(proto, x->id.proto) &&
 	       MATCH(proto, x->id.proto) &&
 	       MATCH(mode, x->props.mode) &&
 	       MATCH(mode, x->props.mode) &&
 	       MATCH(spi, x->id.spi) &&
 	       MATCH(spi, x->id.spi) &&
@@ -89,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
 			return 0;
 			return 0;
 	}
 	}
 
 
-	return strict ? 1 : 0;
+	return strict ? i == info->len : 0;
 }
 }
 
 
 static int match(const struct sk_buff *skb,
 static int match(const struct sk_buff *skb,

+ 7 - 0
net/ipv6/netfilter/ip6_tables.c

@@ -978,6 +978,13 @@ do_replace(void __user *user, unsigned int len)
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
 		return -EFAULT;
 
 
+	/* overflow check */
+	if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
+			SMP_CACHE_BYTES)
+		return -ENOMEM;
+	if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+		return -ENOMEM;
+
 	newinfo = xt_alloc_table_info(tmp.size);
 	newinfo = xt_alloc_table_info(tmp.size);
 	if (!newinfo)
 	if (!newinfo)
 		return -ENOMEM;
 		return -ENOMEM;

+ 4 - 3
net/ipv6/netfilter/ip6t_policy.c

@@ -26,8 +26,9 @@ MODULE_LICENSE("GPL");
 static inline int
 static inline int
 match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
 match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
 {
 {
-#define MATCH_ADDR(x,y,z)	(!e->match.x || \
-				 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
+#define MATCH_ADDR(x,y,z)	(!e->match.x ||				       \
+				 ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
+				  ^ e->invert.x))
 #define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 #define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
 	
 	
 	return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
 	return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
@@ -91,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
 			return 0;
 			return 0;
 	}
 	}
 
 
-	return strict ? 1 : 0;
+	return strict ? i == info->len : 0;
 }
 }
 
 
 static int match(const struct sk_buff *skb,
 static int match(const struct sk_buff *skb,

+ 1 - 1
net/netfilter/nf_conntrack_core.c

@@ -188,7 +188,7 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
 struct nf_conntrack_protocol *
 struct nf_conntrack_protocol *
 __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
 __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
 {
 {
-	if (unlikely(nf_ct_protos[l3proto] == NULL))
+	if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
 		return &nf_conntrack_generic_protocol;
 		return &nf_conntrack_generic_protocol;
 
 
 	return nf_ct_protos[l3proto][protocol];
 	return nf_ct_protos[l3proto][protocol];

+ 0 - 2
net/netfilter/nf_conntrack_ftp.c

@@ -657,8 +657,6 @@ static int __init init(void)
 	/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
 	/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
 		 are tracked or not - YK */
 		 are tracked or not - YK */
 	for (i = 0; i < ports_c; i++) {
 	for (i = 0; i < ports_c; i++) {
-		memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
-
 		ftp[i][0].tuple.src.l3num = PF_INET;
 		ftp[i][0].tuple.src.l3num = PF_INET;
 		ftp[i][1].tuple.src.l3num = PF_INET6;
 		ftp[i][1].tuple.src.l3num = PF_INET6;
 		for (j = 0; j < 2; j++) {
 		for (j = 0; j < 2; j++) {

+ 2 - 1
net/netfilter/nf_conntrack_netlink.c

@@ -1232,7 +1232,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
 
 
 	b = skb->tail;
 	b = skb->tail;
 
 
-	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
 	nfmsg = NLMSG_DATA(nlh);
 	nfmsg = NLMSG_DATA(nlh);
 
 
@@ -1589,6 +1589,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
 };
 };
 
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 
 static int __init ctnetlink_init(void)
 static int __init ctnetlink_init(void)
 {
 {

+ 12 - 8
net/netfilter/nfnetlink_log.c

@@ -37,7 +37,7 @@
 #include "../bridge/br_private.h"
 #include "../bridge/br_private.h"
 #endif
 #endif
 
 
-#define NFULNL_NLBUFSIZ_DEFAULT	4096
+#define NFULNL_NLBUFSIZ_DEFAULT	NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
 #define NFULNL_TIMEOUT_DEFAULT 	100	/* every second */
 #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
 #define NFULNL_QTHRESH_DEFAULT 	100	/* 100 packets */
 
 
@@ -314,24 +314,28 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
 					unsigned int pkt_size)
 					unsigned int pkt_size)
 {
 {
 	struct sk_buff *skb;
 	struct sk_buff *skb;
+	unsigned int n;
 
 
 	UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
 	UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
 
 
 	/* alloc skb which should be big enough for a whole multipart
 	/* alloc skb which should be big enough for a whole multipart
 	 * message.  WARNING: has to be <= 128k due to slab restrictions */
 	 * message.  WARNING: has to be <= 128k due to slab restrictions */
 
 
-	skb = alloc_skb(inst_size, GFP_ATOMIC);
+	n = max(inst_size, pkt_size);
+	skb = alloc_skb(n, GFP_ATOMIC);
 	if (!skb) {
 	if (!skb) {
 		PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n",
 		PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n",
 			inst_size);
 			inst_size);
 
 
-		/* try to allocate only as much as we need for current
-		 * packet */
+		if (n > pkt_size) {
+			/* try to allocate only as much as we need for current
+			 * packet */
 
 
-		skb = alloc_skb(pkt_size, GFP_ATOMIC);
-		if (!skb)
-			PRINTR("nfnetlink_log: can't even alloc %u bytes\n",
-				pkt_size);
+			skb = alloc_skb(pkt_size, GFP_ATOMIC);
+			if (!skb)
+				PRINTR("nfnetlink_log: can't even alloc %u "
+				       "bytes\n", pkt_size);
+		}
 	}
 	}
 
 
 	return skb;
 	return skb;

+ 2 - 1
net/netfilter/nfnetlink_queue.c

@@ -825,7 +825,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
 	}
 	}
 
 
 	if (nfqa[NFQA_MARK-1])
 	if (nfqa[NFQA_MARK-1])
-		skb->nfmark = ntohl(*(u_int32_t *)NFA_DATA(nfqa[NFQA_MARK-1]));
+		entry->skb->nfmark = ntohl(*(u_int32_t *)
+		                           NFA_DATA(nfqa[NFQA_MARK-1]));
 		
 		
 	issue_verdict(entry, verdict);
 	issue_verdict(entry, verdict);
 	instance_put(queue);
 	instance_put(queue);