All of lore.kernel.org
 help / color / mirror / Atom feed
* [NETFILTER 00/08]: Netfilter Update part II
@ 2007-07-14 15:12 Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header Patrick McHardy
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

Hi Dave,

following is a second small netfilter update with patches that missed the
first one, containing a new match for limiting the number of connections
by a host, some cleanup by Yasuyuki and UDP-Lite conntrack support. NAT
support is still missing, I'll probably add that in 2.6.24.

Please apply, thanks.


 include/linux/netfilter/xt_connlimit.h         |   17 ++
 include/net/netfilter/ipv4/nf_conntrack_ipv4.h |    2 +
 include/net/netfilter/ipv6/nf_conntrack_ipv6.h |    2 +-
 include/net/netfilter/nf_conntrack.h           |    4 +
 include/net/netfilter/nf_conntrack_l3proto.h   |    8 +-
 net/bridge/netfilter/ebtables.c                |    4 +-
 net/ipv4/netfilter/arp_tables.c                |    2 +-
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |   25 ++-
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |   57 +----
 net/ipv6/netfilter/ip6_tables.c                |    2 +-
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   31 ++-
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |   46 +---
 net/netfilter/Kconfig                          |   17 ++
 net/netfilter/Makefile                         |    2 +
 net/netfilter/nf_conntrack_core.c              |   37 +++-
 net/netfilter/nf_conntrack_l3proto_generic.c   |    9 +-
 net/netfilter/nf_conntrack_proto_generic.c     |    2 +-
 net/netfilter/nf_conntrack_proto_gre.c         |    2 +-
 net/netfilter/nf_conntrack_proto_sctp.c        |    4 +-
 net/netfilter/nf_conntrack_proto_tcp.c         |    4 +-
 net/netfilter/nf_conntrack_proto_udp.c         |    4 +-
 net/netfilter/nf_conntrack_proto_udplite.c     |  266 ++++++++++++++++++++
 net/netfilter/xt_connlimit.c                   |  313 ++++++++++++++++++++++++
 23 files changed, 730 insertions(+), 130 deletions(-)
 create mode 100644 include/linux/netfilter/xt_connlimit.h
 create mode 100644 net/netfilter/nf_conntrack_proto_udplite.c
 create mode 100644 net/netfilter/xt_connlimit.c

Jan Engelhardt (1):
      [NETFILTER]: x_tables: add connlimit match

Patrick McHardy (3):
      [NETFILTER]: Lower *tables printk severity
      [NETFILTER]: nf_conntrack: mark protocols __read_mostly
      [NETFILTER]: nf_conntrack: UDPLITE support

Yasuyuki Kozakai (4):
      [NETFILTER]: nf_conntrack: Increment error count on parsing IPv4 header
      [NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it
      [NETFILTER]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it
      [NETFILTER]: nf_conntrack: Don't track locally generated special ICMP error

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:44   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it Patrick McHardy
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: Increment error count on parsing IPv4 header

Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 95f7e72287ad5133bfefdf16cba3f6a1afb1ddb1
tree 1afb502056db9c764bbaf70db92f04e51e41d769
parent d84fbb3afb83c70385ccd341c2c4ed3b795c3963
author Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Sat, 14 Jul 2007 17:02:08 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:08 +0200

 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    2 --
 net/netfilter/nf_conntrack_core.c              |    2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 89e20ab..b5c4bb5 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -131,8 +131,6 @@ ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
 	 */
 	if ((protoff < 0) || (protoff > (*pskb)->len)) {
 		pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
-		NF_CT_STAT_INC_ATOMIC(error);
-		NF_CT_STAT_INC_ATOMIC(invalid);
 		return -NF_ACCEPT;
 	}
 
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 3d14110..b730413 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -625,6 +625,8 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
 
 	if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
 		pr_debug("not prepared to track yet or error occured\n");
+		NF_CT_STAT_INC_ATOMIC(error);
+		NF_CT_STAT_INC_ATOMIC(invalid);
 		return -ret;
 	}
 

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:45   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 03/08]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it Patrick McHardy
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it

The icmp[v6] l4proto modules parse headers in ICMP[v6] error to get tuple.
But they have to find the offset to transport protocol header before that.
Their processings are almost same as prepare() of l3proto modules.
This makes prepare() more generic to simplify icmp[v6] l4proto module
later.

Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 967124a1cd396030f714bc5dfb8c809d3429ee44
tree c4913f1f7e63c643ee717b833864bb4c43d4c82f
parent 95f7e72287ad5133bfefdf16cba3f6a1afb1ddb1
author Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Sat, 14 Jul 2007 17:02:12 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:12 +0200

 include/net/netfilter/ipv6/nf_conntrack_ipv6.h |    2 +-
 include/net/netfilter/nf_conntrack_l3proto.h   |    6 +++--
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |   23 ++++++++++++--------
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   27 ++++++++++++++----------
 net/netfilter/nf_conntrack_core.c              |    5 +++-
 net/netfilter/nf_conntrack_l3proto_generic.c   |    7 +++---
 6 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index b4b6049..5a89659 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -7,7 +7,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
 
-extern int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start,
+extern int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start,
 				  u8 *nexthdrp, int len);
 
 extern int nf_ct_frag6_init(void);
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 890752d..e3708a6 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -58,11 +58,11 @@ struct nf_conntrack_l3proto
 
 	/*
 	 * Called before tracking. 
-	 *	*dataoff: offset of protocol header (TCP, UDP,...) in *pskb
+	 *	*dataoff: offset of protocol header (TCP, UDP,...) in skb
 	 *	*protonum: protocol number
 	 */
-	int (*prepare)(struct sk_buff **pskb, unsigned int hooknum,
-		       unsigned int *dataoff, u_int8_t *protonum);
+	int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff,
+			   unsigned int *dataoff, u_int8_t *protonum);
 
 	int (*tuple_to_nfattr)(struct sk_buff *skb,
 			       const struct nf_conntrack_tuple *t);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 3c56299..ee29f4e 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -78,21 +78,26 @@ nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 	return skb;
 }
 
-static int
-ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
-	     u_int8_t *protonum)
+static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
+			    unsigned int *dataoff, u_int8_t *protonum)
 {
+	struct iphdr _iph, *iph;
+
+	iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
+	if (iph == NULL)
+		return -NF_DROP;
+
 	/* Never happen */
-	if (ip_hdr(*pskb)->frag_off & htons(IP_OFFSET)) {
+	if (iph->frag_off & htons(IP_OFFSET)) {
 		if (net_ratelimit()) {
-			printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n",
-			ip_hdr(*pskb)->protocol, hooknum);
+			printk(KERN_ERR "ipv4_get_l4proto: Frag of proto %u\n",
+			iph->protocol);
 		}
 		return -NF_DROP;
 	}
 
-	*dataoff = skb_network_offset(*pskb) + ip_hdrlen(*pskb);
-	*protonum = ip_hdr(*pskb)->protocol;
+	*dataoff = nhoff + (iph->ihl << 2);
+	*protonum = iph->protocol;
 
 	return NF_ACCEPT;
 }
@@ -407,7 +412,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
 	.invert_tuple	 = ipv4_invert_tuple,
 	.print_tuple	 = ipv4_print_tuple,
 	.print_conntrack = ipv4_print_conntrack,
-	.prepare	 = ipv4_prepare,
+	.get_l4proto	 = ipv4_get_l4proto,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 	.tuple_to_nfattr = ipv4_tuple_to_nfattr,
 	.nfattr_to_tuple = ipv4_nfattr_to_tuple,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index b5c4bb5..9b7eaaa 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -86,7 +86,7 @@ static int ipv6_print_conntrack(struct seq_file *s,
  *        - Note also special handling of AUTH header. Thanks to IPsec wizards.
  */
 
-int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp,
+int nf_ct_ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp,
 			   int len)
 {
 	u8 nexthdr = *nexthdrp;
@@ -117,19 +117,24 @@ int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp,
 	return start;
 }
 
-static int
-ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
-	     u_int8_t *protonum)
+static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
+			    unsigned int *dataoff, u_int8_t *protonum)
 {
-	unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data;
-	unsigned char pnum = ipv6_hdr(*pskb)->nexthdr;
-	int protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
-					     (*pskb)->len - extoff);
+	unsigned int extoff = nhoff + sizeof(struct ipv6hdr);
+	unsigned char pnum;
+	int protoff;
+
+	if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr),
+			  &pnum, sizeof(pnum)) != 0) {
+		pr_debug("ip6_conntrack_core: can't get nexthdr\n");
+		return -NF_ACCEPT;
+	}
+	protoff = nf_ct_ipv6_skip_exthdr(skb, extoff, &pnum, skb->len - extoff);
 	/*
-	 * (protoff == (*pskb)->len) mean that the packet doesn't have no data
+	 * (protoff == skb->len) mean that the packet doesn't have no data
 	 * except of IPv6 & ext headers. but it's tracked anyway. - YK
 	 */
-	if ((protoff < 0) || (protoff > (*pskb)->len)) {
+	if ((protoff < 0) || (protoff > skb->len)) {
 		pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
 		return -NF_ACCEPT;
 	}
@@ -375,7 +380,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
 	.invert_tuple		= ipv6_invert_tuple,
 	.print_tuple		= ipv6_print_tuple,
 	.print_conntrack	= ipv6_print_conntrack,
-	.prepare		= ipv6_prepare,
+	.get_l4proto		= ipv6_get_l4proto,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 	.tuple_to_nfattr	= ipv6_tuple_to_nfattr,
 	.nfattr_to_tuple	= ipv6_nfattr_to_tuple,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b730413..5b194e3 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -622,8 +622,9 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
 
 	/* rcu_read_lock()ed by nf_hook_slow */
 	l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
-
-	if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
+	ret = l3proto->get_l4proto(*pskb, skb_network_offset(*pskb),
+				   &dataoff, &protonum);
+	if (ret <= 0) {
 		pr_debug("not prepared to track yet or error occured\n");
 		NF_CT_STAT_INC_ATOMIC(error);
 		NF_CT_STAT_INC_ATOMIC(invalid);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index b1bfa20..0691642 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -61,9 +61,8 @@ static int generic_print_conntrack(struct seq_file *s,
 	return 0;
 }
 
-static int
-generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
-		unsigned int *dataoff, u_int8_t *protonum)
+static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
+			       unsigned int *dataoff, u_int8_t *protonum)
 {
 	/* Never track !!! */
 	return -NF_ACCEPT;
@@ -77,6 +76,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
 	.invert_tuple	 = generic_invert_tuple,
 	.print_tuple	 = generic_print_tuple,
 	.print_conntrack = generic_print_conntrack,
-	.prepare	 = generic_prepare,
+	.get_l4proto	 = generic_get_l4proto,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 03/08]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error Patrick McHardy
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it

nf_ct_get_tuple() requires the offset to transport header and that bothers
callers such as icmp[v6] l4proto modules. This introduces new function
to simplify them.

Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit dabf3efb72da4003b4e22a8159e9ad3007502683
tree 4c6765bd334e0f0bc482947aa457baff1114d532
parent 967124a1cd396030f714bc5dfb8c809d3429ee44
author Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Sat, 14 Jul 2007 17:02:14 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:14 +0200

 include/net/netfilter/nf_conntrack.h           |    4 ++
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |   32 ++++--------------
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |   42 +++++-------------------
 net/netfilter/nf_conntrack_core.c              |   30 +++++++++++++++++
 4 files changed, 49 insertions(+), 59 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d4f02eb..810020e 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -186,6 +186,10 @@ extern void nf_conntrack_hash_insert(struct nf_conn *ct);
 
 extern void nf_conntrack_flush(void);
 
+extern int nf_ct_get_tuplepr(const struct sk_buff *skb,
+			     unsigned int nhoff,
+			     u_int16_t l3num,
+			     struct nf_conntrack_tuple *tuple);
 extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
 				const struct nf_conntrack_tuple *orig);
 
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 0fe8fb0..b8b7999 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -136,40 +136,22 @@ icmp_error_message(struct sk_buff *skb,
 		 unsigned int hooknum)
 {
 	struct nf_conntrack_tuple innertuple, origtuple;
-	struct {
-		struct icmphdr icmp;
-		struct iphdr ip;
-	} _in, *inside;
 	struct nf_conntrack_l4proto *innerproto;
 	struct nf_conntrack_tuple_hash *h;
-	int dataoff;
 
 	NF_CT_ASSERT(skb->nfct == NULL);
 
-	/* Not enough header? */
-	inside = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_in), &_in);
-	if (inside == NULL)
-		return -NF_ACCEPT;
-
-	/* Ignore ICMP's containing fragments (shouldn't happen) */
-	if (inside->ip.frag_off & htons(IP_OFFSET)) {
-		pr_debug("icmp_error_message: fragment of proto %u\n",
-			 inside->ip.protocol);
+	/* Are they talking about one of our connections? */
+	if (!nf_ct_get_tuplepr(skb,
+			       skb_network_offset(skb) + ip_hdrlen(skb)
+						       + sizeof(struct icmphdr),
+			       PF_INET, &origtuple)) {
+		pr_debug("icmp_error_message: failed to get tuple\n");
 		return -NF_ACCEPT;
 	}
 
 	/* rcu_read_lock()ed by nf_hook_slow */
-	innerproto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
-
-	dataoff = ip_hdrlen(skb) + sizeof(inside->icmp);
-	/* Are they talking about one of our connections? */
-	if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
-			     inside->ip.protocol, &origtuple,
-			     &nf_conntrack_l3proto_ipv4, innerproto)) {
-		pr_debug("icmp_error_message: ! get_tuple p=%u",
-			 inside->ip.protocol);
-		return -NF_ACCEPT;
-	}
+	innerproto = __nf_ct_l4proto_find(PF_INET, origtuple.dst.protonum);
 
 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
 	   been preserved inside the ICMP. */
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 9defc7e..0fca7e8 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -136,49 +136,23 @@ icmpv6_error_message(struct sk_buff *skb,
 {
 	struct nf_conntrack_tuple intuple, origtuple;
 	struct nf_conntrack_tuple_hash *h;
-	struct icmp6hdr _hdr, *hp;
-	unsigned int inip6off;
 	struct nf_conntrack_l4proto *inproto;
-	u_int8_t inprotonum;
-	unsigned int inprotoff;
 
 	NF_CT_ASSERT(skb->nfct == NULL);
 
-	hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
-	if (hp == NULL) {
-		pr_debug("icmpv6_error: Can't get ICMPv6 hdr.\n");
-		return -NF_ACCEPT;
-	}
-
-	inip6off = icmp6off + sizeof(_hdr);
-	if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
-			  &inprotonum, sizeof(inprotonum)) != 0) {
-		pr_debug("icmpv6_error: Can't get nexthdr in inner IPv6 "
-			 "header.\n");
-		return -NF_ACCEPT;
-	}
-	inprotoff = nf_ct_ipv6_skip_exthdr(skb,
-					   inip6off + sizeof(struct ipv6hdr),
-					   &inprotonum,
-					   skb->len - inip6off
-						    - sizeof(struct ipv6hdr));
-
-	if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
-		pr_debug("icmpv6_error: Can't get protocol header in ICMPv6 "
-			 "payload.\n");
-		return -NF_ACCEPT;
-	}
-
-	/* rcu_read_lock()ed by nf_hook_slow */
-	inproto = __nf_ct_l4proto_find(PF_INET6, inprotonum);
-
 	/* Are they talking about one of our connections? */
-	if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
-			     &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
+	if (!nf_ct_get_tuplepr(skb,
+			       skb_network_offset(skb)
+				+ sizeof(struct ipv6hdr)
+				+ sizeof(struct icmp6hdr),
+			       PF_INET6, &origtuple)) {
 		pr_debug("icmpv6_error: Can't get tuple\n");
 		return -NF_ACCEPT;
 	}
 
+	/* rcu_read_lock()ed by nf_hook_slow */
+	inproto = __nf_ct_l4proto_find(PF_INET6, origtuple.dst.protonum);
+
 	/* Ordinarily, we'd expect the inverted tupleproto, but it's
 	   been preserved inside the ICMP. */
 	if (!nf_ct_invert_tuple(&intuple, &origtuple,
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5b194e3..8cce814 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -113,6 +113,36 @@ nf_ct_get_tuple(const struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(nf_ct_get_tuple);
 
+int nf_ct_get_tuplepr(const struct sk_buff *skb,
+		      unsigned int nhoff,
+		      u_int16_t l3num,
+		      struct nf_conntrack_tuple *tuple)
+{
+	struct nf_conntrack_l3proto *l3proto;
+	struct nf_conntrack_l4proto *l4proto;
+	unsigned int protoff;
+	u_int8_t protonum;
+	int ret;
+
+	rcu_read_lock();
+
+	l3proto = __nf_ct_l3proto_find(l3num);
+	ret = l3proto->get_l4proto(skb, nhoff, &protoff, &protonum);
+	if (ret != NF_ACCEPT) {
+		rcu_read_unlock();
+		return 0;
+	}
+
+	l4proto = __nf_ct_l4proto_find(l3num, protonum);
+
+	ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, tuple,
+			      l3proto, l4proto);
+
+	rcu_read_unlock();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(nf_ct_get_tuplepr);
+
 int
 nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
 		   const struct nf_conntrack_tuple *orig,

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
                   ` (2 preceding siblings ...)
  2007-07-14 15:12 ` [NETFILTER 03/08]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:45   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 05/08]: Lower *tables printk severity Patrick McHardy
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: Don't track locally generated special ICMP error

The conntrack assigned to locally generated ICMP error is usually the one
assigned to the original packet which has caused the error. But if
the original packet is handled as invalid by nf_conntrack, no conntrack
is assigned to the original packet. Then nf_ct_attach() cannot assign
any conntrack to the ICMP error packet. In that case the current
nf_conntrack_icmp assigns appropriate conntrack to it. But the current
code mistakes the direction of the packet. As a result, NAT code mistakes
the address to be mangled.

To fix the bug, this changes nf_conntrack_icmp not to assign conntrack
to such ICMP error. Actually no address is necessary to be mangled
in this case.

Spotted by Jordan Russell.

Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 28b86df4d02014ae5ce0be0e82c074f15ea0dabf
tree 4f1d74fa6059740eb380260300f87e39c4e911ac
parent dabf3efb72da4003b4e22a8159e9ad3007502683
author Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Sat, 14 Jul 2007 17:02:19 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:19 +0200

 net/ipv4/netfilter/nf_conntrack_proto_icmp.c |   22 +++++-----------------
 1 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index b8b7999..f965733 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -165,25 +165,13 @@ icmp_error_message(struct sk_buff *skb,
 
 	h = nf_conntrack_find_get(&innertuple);
 	if (!h) {
-		/* Locally generated ICMPs will match inverted if they
-		   haven't been SNAT'ed yet */
-		/* FIXME: NAT code has to handle half-done double NAT --RR */
-		if (hooknum == NF_IP_LOCAL_OUT)
-			h = nf_conntrack_find_get(&origtuple);
-
-		if (!h) {
-			pr_debug("icmp_error_message: no match\n");
-			return -NF_ACCEPT;
-		}
-
-		/* Reverse direction from that found */
-		if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
-			*ctinfo += IP_CT_IS_REPLY;
-	} else {
-		if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
-			*ctinfo += IP_CT_IS_REPLY;
+		pr_debug("icmp_error_message: no match\n");
+		return -NF_ACCEPT;
 	}
 
+	if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
+		*ctinfo += IP_CT_IS_REPLY;
+
 	/* Update skb to refer to this connection */
 	skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
 	skb->nfctinfo = *ctinfo;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 05/08]: Lower *tables printk severity
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
                   ` (3 preceding siblings ...)
  2007-07-14 15:12 ` [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:46   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 06/08]: x_tables: add connlimit match Patrick McHardy
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: Lower *tables printk severity

Lower ip6tables, arptables and ebtables printk severity similar to
Dan Aloni's patch for iptables.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit f1cdf0338ecef77b6c1999ae177b4fd21134e625
tree e4ae3f9367502508a48d852fe5492da39ed8cc85
parent 28b86df4d02014ae5ce0be0e82c074f15ea0dabf
author Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:23 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:23 +0200

 net/bridge/netfilter/ebtables.c |    4 ++--
 net/ipv4/netfilter/arp_tables.c |    2 +-
 net/ipv6/netfilter/ip6_tables.c |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index ac9984f..4169a2a 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1525,14 +1525,14 @@ static int __init ebtables_init(void)
 	if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0)
 		return ret;
 
-	printk(KERN_NOTICE "Ebtables v2.0 registered\n");
+	printk(KERN_INFO "Ebtables v2.0 registered\n");
 	return 0;
 }
 
 static void __exit ebtables_fini(void)
 {
 	nf_unregister_sockopt(&ebt_sockopts);
-	printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
+	printk(KERN_INFO "Ebtables v2.0 unregistered\n");
 }
 
 EXPORT_SYMBOL(ebt_register_table);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index e981232..d1149ab 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1184,7 +1184,7 @@ static int __init arp_tables_init(void)
 	if (ret < 0)
 		goto err4;
 
-	printk("arp_tables: (C) 2002 David S. Miller\n");
+	printk(KERN_INFO "arp_tables: (C) 2002 David S. Miller\n");
 	return 0;
 
 err4:
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 254c769..aeda617 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1497,7 +1497,7 @@ static int __init ip6_tables_init(void)
 	if (ret < 0)
 		goto err5;
 
-	printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
+	printk(KERN_INFO "ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
 	return 0;
 
 err5:

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 06/08]: x_tables: add connlimit match
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
                   ` (4 preceding siblings ...)
  2007-07-14 15:12 ` [NETFILTER 05/08]: Lower *tables printk severity Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:47   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly Patrick McHardy
  2007-07-14 15:12 ` [NETFILTER 08/08]: nf_conntrack: UDPLITE support Patrick McHardy
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 11658 bytes --]

[NETFILTER]: x_tables: add connlimit match

ipt_connlimit has been sitting in POM-NG for a long time.
Here is a new shiny xt_connlimit with:

 * xtables'ified
 * will request the layer3 module
   (previously it hotdropped every packet when it was not loaded)
 * fixed: there was a deadlock in case of an OOM condition
 * support for any layer4 protocol (e.g. UDP/SCTP)
 * using jhash, as suggested by Eric Dumazet
 * ipv6 support

Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit ce0ae6ad80f3673eaaa2fb1cab9771939c7e84c6
tree 4078537dc92a3d24c9e42f9b4651c72fc4079fa6
parent f1cdf0338ecef77b6c1999ae177b4fd21134e625
author Jan Engelhardt <jengelh@gmx.de> Sat, 14 Jul 2007 17:02:26 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:05:25 +0200

 include/linux/netfilter/xt_connlimit.h |   17 ++
 net/netfilter/Kconfig                  |    7 +
 net/netfilter/Makefile                 |    1 
 net/netfilter/xt_connlimit.c           |  313 ++++++++++++++++++++++++++++++++
 4 files changed, 338 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/xt_connlimit.h b/include/linux/netfilter/xt_connlimit.h
new file mode 100644
index 0000000..90ae8b4
--- /dev/null
+++ b/include/linux/netfilter/xt_connlimit.h
@@ -0,0 +1,17 @@
+#ifndef _XT_CONNLIMIT_H
+#define _XT_CONNLIMIT_H
+
+struct xt_connlimit_data;
+
+struct xt_connlimit_info {
+	union {
+		u_int32_t v4_mask;
+		u_int32_t v6_mask[4];
+	};
+	unsigned int limit, inverse;
+
+	/* this needs to be at the end */
+	struct xt_connlimit_data *data __attribute__((aligned(8)));
+};
+
+#endif /* _XT_CONNLIMIT_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index df5e8da..9415b9a 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -423,6 +423,13 @@ config NETFILTER_XT_MATCH_CONNBYTES
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_MATCH_CONNLIMIT
+	tristate '"connlimit" match support"'
+	depends on NETFILTER_XTABLES
+	---help---
+	  This match allows you to match against the number of parallel
+	  connections to a server per client IP address (or address block).
+
 config NETFILTER_XT_MATCH_CONNMARK
 	tristate  '"connmark" connection mark match support'
 	depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 58b4245..3e4a16a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
 # matches
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
new file mode 100644
index 0000000..fba803f
--- /dev/null
+++ b/net/netfilter/xt_connlimit.c
@@ -0,0 +1,313 @@
+/*
+ * netfilter module to limit the number of parallel tcp
+ * connections per IP address.
+ *   (c) 2000 Gerd Knorr <kraxel@bytesex.org>
+ *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
+ *		only ignore TIME_WAIT or gone connections
+ *   Copyright © Jan Engelhardt <jengelh@gmx.de>, 2007
+ *
+ * based on ...
+ *
+ * Kernel module to match connection tracking information.
+ * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
+ */
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/jhash.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/netfilter/nf_conntrack_tcp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_connlimit.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_tuple.h>
+
+/* we will save the tuples of all connections we care about */
+struct xt_connlimit_conn {
+	struct list_head list;
+	struct nf_conntrack_tuple tuple;
+};
+
+struct xt_connlimit_data {
+	struct list_head iphash[256];
+	spinlock_t lock;
+};
+
+static u_int32_t connlimit_rnd;
+static bool connlimit_rnd_inited;
+
+static inline unsigned int connlimit_iphash(u_int32_t addr)
+{
+	if (unlikely(!connlimit_rnd_inited)) {
+		get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd));
+		connlimit_rnd_inited = true;
+	}
+	return jhash_1word(addr, connlimit_rnd) & 0xFF;
+}
+
+static inline unsigned int
+connlimit_iphash6(const union nf_conntrack_address *addr,
+		  const union nf_conntrack_address *mask)
+{
+	union nf_conntrack_address res;
+	unsigned int i;
+
+	if (unlikely(!connlimit_rnd_inited)) {
+		get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd));
+		connlimit_rnd_inited = true;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i)
+		res.ip6[i] = addr->ip6[i] & mask->ip6[i];
+
+	return jhash2(res.ip6, ARRAY_SIZE(res.ip6), connlimit_rnd) & 0xFF;
+}
+
+static inline bool already_closed(const struct nf_conn *conn)
+{
+	u_int16_t proto = conn->tuplehash[0].tuple.dst.protonum;
+
+	if (proto == IPPROTO_TCP)
+		return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT;
+	else
+		return 0;
+}
+
+static inline unsigned int
+same_source_net(const union nf_conntrack_address *addr,
+		const union nf_conntrack_address *mask,
+		const union nf_conntrack_address *u3, unsigned int family)
+{
+	if (family == AF_INET) {
+		return (addr->ip & mask->ip) == (u3->ip & mask->ip);
+	} else {
+		union nf_conntrack_address lh, rh;
+		unsigned int i;
+
+		for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i) {
+			lh.ip6[i] = addr->ip6[i] & mask->ip6[i];
+			rh.ip6[i] = u3->ip6[i] & mask->ip6[i];
+		}
+
+		return memcmp(&lh.ip6, &rh.ip6, sizeof(lh.ip6)) == 0;
+	}
+}
+
+static int count_them(struct xt_connlimit_data *data,
+		      const struct nf_conntrack_tuple *tuple,
+		      const union nf_conntrack_address *addr,
+		      const union nf_conntrack_address *mask,
+		      const struct xt_match *match)
+{
+	struct nf_conntrack_tuple_hash *found;
+	struct xt_connlimit_conn *conn;
+	struct xt_connlimit_conn *tmp;
+	struct nf_conn *found_ct;
+	struct list_head *hash;
+	bool addit = true;
+	int matches = 0;
+
+
+	if (match->family == AF_INET6)
+		hash = &data->iphash[connlimit_iphash6(addr, mask)];
+	else
+		hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
+
+	read_lock_bh(&nf_conntrack_lock);
+
+	/* check the saved connections */
+	list_for_each_entry_safe(conn, tmp, hash, list) {
+		found    = __nf_conntrack_find(&conn->tuple, NULL);
+		found_ct = NULL;
+
+		if (found != NULL)
+			found_ct = nf_ct_tuplehash_to_ctrack(found);
+
+		if (found_ct != NULL &&
+		    nf_ct_tuple_equal(&conn->tuple, tuple) &&
+		    !already_closed(found_ct))
+			/*
+			 * Just to be sure we have it only once in the list.
+			 * We should not see tuples twice unless someone hooks
+			 * this into a table without "-p tcp --syn".
+			 */
+			addit = false;
+
+		if (found == NULL) {
+			/* this one is gone */
+			list_del(&conn->list);
+			kfree(conn);
+			continue;
+		}
+
+		if (already_closed(found_ct)) {
+			/*
+			 * we do not care about connections which are
+			 * closed already -> ditch it
+			 */
+			list_del(&conn->list);
+			kfree(conn);
+			continue;
+		}
+
+		if (same_source_net(addr, mask, &conn->tuple.src.u3,
+		    match->family))
+			/* same source network -> be counted! */
+			++matches;
+	}
+
+	read_unlock_bh(&nf_conntrack_lock);
+
+	if (addit) {
+		/* save the new connection in our list */
+		conn = kzalloc(sizeof(*conn), GFP_ATOMIC);
+		if (conn == NULL)
+			return -ENOMEM;
+		conn->tuple = *tuple;
+		list_add(&conn->list, hash);
+		++matches;
+	}
+
+	return matches;
+}
+
+static bool connlimit_match(const struct sk_buff *skb,
+			    const struct net_device *in,
+			    const struct net_device *out,
+			    const struct xt_match *match,
+			    const void *matchinfo, int offset,
+			    unsigned int protoff, bool *hotdrop)
+{
+	const struct xt_connlimit_info *info = matchinfo;
+	union nf_conntrack_address addr, mask;
+	struct nf_conntrack_tuple tuple;
+	const struct nf_conntrack_tuple *tuple_ptr = &tuple;
+	enum ip_conntrack_info ctinfo;
+	const struct nf_conn *ct;
+	int connections;
+
+	ct = nf_ct_get(skb, &ctinfo);
+	if (ct != NULL)
+		tuple_ptr = &ct->tuplehash[0].tuple;
+	else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
+				    match->family, &tuple))
+		goto hotdrop;
+
+	if (match->family == AF_INET6) {
+		const struct ipv6hdr *iph = ipv6_hdr(skb);
+		memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr));
+		memcpy(&mask.ip6, info->v6_mask, sizeof(info->v6_mask));
+	} else {
+		const struct iphdr *iph = ip_hdr(skb);
+		addr.ip = iph->saddr;
+		mask.ip = info->v4_mask;
+	}
+
+	spin_lock_bh(&info->data->lock);
+	connections = count_them(info->data, tuple_ptr, &addr, &mask, match);
+	spin_unlock_bh(&info->data->lock);
+
+	if (connections < 0) {
+		/* kmalloc failed, drop it entirely */
+		*hotdrop = true;
+		return false;
+	}
+
+	return (connections > info->limit) ^ info->inverse;
+
+ hotdrop:
+	*hotdrop = true;
+	return false;
+}
+
+static bool connlimit_check(const char *tablename, const void *ip,
+			    const struct xt_match *match, void *matchinfo,
+			    unsigned int hook_mask)
+{
+	struct xt_connlimit_info *info = matchinfo;
+	unsigned int i;
+
+	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+		printk(KERN_WARNING "cannot load conntrack support for "
+		       "address family %u\n", match->family);
+		return false;
+	}
+
+	/* init private data */
+	info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
+	if (info->data == NULL) {
+		nf_ct_l3proto_module_put(match->family);
+		return false;
+	}
+
+	spin_lock_init(&info->data->lock);
+	for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i)
+		INIT_LIST_HEAD(&info->data->iphash[i]);
+
+	return true;
+}
+
+static void connlimit_destroy(const struct xt_match *match, void *matchinfo)
+{
+	struct xt_connlimit_info *info = matchinfo;
+	struct xt_connlimit_conn *conn;
+	struct xt_connlimit_conn *tmp;
+	struct list_head *hash = info->data->iphash;
+	unsigned int i;
+
+	nf_ct_l3proto_module_put(match->family);
+
+	for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) {
+		list_for_each_entry_safe(conn, tmp, &hash[i], list) {
+			list_del(&conn->list);
+			kfree(conn);
+		}
+	}
+
+	kfree(info->data);
+}
+
+static struct xt_match connlimit_reg[] __read_mostly = {
+	{
+		.name       = "connlimit",
+		.family     = AF_INET,
+		.checkentry = connlimit_check,
+		.match      = connlimit_match,
+		.matchsize  = sizeof(struct xt_connlimit_info),
+		.destroy    = connlimit_destroy,
+		.me         = THIS_MODULE,
+	},
+	{
+		.name       = "connlimit",
+		.family     = AF_INET6,
+		.checkentry = connlimit_check,
+		.match      = connlimit_match,
+		.matchsize  = sizeof(struct xt_connlimit_info),
+		.destroy    = connlimit_destroy,
+		.me         = THIS_MODULE,
+	},
+};
+
+static int __init xt_connlimit_init(void)
+{
+	return xt_register_matches(connlimit_reg, ARRAY_SIZE(connlimit_reg));
+}
+
+static void __exit xt_connlimit_exit(void)
+{
+	xt_unregister_matches(connlimit_reg, ARRAY_SIZE(connlimit_reg));
+}
+
+module_init(xt_connlimit_init);
+module_exit(xt_connlimit_exit);
+MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
+MODULE_DESCRIPTION("netfilter xt_connlimit match module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_connlimit");
+MODULE_ALIAS("ip6t_connlimit");

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
                   ` (5 preceding siblings ...)
  2007-07-14 15:12 ` [NETFILTER 06/08]: x_tables: add connlimit match Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-15  3:48   ` David Miller
  2007-07-14 15:12 ` [NETFILTER 08/08]: nf_conntrack: UDPLITE support Patrick McHardy
  7 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: mark protocols __read_mostly

Also remove two unnecessary EXPORT_SYMBOLs and move the
nf_conntrack_l3proto_ipv4 declaration to the correct file.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 48b2bed5b1229eb77b3df402e70c9c7e8360212d
tree 12da18400ae69862c1c31ad6d84cf847a781b2c1
parent ce0ae6ad80f3673eaaa2fb1cab9771939c7e84c6
author Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:30 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:05:35 +0200

 include/net/netfilter/ipv4/nf_conntrack_ipv4.h |    2 ++
 include/net/netfilter/nf_conntrack_l3proto.h   |    2 --
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |    2 +-
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |    3 +--
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |    2 +-
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |    4 +---
 net/netfilter/nf_conntrack_l3proto_generic.c   |    2 +-
 net/netfilter/nf_conntrack_proto_generic.c     |    2 +-
 net/netfilter/nf_conntrack_proto_gre.c         |    2 +-
 net/netfilter/nf_conntrack_proto_sctp.c        |    4 ++--
 net/netfilter/nf_conntrack_proto_tcp.c         |    4 ++--
 net/netfilter/nf_conntrack_proto_udp.c         |    4 ++--
 12 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
index 3ed4e14..7a67160 100644
--- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -12,6 +12,8 @@
 /* Returns new sk_buff, or NULL */
 struct sk_buff *nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb);
 
+extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
+
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index e3708a6..3c58a2c 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -89,8 +89,6 @@ extern struct nf_conntrack_l3proto *nf_ct_l3proto_find_get(u_int16_t l3proto);
 extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
 
 /* Existing built-in protocols */
-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_generic;
 
 static inline struct nf_conntrack_l3proto *
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index ee29f4e..64552af 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -405,7 +405,7 @@ static struct nf_sockopt_ops so_getorigdst = {
 	.get		= &getorigdst,
 };
 
-struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
+struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
 	.l3proto	 = PF_INET,
 	.name		 = "ipv4",
 	.pkt_to_tuple	 = ipv4_pkt_to_tuple,
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index f965733..6593fd2 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -312,7 +312,7 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
 {
 	.l3proto		= PF_INET,
 	.l4proto		= IPPROTO_ICMP,
@@ -338,4 +338,3 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
 #endif
 #endif
 };
-EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_icmp);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 9b7eaaa..36df221 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -373,7 +373,7 @@ static int ipv6_nfattr_to_tuple(struct nfattr *tb[],
 }
 #endif
 
-struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
+struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
 	.l3proto		= PF_INET6,
 	.name			= "ipv6",
 	.pkt_to_tuple		= ipv6_pkt_to_tuple,
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 0fca7e8..ab154fb 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -276,7 +276,7 @@ static struct ctl_table icmpv6_sysctl_table[] = {
 };
 #endif /* CONFIG_SYSCTL */
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
 {
 	.l3proto		= PF_INET6,
 	.l4proto		= IPPROTO_ICMPV6,
@@ -297,5 +297,3 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
 	.ctl_table		= icmpv6_sysctl_table,
 #endif
 };
-
-EXPORT_SYMBOL(nf_conntrack_l4proto_icmpv6);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index 0691642..991c52c 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -69,7 +69,7 @@ static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
 }
 
 
-struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
+struct nf_conntrack_l3proto nf_conntrack_l3proto_generic __read_mostly = {
 	.l3proto	 = PF_UNSPEC,
 	.name		 = "unknown",
 	.pkt_to_tuple	 = generic_pkt_to_tuple,
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 6faf1be..d8b5018 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -98,7 +98,7 @@ static struct ctl_table generic_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
 {
 	.l3proto		= PF_UNSPEC,
 	.l4proto		= 0,
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 771c4c2..bdbead8 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -261,7 +261,7 @@ static void gre_destroy(struct nf_conn *ct)
 }
 
 /* protocol helper struct */
-static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
+static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
 	.l3proto	 = AF_INET,
 	.l4proto	 = IPPROTO_GRE,
 	.name		 = "gre",
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index debfe61..04192ac 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -601,7 +601,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
+static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
 	.l3proto		= PF_INET,
 	.l4proto 		= IPPROTO_SCTP,
 	.name 			= "sctp",
@@ -622,7 +622,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
 #endif
 };
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
+static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
 	.l3proto		= PF_INET6,
 	.l4proto 		= IPPROTO_SCTP,
 	.name 			= "sctp",
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 1c8206e..87ad3cc 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1372,7 +1372,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
 {
 	.l3proto		= PF_INET,
 	.l4proto 		= IPPROTO_TCP,
@@ -1401,7 +1401,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
 {
 	.l3proto		= PF_INET6,
 	.l4proto 		= IPPROTO_TCP,
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 3620ecc..13d94a0 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -191,7 +191,7 @@ static struct ctl_table udp_compat_sysctl_table[] = {
 #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
 #endif /* CONFIG_SYSCTL */
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
 {
 	.l3proto		= PF_INET,
 	.l4proto		= IPPROTO_UDP,
@@ -218,7 +218,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
 
-struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
+struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
 {
 	.l3proto		= PF_INET6,
 	.l4proto		= IPPROTO_UDP,

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [NETFILTER 08/08]: nf_conntrack: UDPLITE support
  2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
                   ` (6 preceding siblings ...)
  2007-07-14 15:12 ` [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly Patrick McHardy
@ 2007-07-14 15:12 ` Patrick McHardy
  2007-07-14 16:54   ` Yasuyuki KOZAKAI
                     ` (2 more replies)
  7 siblings, 3 replies; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 15:12 UTC (permalink / raw)
  To: davem; +Cc: netfilter-devel, Patrick McHardy

[NETFILTER]: nf_conntrack: UDPLITE support

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 15e277fed17d039cf1866e2232578d50dee24cba
tree 73162bbea0ce866a151ad12fab92c3de8dfc115a
parent 48b2bed5b1229eb77b3df402e70c9c7e8360212d
author Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:02:32 +0200
committer Patrick McHardy <kaber@trash.net> Sat, 14 Jul 2007 17:05:35 +0200

 net/netfilter/Kconfig                      |   10 +
 net/netfilter/Makefile                     |    1 
 net/netfilter/nf_conntrack_proto_udplite.c |  266 ++++++++++++++++++++++++++++
 3 files changed, 277 insertions(+), 0 deletions(-)

diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9415b9a..3ac39f1 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -102,6 +102,16 @@ config NF_CT_PROTO_SCTP
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NF_CT_PROTO_UDPLITE
+	tristate 'UDP-Lite protocol connection tracking support (EXPERIMENTAL)'
+	depends on EXPERIMENTAL && NF_CONNTRACK
+	help
+	  With this option enabled, the layer 3 independent connection
+	  tracking code will be able to do state tracking on UDP-Lite
+	  connections.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NF_CONNTRACK_AMANDA
 	tristate "Amanda backup protocol support"
 	depends on NF_CONNTRACK
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 3e4a16a..0c054bf 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
 # SCTP protocol connection tracking
 obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
 obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
+obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
 
 # netlink interface for nf_conntrack
 obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
new file mode 100644
index 0000000..93e747b
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -0,0 +1,266 @@
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ * (C) 2007 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/netfilter.h>
+#include <linux/udp.h>
+#include <linux/seq_file.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
+
+static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ;
+static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ;
+
+static int udplite_pkt_to_tuple(const struct sk_buff *skb,
+				unsigned int dataoff,
+				struct nf_conntrack_tuple *tuple)
+{
+	struct udphdr _hdr, *hp;
+
+	hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+	if (hp == NULL)
+		return 0;
+
+	tuple->src.u.udp.port = hp->source;
+	tuple->dst.u.udp.port = hp->dest;
+	return 1;
+}
+
+static int udplite_invert_tuple(struct nf_conntrack_tuple *tuple,
+				const struct nf_conntrack_tuple *orig)
+{
+	tuple->src.u.udp.port = orig->dst.u.udp.port;
+	tuple->dst.u.udp.port = orig->src.u.udp.port;
+	return 1;
+}
+
+/* Print out the per-protocol part of the tuple. */
+static int udplite_print_tuple(struct seq_file *s,
+			       const struct nf_conntrack_tuple *tuple)
+{
+	return seq_printf(s, "sport=%hu dport=%hu ",
+			  ntohs(tuple->src.u.udp.port),
+			  ntohs(tuple->dst.u.udp.port));
+}
+
+/* Print out the private part of the conntrack. */
+static int udplite_print_conntrack(struct seq_file *s,
+				   const struct nf_conn *conntrack)
+{
+	return 0;
+}
+
+/* Returns verdict for packet, and may modify conntracktype */
+static int udplite_packet(struct nf_conn *conntrack,
+			  const struct sk_buff *skb,
+			  unsigned int dataoff,
+			  enum ip_conntrack_info ctinfo,
+			  int pf,
+			  unsigned int hooknum)
+{
+	/* If we've seen traffic both ways, this is some kind of UDP
+	   stream.  Extend timeout. */
+	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+		nf_ct_refresh_acct(conntrack, ctinfo, skb,
+				   nf_ct_udplite_timeout_stream);
+		/* Also, more likely to be important, and not a probe */
+		if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+			nf_conntrack_event_cache(IPCT_STATUS, skb);
+	} else
+		nf_ct_refresh_acct(conntrack, ctinfo, skb,
+				   nf_ct_udplite_timeout);
+
+	return NF_ACCEPT;
+}
+
+/* Called when a new connection for this protocol found. */
+static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+		       unsigned int dataoff)
+{
+	return 1;
+}
+
+static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
+			 enum ip_conntrack_info *ctinfo,
+			 int pf,
+			 unsigned int hooknum)
+{
+	unsigned int udplen = skb->len - dataoff;
+	struct udphdr _hdr, *hdr;
+	unsigned int cscov;
+
+	/* Header is too small? */
+	hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
+	if (hdr == NULL) {
+		if (LOG_INVALID(IPPROTO_UDPLITE))
+			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+				      "nf_ct_udplite: short packet ");
+		return -NF_ACCEPT;
+	}
+
+	cscov = ntohs(hdr->len);
+	if (cscov == 0)
+		cscov = udplen;
+	else if (cscov < sizeof(*hdr) || cscov > udplen) {
+		if (LOG_INVALID(IPPROTO_UDPLITE))
+			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+				"nf_ct_udplite: invalid checksum coverage ");
+		return -NF_ACCEPT;
+	}
+
+	/* UDPLITE mandates checksums */
+	if (!hdr->check) {
+		if (LOG_INVALID(IPPROTO_UDPLITE))
+			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+				      "nf_ct_udplite: checksum missing ");
+		return -NF_ACCEPT;
+	}
+
+	/* Checksum invalid? Ignore. */
+	if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) &&
+	    ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
+	     (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))) {
+		if (pf == PF_INET) {
+			struct iphdr *iph = ip_hdr(skb);
+
+			skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
+						       udplen, IPPROTO_UDPLITE, 0);
+		} else {
+			struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+			__wsum hsum = skb_checksum(skb, 0, dataoff, 0);
+
+			skb->csum = ~csum_unfold(
+				csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
+						udplen, IPPROTO_UDPLITE,
+						csum_sub(0, hsum)));
+		}
+
+		skb->ip_summed = CHECKSUM_NONE;
+		if (__skb_checksum_complete_head(skb, dataoff + cscov)) {
+			if (LOG_INVALID(IPPROTO_UDPLITE))
+				nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+					      "nf_ct_udplite: bad UDPLite "
+					      "checksum ");
+			return -NF_ACCEPT;
+		}
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+
+	return NF_ACCEPT;
+}
+
+#ifdef CONFIG_SYSCTL
+static unsigned int udplite_sysctl_table_users;
+static struct ctl_table_header *udplite_sysctl_header;
+static struct ctl_table udplite_sysctl_table[] = {
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nf_conntrack_udplite_timeout",
+		.data		= &nf_ct_udplite_timeout,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "nf_conntrack_udplite_timeout_stream",
+		.data		= &nf_ct_udplite_timeout_stream,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+	},
+	{
+		.ctl_name	= 0
+	}
+};
+#endif /* CONFIG_SYSCTL */
+
+static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
+{
+	.l3proto		= PF_INET,
+	.l4proto		= IPPROTO_UDPLITE,
+	.name			= "udplite",
+	.pkt_to_tuple		= udplite_pkt_to_tuple,
+	.invert_tuple		= udplite_invert_tuple,
+	.print_tuple		= udplite_print_tuple,
+	.print_conntrack	= udplite_print_conntrack,
+	.packet			= udplite_packet,
+	.new			= udplite_new,
+	.error			= udplite_error,
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
+#ifdef CONFIG_SYSCTL
+	.ctl_table_users	= &udplite_sysctl_table_users,
+	.ctl_table_header	= &udplite_sysctl_header,
+	.ctl_table		= udplite_sysctl_table,
+#endif
+};
+
+static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
+{
+	.l3proto		= PF_INET6,
+	.l4proto		= IPPROTO_UDPLITE,
+	.name			= "udplite",
+	.pkt_to_tuple		= udplite_pkt_to_tuple,
+	.invert_tuple		= udplite_invert_tuple,
+	.print_tuple		= udplite_print_tuple,
+	.print_conntrack	= udplite_print_conntrack,
+	.packet			= udplite_packet,
+	.new			= udplite_new,
+	.error			= udplite_error,
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
+#ifdef CONFIG_SYSCTL
+	.ctl_table_users	= &udplite_sysctl_table_users,
+	.ctl_table_header	= &udplite_sysctl_header,
+	.ctl_table		= udplite_sysctl_table,
+#endif
+};
+
+static int __init nf_conntrack_proto_udplite_init(void)
+{
+	int err;
+
+	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
+	if (err < 0)
+		goto err1;
+	err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
+	if (err < 0)
+		goto err2;
+	return 0;
+err2:
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+err1:
+	return err;
+}
+
+static void __exit nf_conntrack_proto_udplite_exit(void)
+{
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
+	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+}
+
+module_init(nf_conntrack_proto_udplite_init);
+module_exit(nf_conntrack_proto_udplite_exit);
+
+MODULE_LICENSE("GPL");

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 08/08]: nf_conntrack: UDPLITE support
  2007-07-14 15:12 ` [NETFILTER 08/08]: nf_conntrack: UDPLITE support Patrick McHardy
@ 2007-07-14 16:54   ` Yasuyuki KOZAKAI
       [not found]   ` <200707141654.l6EGs6XG008905@toshiba.co.jp>
  2007-07-15  3:48   ` David Miller
  2 siblings, 0 replies; 19+ messages in thread
From: Yasuyuki KOZAKAI @ 2007-07-14 16:54 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel, davem

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:44 +0200 (MEST)

> [NETFILTER]: nf_conntrack: UDPLITE support

Maybe you predict this question :) Why do you think that new module is
needed instead of reusing codes in nf_conntrack_proto_udp.c ?

-- Yasuyuki Kozakai

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 08/08]: nf_conntrack: UDPLITE support
       [not found]   ` <200707141654.l6EGs6XG008905@toshiba.co.jp>
@ 2007-07-14 23:05     ` Patrick McHardy
  2007-07-16  8:07       ` Yasuyuki KOZAKAI
  0 siblings, 1 reply; 19+ messages in thread
From: Patrick McHardy @ 2007-07-14 23:05 UTC (permalink / raw)
  To: Yasuyuki KOZAKAI; +Cc: netfilter-devel, davem

Yasuyuki KOZAKAI wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Sat, 14 Jul 2007 17:12:44 +0200 (MEST)
> 
> 
>>[NETFILTER]: nf_conntrack: UDPLITE support
> 
> 
> Maybe you predict this question :) Why do you think that new module is
> needed instead of reusing codes in nf_conntrack_proto_udp.c ?


I did :) Reusing code for the conntrack helper didn't seem to buy
much, the only two functions that actually do anything besides
copying header values are too different to merge (checksumming/
packet handling). It also needs seperate sysctls, which is
responsible for another 20%-30% of the code. So it comes down to
saving two or three completely trivial functions, which is IMO
not even worth exporting them.

For the NAT helpers it makes a lot more sense. The port selection
logic, the in_range check, the manip_pkt function for UDP/TCP
and the nf_conntrack_netlink functions could all be generalized
and moved to a common helper helper :) This is the main reason
why I didn't include a NAT helper yet, I have some unfinished
work to do all that.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header
  2007-07-14 15:12 ` [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header Patrick McHardy
@ 2007-07-15  3:44   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:44 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:35 +0200 (MEST)

> [NETFILTER]: nf_conntrack: Increment error count on parsing IPv4 header
> 
> Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it
  2007-07-14 15:12 ` [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it Patrick McHardy
@ 2007-07-15  3:45   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:45 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:36 +0200 (MEST)

> [NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it
> 
> The icmp[v6] l4proto modules parse headers in ICMP[v6] error to get tuple.
> But they have to find the offset to transport protocol header before that.
> Their processings are almost same as prepare() of l3proto modules.
> This makes prepare() more generic to simplify icmp[v6] l4proto module
> later.
> 
> Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error
  2007-07-14 15:12 ` [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error Patrick McHardy
@ 2007-07-15  3:45   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:45 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:39 +0200 (MEST)

> [NETFILTER]: nf_conntrack: Don't track locally generated special ICMP error
> 
> The conntrack assigned to locally generated ICMP error is usually the one
> assigned to the original packet which has caused the error. But if
> the original packet is handled as invalid by nf_conntrack, no conntrack
> is assigned to the original packet. Then nf_ct_attach() cannot assign
> any conntrack to the ICMP error packet. In that case the current
> nf_conntrack_icmp assigns appropriate conntrack to it. But the current
> code mistakes the direction of the packet. As a result, NAT code mistakes
> the address to be mangled.
> 
> To fix the bug, this changes nf_conntrack_icmp not to assign conntrack
> to such ICMP error. Actually no address is necessary to be mangled
> in this case.
> 
> Spotted by Jordan Russell.
> 
> Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 05/08]: Lower *tables printk severity
  2007-07-14 15:12 ` [NETFILTER 05/08]: Lower *tables printk severity Patrick McHardy
@ 2007-07-15  3:46   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:46 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:40 +0200 (MEST)

> [NETFILTER]: Lower *tables printk severity
> 
> Lower ip6tables, arptables and ebtables printk severity similar to
> Dan Aloni's patch for iptables.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

There are probably other missing KERN_* cases scattered
around the rest of netfilter.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 06/08]: x_tables: add connlimit match
  2007-07-14 15:12 ` [NETFILTER 06/08]: x_tables: add connlimit match Patrick McHardy
@ 2007-07-15  3:47   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:47 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:42 +0200 (MEST)

> [NETFILTER]: x_tables: add connlimit match
> 
> ipt_connlimit has been sitting in POM-NG for a long time.
> Here is a new shiny xt_connlimit with:
> 
>  * xtables'ified
>  * will request the layer3 module
>    (previously it hotdropped every packet when it was not loaded)
>  * fixed: there was a deadlock in case of an OOM condition
>  * support for any layer4 protocol (e.g. UDP/SCTP)
>  * using jhash, as suggested by Eric Dumazet
>  * ipv6 support
> 
> Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied, nice work guys.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly
  2007-07-14 15:12 ` [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly Patrick McHardy
@ 2007-07-15  3:48   ` David Miller
  0 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:48 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:43 +0200 (MEST)

> [NETFILTER]: nf_conntrack: mark protocols __read_mostly
> 
> Also remove two unnecessary EXPORT_SYMBOLs and move the
> nf_conntrack_l3proto_ipv4 declaration to the correct file.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 08/08]: nf_conntrack: UDPLITE support
  2007-07-14 15:12 ` [NETFILTER 08/08]: nf_conntrack: UDPLITE support Patrick McHardy
  2007-07-14 16:54   ` Yasuyuki KOZAKAI
       [not found]   ` <200707141654.l6EGs6XG008905@toshiba.co.jp>
@ 2007-07-15  3:48   ` David Miller
  2 siblings, 0 replies; 19+ messages in thread
From: David Miller @ 2007-07-15  3:48 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel

From: Patrick McHardy <kaber@trash.net>
Date: Sat, 14 Jul 2007 17:12:44 +0200 (MEST)

> [NETFILTER]: nf_conntrack: UDPLITE support
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [NETFILTER 08/08]: nf_conntrack: UDPLITE support
  2007-07-14 23:05     ` Patrick McHardy
@ 2007-07-16  8:07       ` Yasuyuki KOZAKAI
  0 siblings, 0 replies; 19+ messages in thread
From: Yasuyuki KOZAKAI @ 2007-07-16  8:07 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel, davem, yasuyuki.kozakai

From: Patrick McHardy <kaber@trash.net>

> >>[NETFILTER]: nf_conntrack: UDPLITE support
> > 
> > 
> > Maybe you predict this question :) Why do you think that new module is
> > needed instead of reusing codes in nf_conntrack_proto_udp.c ?
> 
> 
> I did :) Reusing code for the conntrack helper didn't seem to buy
> much, the only two functions that actually do anything besides
> copying header values are too different to merge (checksumming/
> packet handling). It also needs seperate sysctls, which is
> responsible for another 20%-30% of the code. So it comes down to
> saving two or three completely trivial functions, which is IMO
> not even worth exporting them.
> 
> For the NAT helpers it makes a lot more sense. The port selection
> logic, the in_range check, the manip_pkt function for UDP/TCP
> and the nf_conntrack_netlink functions could all be generalized
> and moved to a common helper helper :) This is the main reason
> why I didn't include a NAT helper yet, I have some unfinished
> work to do all that.

That is nice idea. Thanks for explanation.

-- Yasuyuki Kozakai

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2007-07-16  8:07 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-14 15:12 [NETFILTER 00/08]: Netfilter Update part II Patrick McHardy
2007-07-14 15:12 ` [NETFILTER 01/08]: nf_conntrack: Increment error count on parsing IPv4 header Patrick McHardy
2007-07-15  3:44   ` David Miller
2007-07-14 15:12 ` [NETFILTER 02/08]: nf_conntrack: make l3proto->prepare() generic and renames it Patrick McHardy
2007-07-15  3:45   ` David Miller
2007-07-14 15:12 ` [NETFILTER 03/08]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it Patrick McHardy
2007-07-14 15:12 ` [NETFILTER 04/08]: nf_conntrack: Don't track locally generated special ICMP error Patrick McHardy
2007-07-15  3:45   ` David Miller
2007-07-14 15:12 ` [NETFILTER 05/08]: Lower *tables printk severity Patrick McHardy
2007-07-15  3:46   ` David Miller
2007-07-14 15:12 ` [NETFILTER 06/08]: x_tables: add connlimit match Patrick McHardy
2007-07-15  3:47   ` David Miller
2007-07-14 15:12 ` [NETFILTER 07/08]: nf_conntrack: mark protocols __read_mostly Patrick McHardy
2007-07-15  3:48   ` David Miller
2007-07-14 15:12 ` [NETFILTER 08/08]: nf_conntrack: UDPLITE support Patrick McHardy
2007-07-14 16:54   ` Yasuyuki KOZAKAI
     [not found]   ` <200707141654.l6EGs6XG008905@toshiba.co.jp>
2007-07-14 23:05     ` Patrick McHardy
2007-07-16  8:07       ` Yasuyuki KOZAKAI
2007-07-15  3:48   ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.