netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput
@ 2007-11-07 14:07 Herbert Xu
  2007-11-07 14:08 ` [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst Herbert Xu
                   ` (23 more replies)
  0 siblings, 24 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:07 UTC (permalink / raw)
  To: David S. Miller, netdev

Hi Dave:

Here's a dump of what I've currently got in my IPsec tree.
It contains all the patches I've posted previously which are
yet to be merged.

The first 11 patches are unchanged from the previous posting.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:32   ` David Miller
  2007-11-07 14:08 ` [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output Herbert Xu
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPV6]: Only set nfheader_len for top xfrm dst

We only need to set nfheader_len in the top xfrm dst.  This is because
we only ever read the nfheader_len from the top xfrm dst.

It is also easier to count nfheader_len as part of header_len which
then lets us remove the ugly wrapper functions for incrementing and
decrementing header lengths in xfrm6_policy.c.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv6/ip6_output.c   |    3 ++-
 net/ipv6/xfrm6_policy.c |   26 ++++----------------------
 2 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 653fc0a..6289dfc 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1096,7 +1096,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 		inet->cork.length = 0;
 		sk->sk_sndmsg_page = NULL;
 		sk->sk_sndmsg_off = 0;
-		exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0);
+		exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0) -
+			    rt->u.dst.nfheader_len;
 		length += exthdrlen;
 		transhdrlen += exthdrlen;
 	} else {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 82e27b8..e5170bc 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -102,24 +102,6 @@ __xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
 		(struct in6_addr*)&x->props.saddr;
 }
 
-static inline void
-__xfrm6_bundle_len_inc(int *len, int *nflen, struct xfrm_state *x)
-{
-	if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
-		*nflen += x->props.header_len;
-	else
-		*len += x->props.header_len;
-}
-
-static inline void
-__xfrm6_bundle_len_dec(int *len, int *nflen, struct xfrm_state *x)
-{
-	if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
-		*nflen -= x->props.header_len;
-	else
-		*len -= x->props.header_len;
-}
-
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
  * all the metrics... Shortly, bundle a bundle.
  */
@@ -142,7 +124,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 	int i;
 	int err = 0;
 	int header_len = 0;
-	int nfheader_len = 0;
 	int trailer_len = 0;
 
 	dst = dst_prev = NULL;
@@ -175,7 +156,9 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst1->next = dst_prev;
 		dst_prev = dst1;
 
-		__xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
+		if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
+			dst->nfheader_len += xfrm[i]->props.header_len;
+		header_len += xfrm[i]->props.header_len;
 		trailer_len += xfrm[i]->props.trailer_len;
 
 		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
@@ -223,7 +206,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->flags	       |= DST_HOST;
 		dst_prev->lastuse	= jiffies;
 		dst_prev->header_len	= header_len;
-		dst_prev->nfheader_len	= nfheader_len;
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
@@ -242,7 +224,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		x->u.rt6.rt6i_src      = rt0->rt6i_src;
 		x->u.rt6.rt6i_idev     = rt0->rt6i_idev;
 		in6_dev_hold(rt0->rt6i_idev);
-		__xfrm6_bundle_len_dec(&header_len, &nfheader_len, x->u.dst.xfrm);
+		header_len -= x->u.dst.xfrm->props.header_len;
 		trailer_len -= x->u.dst.xfrm->props.trailer_len;
 	}
 

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

* [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
  2007-11-07 14:08 ` [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:33   ` David Miller
  2007-11-07 14:08 ` [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info Herbert Xu
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Use dst->header_len when resizing on output

Currently we use x->props.header_len when resizing on output.  However,
if we're resizing at all we might as well go the whole hog and do it
for the whole dst.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/xfrm/xfrm_output.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index f4bfd6c..58d5a74 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -19,7 +19,8 @@
 
 static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
-	int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev)
+	struct dst_entry *dst = skb->dst;
+	int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
 		- skb_headroom(skb);
 
 	if (nhead > 0)

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

* [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
  2007-11-07 14:08 ` [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst Herbert Xu
  2007-11-07 14:08 ` [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:33   ` David Miller
  2007-11-07 14:08 ` [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard Herbert Xu
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPV6]: Move nfheader_len into rt6_info

The dst member nfheader_len is only used by IPv6.  It's also currently
creating a rather ugly alignment hole in struct dst.  Therefore this patch
moves it from there into struct rt6_info.

It also reorders the fields in rt6_info to minimize holes.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/dst.h       |    1 -
 include/net/ip6_fib.h   |   11 ++++++++---
 net/ipv4/xfrm4_policy.c |    1 -
 net/ipv6/ip6_output.c   |    5 +++--
 net/ipv6/xfrm6_policy.c |    3 ++-
 5 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index e9ff4a4..8f88c52 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -50,7 +50,6 @@ struct dst_entry
 	unsigned long		expires;
 
 	unsigned short		header_len;	/* more space at head required */
-	unsigned short		nfheader_len;	/* more non-fragment space at head required */
 	unsigned short		trailer_len;	/* space to reserve at tail */
 
 	u32			metrics[RTAX_MAX];
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 8578213..4cefcff 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -99,16 +99,21 @@ struct rt6_info
 	u32				rt6i_flags;
 	u32				rt6i_metric;
 	atomic_t			rt6i_ref;
-	struct fib6_table		*rt6i_table;
 
-	struct rt6key			rt6i_dst;
-	struct rt6key			rt6i_src;
+	/* more non-fragment space at head required */
+	unsigned short			nfheader_len;
 
 	u8				rt6i_protocol;
 
+	struct fib6_table		*rt6i_table;
+
+	struct rt6key			rt6i_dst;
+
 #ifdef CONFIG_XFRM
 	u32				rt6i_flow_cache_genid;
 #endif
+
+	struct rt6key			rt6i_src;
 };
 
 static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index cc86fb1..5ee3a2f 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -161,7 +161,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->flags	       |= DST_HOST;
 		dst_prev->lastuse	= jiffies;
 		dst_prev->header_len	= header_len;
-		dst_prev->nfheader_len	= 0;
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6289dfc..698d9d2 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1097,7 +1097,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 		sk->sk_sndmsg_page = NULL;
 		sk->sk_sndmsg_off = 0;
 		exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0) -
-			    rt->u.dst.nfheader_len;
+			    rt->nfheader_len;
 		length += exthdrlen;
 		transhdrlen += exthdrlen;
 	} else {
@@ -1112,7 +1112,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 
 	hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 
-	fragheaderlen = sizeof(struct ipv6hdr) + rt->u.dst.nfheader_len + (opt ? opt->opt_nflen : 0);
+	fragheaderlen = sizeof(struct ipv6hdr) + rt->nfheader_len +
+			(opt ? opt->opt_nflen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
 
 	if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index e5170bc..9095dfc 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -157,7 +157,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev = dst1;
 
 		if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
-			dst->nfheader_len += xfrm[i]->props.header_len;
+			((struct rt6_info *)dst)->nfheader_len +=
+				xfrm[i]->props.header_len;
 		header_len += xfrm[i]->props.header_len;
 		trailer_len += xfrm[i]->props.trailer_len;
 

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

* [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (2 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:34   ` David Miller
  2007-11-07 14:08 ` [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h Herbert Xu
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[NET]: Eliminate duplicate copies of dst_discard

We have a number of copies of dst_discard scattered around the place which
all do the same thing, namely free a packet on the input or output paths.

This patch deletes all of them except dst_discard and points all the users
to it.

The only non-trivial bit is decnet where it returns an error.  However,
conceptually this is identical to the blackhole functions used in IPv4
and IPv6 which do not return errors.  So they should either all return
errors or all return zero.  For now I've stuck with the majority and
picked zero as the return value.

It doesn't really matter in practice since few if any driver would react
differently depending on a zero return value or NET_RX_DROP.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/dst.h     |    1 +
 net/core/dst.c        |    3 ++-
 net/decnet/dn_route.c |   13 +------------
 net/ipv4/route.c      |   11 +++--------
 net/ipv6/exthdrs.c    |   13 ++-----------
 net/ipv6/route.c      |   21 ++++-----------------
 6 files changed, 13 insertions(+), 49 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 8f88c52..4df103b 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -172,6 +172,7 @@ static inline struct dst_entry *dst_pop(struct dst_entry *dst)
 	return child;
 }
 
+extern int dst_discard(struct sk_buff *skb);
 extern void * dst_alloc(struct dst_ops * ops);
 extern void __dst_free(struct dst_entry * dst);
 extern struct dst_entry *dst_destroy(struct dst_entry * dst);
diff --git a/net/core/dst.c b/net/core/dst.c
index 16958e6..21b1d0f 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -154,11 +154,12 @@ loop:
 #endif
 }
 
-static int dst_discard(struct sk_buff *skb)
+int dst_discard(struct sk_buff *skb)
 {
 	kfree_skb(skb);
 	return 0;
 }
+EXPORT_SYMBOL(dst_discard);
 
 void * dst_alloc(struct dst_ops * ops)
 {
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 97eee5e..e1f6669 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -769,17 +769,6 @@ drop:
 }
 
 /*
- * Drop packet. This is used for endnodes and for
- * when we should not be forwarding packets from
- * this dest.
- */
-static int dn_blackhole(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return NET_RX_DROP;
-}
-
-/*
  * Used to catch bugs. This should never normally get
  * called.
  */
@@ -1402,7 +1391,7 @@ make_route:
 		default:
 		case RTN_UNREACHABLE:
 		case RTN_BLACKHOLE:
-			rt->u.dst.input = dn_blackhole;
+			rt->u.dst.input = dst_discard;
 	}
 	rt->rt_flags = flags;
 	if (rt->u.dst.dev)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 21b12de..d5cbcee 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -92,6 +92,7 @@
 #include <linux/jhash.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
+#include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
@@ -2362,12 +2363,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
 };
 
 
-static int ipv4_blackhole_output(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return 0;
-}
-
 static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk)
 {
 	struct rtable *ort = *rp;
@@ -2379,8 +2374,8 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock
 
 		atomic_set(&new->__refcnt, 1);
 		new->__use = 1;
-		new->input = ipv4_blackhole_output;
-		new->output = ipv4_blackhole_output;
+		new->input = dst_discard;
+		new->output = dst_discard;
 		memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
 
 		new->dev = ort->u.dst.dev;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 1e89efd..cee06b1 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -32,6 +32,7 @@
 #include <linux/in6.h>
 #include <linux/icmpv6.h>
 
+#include <net/dst.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 
@@ -318,18 +319,8 @@ void __init ipv6_destopt_init(void)
 		printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
 }
 
-/********************************
-  NONE header. No data in packet.
- ********************************/
-
-static int ipv6_nodata_rcv(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return 0;
-}
-
 static struct inet6_protocol nodata_protocol = {
-	.handler	=	ipv6_nodata_rcv,
+	.handler	=	dst_discard,
 	.flags		=	INET6_PROTO_NOPOLICY,
 };
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 95f8e4a..7db3cdf 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -156,7 +156,6 @@ struct rt6_info ip6_null_entry = {
 
 static int ip6_pkt_prohibit(struct sk_buff *skb);
 static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-static int ip6_pkt_blk_hole(struct sk_buff *skb);
 
 struct rt6_info ip6_prohibit_entry = {
 	.u = {
@@ -185,8 +184,8 @@ struct rt6_info ip6_blk_hole_entry = {
 			.obsolete	= -1,
 			.error		= -EINVAL,
 			.metrics	= { [RTAX_HOPLIMIT - 1] = 255, },
-			.input		= ip6_pkt_blk_hole,
-			.output		= ip6_pkt_blk_hole,
+			.input		= dst_discard,
+			.output		= dst_discard,
 			.ops		= &ip6_dst_ops,
 			.path		= (struct dst_entry*)&ip6_blk_hole_entry,
 		}
@@ -785,12 +784,6 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
 
 EXPORT_SYMBOL(ip6_route_output);
 
-static int ip6_blackhole_output(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return 0;
-}
-
 int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl)
 {
 	struct rt6_info *ort = (struct rt6_info *) *dstp;
@@ -803,8 +796,8 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
 
 		atomic_set(&new->__refcnt, 1);
 		new->__use = 1;
-		new->input = ip6_blackhole_output;
-		new->output = ip6_blackhole_output;
+		new->input = dst_discard;
+		new->output = dst_discard;
 
 		memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
 		new->dev = ort->u.dst.dev;
@@ -1814,12 +1807,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
 	return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 }
 
-static int ip6_pkt_blk_hole(struct sk_buff *skb)
-{
-	kfree_skb(skb);
-	return 0;
-}
-
 #endif
 
 /*

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

* [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (3 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:34   ` David Miller
  2007-11-07 14:08 ` [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst Herbert Xu
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[NET]: Remove unnecessary inclusion of dst.h

The file net/netevent.h only refers to struct dst_entry * so it doesn't
need to include dst.h.  I've replaced it with a forward declaration.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/netevent.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/net/netevent.h b/include/net/netevent.h
index e5d2162..e82b7ba 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -12,7 +12,7 @@
  */
 #ifdef __KERNEL__
 
-#include <net/dst.h>
+struct dst_entry;
 
 struct netevent_redirect {
 	struct dst_entry *old;

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

* [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (4 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:35   ` David Miller
  2007-11-07 14:08 ` [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard Herbert Xu
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Only set neighbour on top xfrm dst

The neighbour field is only used by dst_confirm which only ever happens on
the top-most xfrm dst.  So it's a waste to duplicate for every other xfrm
dst.  This patch moves its setting out of the loop so that only the top one
gets set.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/xfrm4_policy.c |    5 +++--
 net/ipv6/xfrm6_policy.c |    6 ++++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 5ee3a2f..7d250a1 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -144,6 +144,9 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 	dst_prev->child = &rt->u.dst;
 	dst->path = &rt->u.dst;
 
+	/* Copy neighbout for reachability confirmation */
+	dst->neighbour = neigh_clone(rt->u.dst.neighbour);
+
 	*dst_p = dst;
 	dst = dst_prev;
 
@@ -164,8 +167,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
-		/* Copy neighbout for reachability confirmation */
-		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
 		dst_prev->input		= rt->u.dst.input;
 		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
 		if (rt0->peer)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 9095dfc..15747f3 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -188,6 +188,10 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
 	dst_prev->child = &rt->u.dst;
 	dst->path = &rt->u.dst;
+
+	/* Copy neighbour for reachability confirmation */
+	dst->neighbour = neigh_clone(rt->u.dst.neighbour);
+
 	if (rt->rt6i_node)
 		((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum;
 
@@ -210,8 +214,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
-		/* Copy neighbour for reachability confirmation */
-		dst_prev->neighbour	= neigh_clone(rt->u.dst.neighbour);
 		dst_prev->input		= rt->u.dst.input;
 		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
 		/* Sheit... I remember I did this right. Apparently,

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

* [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (5 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:35   ` David Miller
  2007-11-07 14:08 ` [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst Herbert Xu
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Set dst->input to dst_discard

The input function should never be invoked on IPsec dst objects.  This is
because we don't apply IPsec on input until after we've made the routing
decision.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/xfrm4_policy.c |    3 ++-
 net/ipv6/xfrm6_policy.c |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7d250a1..c40a71b 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -10,6 +10,7 @@
 
 #include <linux/compiler.h>
 #include <linux/inetdevice.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 
@@ -167,7 +168,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
-		dst_prev->input		= rt->u.dst.input;
+		dst_prev->input = dst_discard;
 		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
 		if (rt0->peer)
 			atomic_inc(&rt0->peer->refcnt);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 15747f3..a1c6b7c 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -14,6 +14,7 @@
 #include <linux/compiler.h>
 #include <linux/netdevice.h>
 #include <net/addrconf.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -214,7 +215,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		dst_prev->trailer_len	= trailer_len;
 		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
 
-		dst_prev->input		= rt->u.dst.input;
+		dst_prev->input = dst_discard;
 		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
 		/* Sheit... I remember I did this right. Apparently,
 		 * it was magically lost, so this code needs audit */

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

* [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (6 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:36   ` David Miller
  2007-11-07 14:08 ` [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags Herbert Xu
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Make sure idev is consistent with dev in xfrm_dst

Previously we took the device from the bottom route and idev from the top
route.  This is bad because idev may well point to a different device.
This patch changes it so that we get the idev from the device directly.

It also makes it an error if either dev or idev is NULL.  This is consistent
with the rest of the routing code which also treats these cases as errors.

I've removed the err initialisation in xfrm6_policy.c because it achieves
no purpose and hid a bug when an initial version of this patch neglected
to set err to -ENODEV (fortunately the IPv4 version warned about it).

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/xfrm4_policy.c |   13 +++++++++----
 net/ipv6/xfrm6_policy.c |   15 ++++++++++-----
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index c40a71b..d903c8b 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -153,14 +153,21 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
 	dst_prev = *dst_p;
 	i = 0;
+	err = -ENODEV;
 	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
 		x->u.rt.fl = *fl;
 
 		dst_prev->xfrm = xfrm[i++];
 		dst_prev->dev = rt->u.dst.dev;
-		if (rt->u.dst.dev)
-			dev_hold(rt->u.dst.dev);
+		if (!rt->u.dst.dev)
+			goto error;
+		dev_hold(rt->u.dst.dev);
+
+		x->u.rt.idev = in_dev_get(rt->u.dst.dev);
+		if (!x->u.rt.idev)
+			goto error;
+
 		dst_prev->obsolete	= -1;
 		dst_prev->flags	       |= DST_HOST;
 		dst_prev->lastuse	= jiffies;
@@ -181,8 +188,6 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		x->u.rt.rt_dst = rt0->rt_dst;
 		x->u.rt.rt_gateway = rt0->rt_gateway;
 		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
-		x->u.rt.idev = rt0->idev;
-		in_dev_hold(rt0->idev);
 		header_len -= x->u.dst.xfrm->props.header_len;
 		trailer_len -= x->u.dst.xfrm->props.trailer_len;
 	}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index a1c6b7c..f04e718 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -123,7 +123,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		}
 	};
 	int i;
-	int err = 0;
+	int err;
 	int header_len = 0;
 	int trailer_len = 0;
 
@@ -201,13 +201,20 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 
 	dst_prev = *dst_p;
 	i = 0;
+	err = -ENODEV;
 	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
 
 		dst_prev->xfrm = xfrm[i++];
 		dst_prev->dev = rt->u.dst.dev;
-		if (rt->u.dst.dev)
-			dev_hold(rt->u.dst.dev);
+		if (!rt->u.dst.dev)
+			goto error;
+		dev_hold(rt->u.dst.dev);
+
+		x->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+		if (!x->u.rt6.rt6i_idev)
+			goto error;
+
 		dst_prev->obsolete	= -1;
 		dst_prev->flags	       |= DST_HOST;
 		dst_prev->lastuse	= jiffies;
@@ -226,8 +233,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
 		x->u.rt6.rt6i_dst      = rt0->rt6i_dst;
 		x->u.rt6.rt6i_src      = rt0->rt6i_src;
-		x->u.rt6.rt6i_idev     = rt0->rt6i_idev;
-		in6_dev_hold(rt0->rt6i_idev);
 		header_len -= x->u.dst.xfrm->props.header_len;
 		trailer_len -= x->u.dst.xfrm->props.trailer_len;
 	}

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

* [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (7 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:37   ` David Miller
  2007-11-07 14:08 ` [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup Herbert Xu
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Replace x->type->{local,remote}_addr with flags

The functions local_addr and remote_addr are more than what they're needed
for.  The same thing can be done easily with flags on the type object.
This patch does that and simplifies the wrapper functions in xfrm6_policy
accordingly.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h      |    4 ++--
 net/ipv6/mip6.c         |   11 ++---------
 net/ipv6/xfrm6_policy.c |   20 ++++++++------------
 3 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 58dfa82..f96bae2 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -282,6 +282,8 @@ struct xfrm_type
 	__u8			flags;
 #define XFRM_TYPE_NON_FRAGMENT	1
 #define XFRM_TYPE_REPLAY_PROT	2
+#define XFRM_TYPE_LOCAL_COADDR	4
+#define XFRM_TYPE_REMOTE_COADDR	8
 
 	int			(*init_state)(struct xfrm_state *x);
 	void			(*destructor)(struct xfrm_state *);
@@ -289,8 +291,6 @@ struct xfrm_type
 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
 	int			(*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
 	int			(*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
-	xfrm_address_t		*(*local_addr)(struct xfrm_state *, xfrm_address_t *);
-	xfrm_address_t		*(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
 	/* Estimate maximal size of result of transformation of a dgram */
 	u32			(*get_mtu)(struct xfrm_state *, int size);
 };
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 7fd841d..edfd9cd 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -34,11 +34,6 @@
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
-static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
-{
-	return x->coaddr;
-}
-
 static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
 {
 	return (n - len + 16) & 0x7;
@@ -337,14 +332,13 @@ static struct xfrm_type mip6_destopt_type =
 	.description	= "MIP6DESTOPT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_DSTOPTS,
-	.flags		= XFRM_TYPE_NON_FRAGMENT,
+	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
 	.init_state	= mip6_destopt_init_state,
 	.destructor	= mip6_destopt_destroy,
 	.input		= mip6_destopt_input,
 	.output		= mip6_destopt_output,
 	.reject		= mip6_destopt_reject,
 	.hdr_offset	= mip6_destopt_offset,
-	.local_addr	= mip6_xfrm_addr,
 };
 
 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
@@ -467,13 +461,12 @@ static struct xfrm_type mip6_rthdr_type =
 	.description	= "MIP6RT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_ROUTING,
-	.flags		= XFRM_TYPE_NON_FRAGMENT,
+	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
 	.init_state	= mip6_rthdr_init_state,
 	.destructor	= mip6_rthdr_destroy,
 	.input		= mip6_rthdr_input,
 	.output		= mip6_rthdr_output,
 	.hdr_offset	= mip6_rthdr_offset,
-	.remote_addr	= mip6_xfrm_addr,
 };
 
 static int __init mip6_init(void)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index f04e718..ed29bef 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -87,20 +87,16 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 	return dst;
 }
 
-static inline struct in6_addr*
-__xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr)
+static inline xfrm_address_t *__xfrm6_bundle_addr_remote(struct xfrm_state *x)
 {
-	return (x->type->remote_addr) ?
-		(struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) :
-		(struct in6_addr*)&x->id.daddr;
+	return (x->type->flags & XFRM_TYPE_REMOTE_COADDR) ? x->coaddr :
+							    &x->id.daddr;
 }
 
-static inline struct in6_addr*
-__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
+static inline xfrm_address_t *__xfrm6_bundle_addr_local(struct xfrm_state *x)
 {
-	return (x->type->local_addr) ?
-		(struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) :
-		(struct in6_addr*)&x->props.saddr;
+	return (x->type->flags & XFRM_TYPE_LOCAL_COADDR) ? x->coaddr :
+							   &x->props.saddr;
 }
 
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
@@ -171,9 +167,9 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 				fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
 				break;
 			case AF_INET6:
-				ipv6_addr_copy(&fl_tunnel.fl6_dst, __xfrm6_bundle_addr_remote(xfrm[i], &fl->fl6_dst));
+				ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr *)__xfrm6_bundle_addr_remote(xfrm[i]));
 
-				ipv6_addr_copy(&fl_tunnel.fl6_src, __xfrm6_bundle_addr_local(xfrm[i], &fl->fl6_src));
+				ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr *)__xfrm6_bundle_addr_local(xfrm[i]));
 				break;
 			default:
 				BUG_ON(1);

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

* [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (8 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:37   ` David Miller
  2007-11-07 14:08 ` [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create Herbert Xu
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Move flow construction into xfrm_dst_lookup

This patch moves the flow construction from the callers of xfrm_dst_lookup
into that function.  It also changes xfrm_dst_lookup so that it takes an
xfrm state as its argument instead of explicit addresses.

This removes any address-specific logic from the callers of xfrm_dst_lookup
which is needed to correctly support inter-family transforms.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h      |   10 +---
 net/ipv4/xfrm4_policy.c |   80 ++++++++++++++++++---------------------
 net/ipv6/xfrm6_policy.c |   97 +++++++++++++++++-------------------------------
 net/xfrm/xfrm_policy.c  |   25 +++++++-----
 4 files changed, 91 insertions(+), 121 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index f96bae2..9b6af22 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -233,7 +233,8 @@ struct xfrm_policy_afinfo {
 	unsigned short		family;
 	struct dst_ops		*dst_ops;
 	void			(*garbage_collect)(void);
-	int			(*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
+	struct dst_entry	*(*dst_lookup)(int tos, xfrm_address_t *saddr,
+					       xfrm_address_t *daddr);
 	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
 	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
 	int			(*bundle_create)(struct xfrm_policy *policy, 
@@ -1079,7 +1080,6 @@ extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
 #ifdef CONFIG_XFRM
 extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);
-extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 #else
 static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
 {
@@ -1092,13 +1092,9 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
  	kfree_skb(skb);
 	return 0;
 }
-
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
-{
-	return -EINVAL;
-} 
 #endif
 
+extern struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos);
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index d903c8b..cebc847 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,8 @@
  *
  */
 
-#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
 #include <linux/inetdevice.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
@@ -17,28 +18,44 @@
 static struct dst_ops xfrm4_dst_ops;
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
 
-static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
+static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr,
+					  xfrm_address_t *daddr)
 {
-	return __ip_route_output_key((struct rtable**)dst, fl);
-}
-
-static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
-{
-	struct rtable *rt;
-	struct flowi fl_tunnel = {
+	struct flowi fl = {
 		.nl_u = {
 			.ip4_u = {
+				.tos = tos,
 				.daddr = daddr->a4,
 			},
 		},
 	};
+	struct dst_entry *dst;
+	struct rtable *rt;
+	int err;
 
-	if (!xfrm4_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
-		saddr->a4 = rt->rt_src;
-		dst_release(&rt->u.dst);
-		return 0;
-	}
-	return -EHOSTUNREACH;
+	if (saddr)
+		fl.fl4_src = saddr->a4;
+
+	err = __ip_route_output_key(&rt, &fl);
+	dst = &rt->u.dst;
+	if (err)
+		dst = ERR_PTR(err);
+	return dst;
+}
+
+static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+{
+	struct dst_entry *dst;
+	struct rtable *rt;
+
+	dst = xfrm4_dst_lookup(0, NULL, daddr);
+	if (IS_ERR(dst))
+		return -EHOSTUNREACH;
+
+	rt = (struct rtable *)dst;
+	saddr->a4 = rt->rt_src;
+	dst_release(dst);
+	return 0;
 }
 
 static struct dst_entry *
@@ -73,15 +90,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 	struct dst_entry *dst, *dst_prev;
 	struct rtable *rt0 = (struct rtable*)(*dst_p);
 	struct rtable *rt = rt0;
-	struct flowi fl_tunnel = {
-		.nl_u = {
-			.ip4_u = {
-				.saddr = fl->fl4_src,
-				.daddr = fl->fl4_dst,
-				.tos = fl->fl4_tos
-			}
-		}
-	};
+	int tos = fl->fl4_tos;
 	int i;
 	int err;
 	int header_len = 0;
@@ -119,25 +128,12 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		trailer_len += xfrm[i]->props.trailer_len;
 
 		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-			unsigned short encap_family = xfrm[i]->props.family;
-			switch (encap_family) {
-			case AF_INET:
-				fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
-				fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
-				break;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-			case AF_INET6:
-				ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr*)&xfrm[i]->id.daddr.a6);
-				ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr*)&xfrm[i]->props.saddr.a6);
-				break;
-#endif
-			default:
-				BUG_ON(1);
-			}
-			err = xfrm_dst_lookup((struct xfrm_dst **)&rt,
-					      &fl_tunnel, encap_family);
-			if (err)
+			dst1 = xfrm_dst_lookup(xfrm[i], tos);
+			err = PTR_ERR(dst1);
+			if (IS_ERR(dst1))
 				goto error;
+
+			rt = (struct rtable *)dst1;
 		} else
 			dst_hold(&rt->u.dst);
 	}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index ed29bef..864258f 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -11,7 +11,8 @@
  *
  */
 
-#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <net/addrconf.h>
 #include <net/dst.h>
@@ -26,35 +27,40 @@
 static struct dst_ops xfrm6_dst_ops;
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
 
-static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl)
+static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
+					  xfrm_address_t *daddr)
 {
-	struct dst_entry *dst = ip6_route_output(NULL, fl);
-	int err = dst->error;
-	if (!err)
-		*xdst = (struct xfrm_dst *) dst;
-	else
+	struct flowi fl = {};
+	struct dst_entry *dst;
+	int err;
+
+	memcpy(&fl.fl6_dst, daddr, sizeof(fl.fl6_dst));
+	if (saddr)
+		memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src));
+
+	dst = ip6_route_output(NULL, &fl);
+
+	err = dst->error;
+	if (dst->error) {
 		dst_release(dst);
-	return err;
+		dst = ERR_PTR(err);
+	}
+
+	return dst;
 }
 
 static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
 {
-	struct rt6_info *rt;
-	struct flowi fl_tunnel = {
-		.nl_u = {
-			.ip6_u = {
-				.daddr = *(struct in6_addr *)&daddr->a6,
-			},
-		},
-	};
-
-	if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
-		ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
-			       (struct in6_addr *)&saddr->a6);
-		dst_release(&rt->u.dst);
-		return 0;
-	}
-	return -EHOSTUNREACH;
+	struct dst_entry *dst;
+
+	dst = xfrm6_dst_lookup(0, NULL, daddr);
+	if (IS_ERR(dst))
+		return -EHOSTUNREACH;
+
+	ipv6_get_saddr(dst, (struct in6_addr *)&daddr->a6,
+		       (struct in6_addr *)&saddr->a6);
+	dst_release(dst);
+	return 0;
 }
 
 static struct dst_entry *
@@ -87,18 +93,6 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 	return dst;
 }
 
-static inline xfrm_address_t *__xfrm6_bundle_addr_remote(struct xfrm_state *x)
-{
-	return (x->type->flags & XFRM_TYPE_REMOTE_COADDR) ? x->coaddr :
-							    &x->id.daddr;
-}
-
-static inline xfrm_address_t *__xfrm6_bundle_addr_local(struct xfrm_state *x)
-{
-	return (x->type->flags & XFRM_TYPE_LOCAL_COADDR) ? x->coaddr :
-							   &x->props.saddr;
-}
-
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
  * all the metrics... Shortly, bundle a bundle.
  */
@@ -110,14 +104,6 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 	struct dst_entry *dst, *dst_prev;
 	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
 	struct rt6_info *rt  = rt0;
-	struct flowi fl_tunnel = {
-		.nl_u = {
-			.ip6_u = {
-				.saddr = fl->fl6_src,
-				.daddr = fl->fl6_dst,
-			}
-		}
-	};
 	int i;
 	int err;
 	int header_len = 0;
@@ -160,25 +146,12 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 		trailer_len += xfrm[i]->props.trailer_len;
 
 		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-			unsigned short encap_family = xfrm[i]->props.family;
-			switch(encap_family) {
-			case AF_INET:
-				fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
-				fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
-				break;
-			case AF_INET6:
-				ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr *)__xfrm6_bundle_addr_remote(xfrm[i]));
-
-				ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr *)__xfrm6_bundle_addr_local(xfrm[i]));
-				break;
-			default:
-				BUG_ON(1);
-			}
-
-			err = xfrm_dst_lookup((struct xfrm_dst **) &rt,
-					      &fl_tunnel, encap_family);
-			if (err)
+			dst1 = xfrm_dst_lookup(xfrm[i], 0);
+			err = PTR_ERR(dst1);
+			if (IS_ERR(dst1))
 				goto error;
+
+			rt = (struct rt6_info *)dst1;
 		} else
 			dst_hold(&rt->u.dst);
 	}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b702bd8..6168341 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
@@ -84,21 +85,25 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
 	return 0;
 }
 
-int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
-		    unsigned short family)
+struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos)
 {
-	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
-	int err = 0;
+	xfrm_address_t *saddr = &x->props.saddr;
+	xfrm_address_t *daddr = &x->id.daddr;
+	struct xfrm_policy_afinfo *afinfo;
+	struct dst_entry *dst;
 
+	if (x->type->flags & XFRM_TYPE_LOCAL_COADDR)
+		saddr = x->coaddr;
+	if (x->type->flags & XFRM_TYPE_REMOTE_COADDR)
+		daddr = x->coaddr;
+
+	afinfo = xfrm_policy_get_afinfo(x->props.family);
 	if (unlikely(afinfo == NULL))
-		return -EAFNOSUPPORT;
+		return ERR_PTR(-EAFNOSUPPORT);
 
-	if (likely(afinfo->dst_lookup != NULL))
-		err = afinfo->dst_lookup(dst, fl);
-	else
-		err = -EINVAL;
+	dst = afinfo->dst_lookup(tos, saddr, daddr);
 	xfrm_policy_put_afinfo(afinfo);
-	return err;
+	return dst;
 }
 EXPORT_SYMBOL(xfrm_dst_lookup);
 

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

* [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (9 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:38   ` David Miller
  2007-11-07 14:08 ` [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now Herbert Xu
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Merge common code into xfrm_bundle_create

Half of the code in xfrm4_bundle_create and xfrm6_bundle_create are common.
This patch extracts that logic and puts it into xfrm_bundle_create.  The
rest of it are then accessed through afinfo.

As a result this fixes the problem with inter-family transforms where we
treat every xfrm dst in the bundle as if it belongs to the top family.

This patch also fixes a long-standing error-path bug where we may free the
xfrm states twice.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h      |   11 +-
 net/ipv4/xfrm4_policy.c |  134 ++++++-----------------------------
 net/ipv6/xfrm6_policy.c |  143 ++++++-------------------------------
 net/xfrm/xfrm_policy.c  |  183 +++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 215 insertions(+), 256 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9b6af22..4178c2b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -227,6 +227,7 @@ struct km_event
 	u32	event;
 };
 
+struct net_device;
 struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
@@ -237,13 +238,11 @@ struct xfrm_policy_afinfo {
 					       xfrm_address_t *daddr);
 	int			(*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
 	struct dst_entry	*(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
-	int			(*bundle_create)(struct xfrm_policy *policy, 
-						 struct xfrm_state **xfrm, 
-						 int nx,
-						 struct flowi *fl, 
-						 struct dst_entry **dst_p);
 	void			(*decode_session)(struct sk_buff *skb,
 						  struct flowi *fl);
+	int			(*get_tos)(struct flowi *fl);
+	int			(*fill_dst)(struct xfrm_dst *xdst,
+					    struct net_device *dev);
 };
 
 extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
@@ -1094,7 +1093,6 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 }
 #endif
 
-extern struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos);
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
@@ -1113,7 +1111,6 @@ extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
 extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
 			  struct flowi *fl, int family, int strict);
-extern void xfrm_init_pmtu(struct dst_entry *dst);
 
 #ifdef CONFIG_XFRM_MIGRATE
 extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index cebc847..1d75243 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -79,122 +79,39 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 	return dst;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
-
-static int
-__xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-		      struct flowi *fl, struct dst_entry **dst_p)
+static int xfrm4_get_tos(struct flowi *fl)
 {
-	struct dst_entry *dst, *dst_prev;
-	struct rtable *rt0 = (struct rtable*)(*dst_p);
-	struct rtable *rt = rt0;
-	int tos = fl->fl4_tos;
-	int i;
-	int err;
-	int header_len = 0;
-	int trailer_len = 0;
-
-	dst = dst_prev = NULL;
-	dst_hold(&rt->u.dst);
-
-	for (i = 0; i < nx; i++) {
-		struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
-		struct xfrm_dst *xdst;
-
-		if (unlikely(dst1 == NULL)) {
-			err = -ENOBUFS;
-			dst_release(&rt->u.dst);
-			goto error;
-		}
+	return fl->fl4_tos;
+}
 
-		if (!dst)
-			dst = dst1;
-		else {
-			dst_prev->child = dst1;
-			dst1->flags |= DST_NOHASH;
-			dst_clone(dst1);
-		}
+static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+{
+	struct rtable *rt = (struct rtable *)xdst->route;
 
-		xdst = (struct xfrm_dst *)dst1;
-		xdst->route = &rt->u.dst;
-		xdst->genid = xfrm[i]->genid;
+	xdst->u.rt.fl = rt->fl;
 
-		dst1->next = dst_prev;
-		dst_prev = dst1;
+	xdst->u.dst.dev = dev;
+	dev_hold(dev);
 
-		header_len += xfrm[i]->props.header_len;
-		trailer_len += xfrm[i]->props.trailer_len;
+	xdst->u.rt.idev = in_dev_get(dev);
+	if (!xdst->u.rt.idev)
+		return -ENODEV;
 
-		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-			dst1 = xfrm_dst_lookup(xfrm[i], tos);
-			err = PTR_ERR(dst1);
-			if (IS_ERR(dst1))
-				goto error;
+	xdst->u.rt.peer = rt->peer;
+	if (rt->peer)
+		atomic_inc(&rt->peer->refcnt);
 
-			rt = (struct rtable *)dst1;
-		} else
-			dst_hold(&rt->u.dst);
-	}
+	/* Sheit... I remember I did this right. Apparently,
+	 * it was magically lost, so this code needs audit */
+	xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST |
+					      RTCF_LOCAL);
+	xdst->u.rt.rt_type = rt->rt_type;
+	xdst->u.rt.rt_src = rt->rt_src;
+	xdst->u.rt.rt_dst = rt->rt_dst;
+	xdst->u.rt.rt_gateway = rt->rt_gateway;
+	xdst->u.rt.rt_spec_dst = rt->rt_spec_dst;
 
-	dst_prev->child = &rt->u.dst;
-	dst->path = &rt->u.dst;
-
-	/* Copy neighbout for reachability confirmation */
-	dst->neighbour = neigh_clone(rt->u.dst.neighbour);
-
-	*dst_p = dst;
-	dst = dst_prev;
-
-	dst_prev = *dst_p;
-	i = 0;
-	err = -ENODEV;
-	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		x->u.rt.fl = *fl;
-
-		dst_prev->xfrm = xfrm[i++];
-		dst_prev->dev = rt->u.dst.dev;
-		if (!rt->u.dst.dev)
-			goto error;
-		dev_hold(rt->u.dst.dev);
-
-		x->u.rt.idev = in_dev_get(rt->u.dst.dev);
-		if (!x->u.rt.idev)
-			goto error;
-
-		dst_prev->obsolete	= -1;
-		dst_prev->flags	       |= DST_HOST;
-		dst_prev->lastuse	= jiffies;
-		dst_prev->header_len	= header_len;
-		dst_prev->trailer_len	= trailer_len;
-		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
-
-		dst_prev->input = dst_discard;
-		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
-		if (rt0->peer)
-			atomic_inc(&rt0->peer->refcnt);
-		x->u.rt.peer = rt0->peer;
-		/* Sheit... I remember I did this right. Apparently,
-		 * it was magically lost, so this code needs audit */
-		x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-		x->u.rt.rt_type = rt0->rt_type;
-		x->u.rt.rt_src = rt0->rt_src;
-		x->u.rt.rt_dst = rt0->rt_dst;
-		x->u.rt.rt_gateway = rt0->rt_gateway;
-		x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
-		header_len -= x->u.dst.xfrm->props.header_len;
-		trailer_len -= x->u.dst.xfrm->props.trailer_len;
-	}
-
-	xfrm_init_pmtu(dst);
 	return 0;
-
-error:
-	if (dst)
-		dst_free(dst);
-	return err;
 }
 
 static void
@@ -330,8 +247,9 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
 	.dst_lookup =		xfrm4_dst_lookup,
 	.get_saddr =		xfrm4_get_saddr,
 	.find_bundle = 		__xfrm4_find_bundle,
-	.bundle_create =	__xfrm4_bundle_create,
 	.decode_session =	_decode_session4,
+	.get_tos =		xfrm4_get_tos,
+	.fill_dst =		xfrm4_fill_dst,
 };
 
 static void __init xfrm4_policy_init(void)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 864258f..50a3841 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -93,126 +93,34 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 	return dst;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
-
-static int
-__xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-		      struct flowi *fl, struct dst_entry **dst_p)
+static int xfrm6_get_tos(struct flowi *fl)
 {
-	struct dst_entry *dst, *dst_prev;
-	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
-	struct rt6_info *rt  = rt0;
-	int i;
-	int err;
-	int header_len = 0;
-	int trailer_len = 0;
-
-	dst = dst_prev = NULL;
-	dst_hold(&rt->u.dst);
-
-	for (i = 0; i < nx; i++) {
-		struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
-		struct xfrm_dst *xdst;
-
-		if (unlikely(dst1 == NULL)) {
-			err = -ENOBUFS;
-			dst_release(&rt->u.dst);
-			goto error;
-		}
-
-		if (!dst)
-			dst = dst1;
-		else {
-			dst_prev->child = dst1;
-			dst1->flags |= DST_NOHASH;
-			dst_clone(dst1);
-		}
-
-		xdst = (struct xfrm_dst *)dst1;
-		xdst->route = &rt->u.dst;
-		xdst->genid = xfrm[i]->genid;
-		if (rt->rt6i_node)
-			xdst->route_cookie = rt->rt6i_node->fn_sernum;
-
-		dst1->next = dst_prev;
-		dst_prev = dst1;
-
-		if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
-			((struct rt6_info *)dst)->nfheader_len +=
-				xfrm[i]->props.header_len;
-		header_len += xfrm[i]->props.header_len;
-		trailer_len += xfrm[i]->props.trailer_len;
-
-		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-			dst1 = xfrm_dst_lookup(xfrm[i], 0);
-			err = PTR_ERR(dst1);
-			if (IS_ERR(dst1))
-				goto error;
-
-			rt = (struct rt6_info *)dst1;
-		} else
-			dst_hold(&rt->u.dst);
-	}
+	return 0;
+}
 
-	dst_prev->child = &rt->u.dst;
-	dst->path = &rt->u.dst;
-
-	/* Copy neighbour for reachability confirmation */
-	dst->neighbour = neigh_clone(rt->u.dst.neighbour);
-
-	if (rt->rt6i_node)
-		((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum;
-
-	*dst_p = dst;
-	dst = dst_prev;
-
-	dst_prev = *dst_p;
-	i = 0;
-	err = -ENODEV;
-	for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-
-		dst_prev->xfrm = xfrm[i++];
-		dst_prev->dev = rt->u.dst.dev;
-		if (!rt->u.dst.dev)
-			goto error;
-		dev_hold(rt->u.dst.dev);
-
-		x->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
-		if (!x->u.rt6.rt6i_idev)
-			goto error;
-
-		dst_prev->obsolete	= -1;
-		dst_prev->flags	       |= DST_HOST;
-		dst_prev->lastuse	= jiffies;
-		dst_prev->header_len	= header_len;
-		dst_prev->trailer_len	= trailer_len;
-		memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
-
-		dst_prev->input = dst_discard;
-		dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
-		/* Sheit... I remember I did this right. Apparently,
-		 * it was magically lost, so this code needs audit */
-		x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-		x->u.rt6.rt6i_metric   = rt0->rt6i_metric;
-		x->u.rt6.rt6i_node     = rt0->rt6i_node;
-		x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
-		memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
-		x->u.rt6.rt6i_dst      = rt0->rt6i_dst;
-		x->u.rt6.rt6i_src      = rt0->rt6i_src;
-		header_len -= x->u.dst.xfrm->props.header_len;
-		trailer_len -= x->u.dst.xfrm->props.trailer_len;
-	}
+static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+{
+	struct rt6_info *rt = (struct rt6_info*)xdst->route;
+
+	xdst->u.dst.dev = dev;
+	dev_hold(dev);
+
+	xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+	if (!xdst->u.rt6.rt6i_idev)
+		return -ENODEV;
+
+	/* Sheit... I remember I did this right. Apparently,
+	 * it was magically lost, so this code needs audit */
+	xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTCF_BROADCAST |
+						   RTCF_MULTICAST |
+						   RTCF_LOCAL);
+	xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
+	xdst->u.rt6.rt6i_node = rt->rt6i_node;
+	xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
+	xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
+	xdst->u.rt6.rt6i_src = rt->rt6i_src;
 
-	xfrm_init_pmtu(dst);
 	return 0;
-
-error:
-	if (dst)
-		dst_free(dst);
-	return err;
 }
 
 static inline void
@@ -355,8 +263,9 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
 	.dst_lookup =		xfrm6_dst_lookup,
 	.get_saddr = 		xfrm6_get_saddr,
 	.find_bundle =		__xfrm6_find_bundle,
-	.bundle_create =	__xfrm6_bundle_create,
 	.decode_session =	_decode_session6,
+	.get_tos =		xfrm6_get_tos,
+	.fill_dst =		xfrm6_fill_dst,
 };
 
 static void __init xfrm6_policy_init(void)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6168341..5a03612 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -24,6 +24,7 @@
 #include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/cache.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 
@@ -50,6 +51,7 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
+static void xfrm_init_pmtu(struct dst_entry *dst);
 
 static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -85,7 +87,8 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
 	return 0;
 }
 
-struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos)
+static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
+						int family)
 {
 	xfrm_address_t *saddr = &x->props.saddr;
 	xfrm_address_t *daddr = &x->id.daddr;
@@ -97,7 +100,7 @@ struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos)
 	if (x->type->flags & XFRM_TYPE_REMOTE_COADDR)
 		daddr = x->coaddr;
 
-	afinfo = xfrm_policy_get_afinfo(x->props.family);
+	afinfo = xfrm_policy_get_afinfo(family);
 	if (unlikely(afinfo == NULL))
 		return ERR_PTR(-EAFNOSUPPORT);
 
@@ -105,7 +108,6 @@ struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos)
 	xfrm_policy_put_afinfo(afinfo);
 	return dst;
 }
-EXPORT_SYMBOL(xfrm_dst_lookup);
 
 static inline unsigned long make_jiffies(long secs)
 {
@@ -1235,24 +1237,164 @@ xfrm_find_bundle(struct flowi *fl, struct xfrm_policy *policy, unsigned short fa
 	return x;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
+static inline int xfrm_get_tos(struct flowi *fl, int family)
+{
+	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+	int tos;
 
-static int
-xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-		   struct flowi *fl, struct dst_entry **dst_p,
-		   unsigned short family)
+	if (!afinfo)
+		return -EINVAL;
+
+	tos = afinfo->get_tos(fl);
+
+	xfrm_policy_put_afinfo(afinfo);
+
+	return tos;
+}
+
+static inline struct xfrm_dst *xfrm_alloc_dst(int family)
 {
-	int err;
 	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
-	if (unlikely(afinfo == NULL))
+	struct xfrm_dst *xdst;
+
+	if (!afinfo)
+		return ERR_PTR(-EINVAL);
+
+	xdst = dst_alloc(afinfo->dst_ops) ?: ERR_PTR(-ENOBUFS);
+
+	xfrm_policy_put_afinfo(afinfo);
+
+	return xdst;
+}
+
+static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+{
+	struct xfrm_policy_afinfo *afinfo =
+		xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
+	int err;
+
+	if (!afinfo)
 		return -EINVAL;
-	err = afinfo->bundle_create(policy, xfrm, nx, fl, dst_p);
+
+	err = afinfo->fill_dst(xdst, dev);
+
 	xfrm_policy_put_afinfo(afinfo);
+
 	return err;
 }
 
+/* Allocate chain of dst_entry's, attach known xfrm's, calculate
+ * all the metrics... Shortly, bundle a bundle.
+ */
+
+static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
+					    struct xfrm_state **xfrm, int nx,
+					    struct flowi *fl,
+					    struct dst_entry *dst)
+{
+	unsigned long now = jiffies;
+	struct net_device *dev;
+	struct dst_entry *dst_prev = NULL;
+	struct dst_entry *dst0 = NULL;
+	int i = 0;
+	int err;
+	int header_len = 0;
+	int trailer_len = 0;
+	int tos;
+	int family = policy->selector.family;
+
+	tos = xfrm_get_tos(fl, family);
+	err = tos;
+	if (tos < 0)
+		goto put_states;
+
+	dst_hold(dst);
+
+	for (; i < nx; i++) {
+		struct xfrm_dst *xdst = xfrm_alloc_dst(family);
+		struct dst_entry *dst1 = &xdst->u.dst;
+
+		err = PTR_ERR(xdst);
+		if (IS_ERR(xdst)) {
+			dst_release(dst);
+			goto put_states;
+		}
+
+		if (!dst_prev)
+			dst0 = dst1;
+		else {
+			dst_prev->child = dst_clone(dst1);
+			dst1->flags |= DST_NOHASH;
+		}
+
+		xdst->route = dst;
+		memcpy(&dst1->metrics, &dst->metrics, sizeof(dst->metrics));
+
+		if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
+			family = xfrm[i]->props.family;
+			dst = xfrm_dst_lookup(xfrm[i], tos, family);
+			err = PTR_ERR(dst);
+			if (IS_ERR(dst))
+				goto put_states;
+		} else
+			dst_hold(dst);
+
+		dst1->xfrm = xfrm[i];
+		xdst->genid = xfrm[i]->genid;
+
+		dst1->obsolete = -1;
+		dst1->flags |= DST_HOST;
+		dst1->lastuse = now;
+
+		dst1->input = dst_discard;
+		dst1->output = xfrm[i]->outer_mode->afinfo->output;
+
+		dst1->next = dst_prev;
+		dst_prev = dst1;
+
+		header_len += xfrm[i]->props.header_len;
+		trailer_len += xfrm[i]->props.trailer_len;
+	}
+
+	dst_prev->child = dst;
+	dst0->path = dst;
+
+	err = -ENODEV;
+	dev = dst->dev;
+	if (!dev)
+		goto free_dst;
+
+	/* Copy neighbout for reachability confirmation */
+	dst0->neighbour = neigh_clone(dst->neighbour);
+
+	xfrm_init_pmtu(dst_prev);
+
+	for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
+		struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
+
+		err = xfrm_fill_dst(xdst, dev);
+		if (err)
+			goto free_dst;
+
+		dst_prev->header_len = header_len;
+		dst_prev->trailer_len = trailer_len;
+		header_len -= xdst->u.dst.xfrm->props.header_len;
+		trailer_len -= xdst->u.dst.xfrm->props.trailer_len;
+	}
+
+out:
+	return dst0;
+
+put_states:
+	for (; i < nx; i++)
+		xfrm_state_put(xfrm[i]);
+free_dst:
+	if (dst0)
+		dst_free(dst0);
+	dst0 = ERR_PTR(err);
+	goto out;
+}
+
 static int inline
 xfrm_dst_alloc_copy(void **target, void *src, int size)
 {
@@ -1452,15 +1594,10 @@ restart:
 			return 0;
 		}
 
-		dst = dst_orig;
-		err = xfrm_bundle_create(policy, xfrm, nx, fl, &dst, family);
-
-		if (unlikely(err)) {
-			int i;
-			for (i=0; i<nx; i++)
-				xfrm_state_put(xfrm[i]);
+		dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
+		err = PTR_ERR(dst);
+		if (IS_ERR(dst))
 			goto error;
-		}
 
 		for (pi = 0; pi < npols; pi++) {
 			read_lock_bh(&pols[pi]->lock);
@@ -1883,7 +2020,7 @@ static int xfrm_flush_bundles(void)
 	return 0;
 }
 
-void xfrm_init_pmtu(struct dst_entry *dst)
+static void xfrm_init_pmtu(struct dst_entry *dst)
 {
 	do {
 		struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
@@ -1904,8 +2041,6 @@ void xfrm_init_pmtu(struct dst_entry *dst)
 	} while ((dst = dst->next));
 }
 
-EXPORT_SYMBOL(xfrm_init_pmtu);
-
 /* Check that the bundle accepts the flow and its components are
  * still valid.
  */

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

* [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (10 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:39   ` David Miller
  2007-11-07 14:08 ` [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section Herbert Xu
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Forbid BEET + ipcomp for now

While BEET can theoretically work with IPComp the current code can't do that
because it tries to construct a BEET mode tunnel type which doesn't (and
cannot) exist.  In fact as it is it won't even attach a tunnel object at
all for BEET which is bogus.

To support this fully we'd also need to change the policy checks on input
to recognise a plain tunnel as a legal variant of an optional BEET transform.

This patch simply fails such constructions for now.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/ipcomp.c  |   20 ++++++++++++--------
 net/ipv6/ipcomp6.c |   19 ++++++++-----------
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ca1b5fd..afcdbf4 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -181,7 +181,6 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
 static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t;
-	u8 mode = XFRM_MODE_TUNNEL;
 
 	t = xfrm_state_alloc();
 	if (t == NULL)
@@ -192,9 +191,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 	t->id.daddr.a4 = x->id.daddr.a4;
 	memcpy(&t->sel, &x->sel, sizeof(t->sel));
 	t->props.family = AF_INET;
-	if (x->props.mode == XFRM_MODE_BEET)
-		mode = x->props.mode;
-	t->props.mode = mode;
+	t->props.mode = x->props.mode;
 	t->props.saddr.a4 = x->props.saddr.a4;
 	t->props.flags = x->props.flags;
 
@@ -388,15 +385,22 @@ static int ipcomp_init_state(struct xfrm_state *x)
 	if (x->encap)
 		goto out;
 
+	x->props.header_len = 0;
+	switch (x->props.mode) {
+	case XFRM_MODE_TRANSPORT:
+		break;
+	case XFRM_MODE_TUNNEL:
+		x->props.header_len += sizeof(struct iphdr);
+		break;
+	default:
+		goto out;
+	}
+
 	err = -ENOMEM;
 	ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
 	if (!ipcd)
 		goto out;
 
-	x->props.header_len = 0;
-	if (x->props.mode == XFRM_MODE_TUNNEL)
-		x->props.header_len += sizeof(struct iphdr);
-
 	mutex_lock(&ipcomp_resource_mutex);
 	if (!ipcomp_alloc_scratches())
 		goto error;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 85eb479..eca0595 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -189,7 +189,6 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 {
 	struct xfrm_state *t = NULL;
-	u8 mode = XFRM_MODE_TUNNEL;
 
 	t = xfrm_state_alloc();
 	if (!t)
@@ -203,9 +202,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 	memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
 	memcpy(&t->sel, &x->sel, sizeof(t->sel));
 	t->props.family = AF_INET6;
-	if (x->props.mode == XFRM_MODE_BEET)
-		mode = x->props.mode;
-	t->props.mode = mode;
+	t->props.mode = x->props.mode;
 	memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
 	if (xfrm_init_state(t))
@@ -404,22 +401,22 @@ static int ipcomp6_init_state(struct xfrm_state *x)
 	if (x->encap)
 		goto out;
 
-	err = -ENOMEM;
-	ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
-	if (!ipcd)
-		goto out;
-
 	x->props.header_len = 0;
 	switch (x->props.mode) {
-	case XFRM_MODE_BEET:
 	case XFRM_MODE_TRANSPORT:
 		break;
 	case XFRM_MODE_TUNNEL:
 		x->props.header_len += sizeof(struct ipv6hdr);
+		break;
 	default:
-		goto error;
+		goto out;
 	}
 
+	err = -ENOMEM;
+	ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
+	if (!ipcd)
+		goto out;
+
 	mutex_lock(&ipcomp6_resource_mutex);
 	if (!ipcomp6_alloc_scratches())
 		goto error;

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

* [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (11 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-07 16:17   ` Ingo Oeser
  2007-11-14  5:39   ` David Miller
  2007-11-07 14:08 ` [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp Herbert Xu
                   ` (10 subsequent siblings)
  23 siblings, 2 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Move x->outer_mode->output out of locked section

RO mode is the only one that requires a locked output function.  So it's
easier to move the lock into that function rather than requiring everyone
else to run under the lock.

In particular, this allows us to move the size check into the output
function without causing a potential dead-lock should the ICMP error
somehow hit the same SA on transmission.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv6/xfrm6_mode_ro.c |    3 +++
 net/xfrm/xfrm_output.c   |    8 ++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index a7bc8c6..4a01cb3 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -28,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/spinlock.h>
 #include <linux/stringify.h>
 #include <linux/time.h>
 #include <net/ipv6.h>
@@ -53,7 +54,9 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
 	__skb_pull(skb, hdr_len);
 	memmove(ipv6_hdr(skb), iph, hdr_len);
 
+	spin_lock_bh(&x->lock);
 	x->lastused = get_seconds();
+	spin_unlock_bh(&x->lock);
 
 	return 0;
 }
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 58d5a74..b1efdc8 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -53,6 +53,10 @@ int xfrm_output(struct sk_buff *skb)
 	}
 
 	do {
+		err = x->outer_mode->output(x, skb);
+		if (err)
+			goto error;
+
 		spin_lock_bh(&x->lock);
 		err = xfrm_state_check(x, skb);
 		if (err)
@@ -64,10 +68,6 @@ int xfrm_output(struct sk_buff *skb)
 				xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
 		}
 
-		err = x->outer_mode->output(x, skb);
-		if (err)
-			goto error;
-
 		x->curlft.bytes += skb->len;
 		x->curlft.packets++;
 

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

* [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (12 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:40   ` David Miller
  2007-11-07 14:08 ` [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output Herbert Xu
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[INET]: Give outer DSCP directly to ip*_copy_dscp

This patch changes the prototype of ipv4_copy_dscp and ipv6_copy_dscp so
that they directly take the outer DSCP rather than the outer IP header.
This will help us to unify the code for inter-family tunnels.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/inet_ecn.h       |    8 ++++----
 net/ipv4/xfrm4_mode_tunnel.c |    2 +-
 net/ipv6/ip6_tunnel.c        |    2 +-
 net/ipv6/xfrm6_mode_tunnel.c |    3 ++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index de8399a..ba33db0 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -83,9 +83,9 @@ static inline void IP_ECN_clear(struct iphdr *iph)
 	iph->tos &= ~INET_ECN_MASK;
 }
 
-static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
+static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
 {
-	u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
+	dscp &= ~INET_ECN_MASK;
 	ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
 }
 
@@ -104,9 +104,9 @@ static inline void IP6_ECN_clear(struct ipv6hdr *iph)
 	*(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
 }
 
-static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner)
+static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
 {
-	u32 dscp = ipv6_get_dsfield(outer) & ~INET_ECN_MASK;
+	dscp &= ~INET_ECN_MASK;
 	ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
 }
 
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index e4deecb..68a9f56 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -113,7 +113,7 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 	iph = ip_hdr(skb);
 	if (iph->protocol == IPPROTO_IPIP) {
 		if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-			ipv4_copy_dscp(iph, ipip_hdr(skb));
+			ipv4_copy_dscp(ipv4_get_dsfield(iph), ipip_hdr(skb));
 		if (!(x->props.flags & XFRM_STATE_NOECN))
 			ipip_ecn_decapsulate(skb);
 	}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 5383b33..a4051af 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -635,7 +635,7 @@ static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
 					struct sk_buff *skb)
 {
 	if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
-		ipv6_copy_dscp(ipv6h, ipv6_hdr(skb));
+		ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb));
 
 	if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
 		IP6_ECN_set_ce(ipv6_hdr(skb));
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index fd84e22..9a43ea7 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -95,7 +95,8 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 	nh = skb_network_header(skb);
 	if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
 		if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-			ipv6_copy_dscp(ipv6_hdr(skb), ipipv6_hdr(skb));
+			ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
+				       ipipv6_hdr(skb));
 		if (!(x->props.flags & XFRM_STATE_NOECN))
 			ipip6_ecn_decapsulate(skb);
 	} else {

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

* [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (13 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:41   ` David Miller
  2007-11-07 14:08 ` [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input Herbert Xu
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Separate inner/outer mode processing on output

With inter-family transforms the inner mode differs from the outer mode.
Attempting to handle both sides from the same function means that it
needs to handle both IPv4 and IPv6 which creates duplication and confusion.

This patch separates the two parts on the output path so that each function
deals with one family only.

In particular, the functions xfrm4_extract_output/xfrm6_extract_output
moves the pertinent fields from the IPv4/IPv6 IP headers into a neutral
format stored in skb->cb.  This is then used by the outer mode output
functions to write the outer IP header.  In this way the output function
no longer has to know about the inner address family.

Since the extract functions are only called by tunnel modes (the only
modes that can support inter-family transforms), I've also moved the
xfrm*_tunnel_check_size calls into them.  This allows the correct ICMP
message to be sent as opposed to now where you might call icmp_send with
an IPv6 packet and vice versa.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h           |   51 ++++++++++++++++++++++++++++++++++++++++++-
 net/ipv4/xfrm4_mode_beet.c   |   15 ++++++++++--
 net/ipv4/xfrm4_mode_tunnel.c |   37 +++++++++----------------------
 net/ipv4/xfrm4_output.c      |   41 +++++++++++++++++++++++++---------
 net/ipv4/xfrm4_state.c       |   17 ++++++++++++++
 net/ipv6/xfrm6_mode_beet.c   |   28 +++++++++++------------
 net/ipv6/xfrm6_mode_tunnel.c |   31 ++++++++------------------
 net/ipv6/xfrm6_output.c      |   39 +++++++++++++++++++++++++-------
 net/ipv6/xfrm6_state.c       |   18 +++++++++++++++
 9 files changed, 193 insertions(+), 84 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 4178c2b..9115baa 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -257,6 +257,7 @@ extern int __xfrm_state_delete(struct xfrm_state *x);
 
 struct xfrm_state_afinfo {
 	unsigned int		family;
+	unsigned int		proto;
 	struct module		*owner;
 	struct xfrm_type	*type_map[IPPROTO_MAX];
 	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
@@ -267,6 +268,8 @@ struct xfrm_state_afinfo {
 	int			(*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
 	int			(*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
 	int			(*output)(struct sk_buff *skb);
+	int			(*extract_output)(struct xfrm_state *x,
+						  struct sk_buff *skb);
 };
 
 extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -312,7 +315,18 @@ struct xfrm_mode {
 	 * header.  The value of the network header will always point
 	 * to the top IP header while skb->data will point to the payload.
 	 */
-	int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+	int (*output2)(struct xfrm_state *x,struct sk_buff *skb);
+
+	/*
+	 * This is the actual output entry point.
+	 *
+	 * For transport mode and equivalent this would be identical to
+	 * output2 (which does not need to be set).  While tunnel mode
+	 * and equivalent would set this to a tunnel encapsulation function
+	 * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn
+	 * call output2.
+	 */
+	int (*output)(struct xfrm_state *x, struct sk_buff *skb);
 
 	struct xfrm_state_afinfo *afinfo;
 	struct module *owner;
@@ -454,6 +468,35 @@ struct xfrm_skb_cb {
 
 #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
 
+/*
+ * This structure is used by the afinfo prepare_input/prepare_output functions
+ * to transmit header information to the mode input/output functions.
+ */
+struct xfrm_mode_skb_cb {
+	union {
+		struct inet_skb_parm h4;
+		struct inet6_skb_parm h6;
+	} header;
+
+	/* Copied from header for IPv4, always set to zero and DF for IPv6. */
+	__be16 id;
+	__be16 frag_off;
+
+	/* TOS for IPv4, class for IPv6. */
+	u8 tos;
+
+	/* TTL for IPv4, hop limitfor IPv6. */
+	u8 ttl;
+
+	/* Protocol for IPv4, NH for IPv6. */
+	u8 protocol;
+
+	/* Used by IPv6 only, zero for IPv4. */
+	u8 flow_lbl[3];
+};
+
+#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
+
 /* Audit Information */
 struct xfrm_audit
 {
@@ -1051,6 +1094,7 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_extract_header(struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 			   int encap_type);
 extern int xfrm4_rcv(struct sk_buff *skb);
@@ -1060,9 +1104,12 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 	return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
 }
 
+extern int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
+extern int xfrm6_extract_header(struct sk_buff *skb);
 extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
@@ -1072,6 +1119,8 @@ extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short
 extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
 extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
 extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
+extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_output(struct sk_buff *skb);
 extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
 				 u8 **prevhdr);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index e42e122..94842ad 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -43,7 +43,17 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 	ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
 
 	top_iph = ip_hdr(skb);
-	memmove(top_iph, iph, sizeof(*iph));
+
+	top_iph->ihl = 5;
+	top_iph->version = 4;
+
+	top_iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
+	top_iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
+
+	top_iph->id = XFRM_MODE_SKB_CB(skb)->id;
+	top_iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
+	top_iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
+
 	if (unlikely(optlen)) {
 		BUG_ON(optlen < 0);
 
@@ -111,7 +121,8 @@ out:
 
 static struct xfrm_mode xfrm4_beet_mode = {
 	.input = xfrm4_beet_input,
-	.output = xfrm4_beet_output,
+	.output2 = xfrm4_beet_output,
+	.output = xfrm4_prepare_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_BEET,
 	.flags = XFRM_MODE_FLAG_TUNNEL,
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 68a9f56..cc8bbb2 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -36,53 +36,37 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
 static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
-	struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-	struct iphdr *iph, *top_iph;
+	struct iphdr *top_iph;
 	int flags;
 
-	iph = ip_hdr(skb);
-
 	skb_set_network_header(skb, -x->props.header_len);
 	skb->mac_header = skb->network_header +
 			  offsetof(struct iphdr, protocol);
-	skb->transport_header = skb->network_header + sizeof(*iph);
+	skb->transport_header = skb->network_header + sizeof(*top_iph);
 	top_iph = ip_hdr(skb);
 
 	top_iph->ihl = 5;
 	top_iph->version = 4;
 
-	flags = x->props.flags;
+	top_iph->protocol = x->inner_mode->afinfo->proto;
 
 	/* DS disclosed */
-	if (xdst->route->ops->family == AF_INET) {
-		top_iph->protocol = IPPROTO_IPIP;
-		top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
-		top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
-			0 : (iph->frag_off & htons(IP_DF));
-	}
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	else {
-		struct ipv6hdr *ipv6h = (struct ipv6hdr*)iph;
-		top_iph->protocol = IPPROTO_IPV6;
-		top_iph->tos = INET_ECN_encapsulate(iph->tos, ipv6_get_dsfield(ipv6h));
-		top_iph->frag_off = 0;
-	}
-#endif
+	top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
+					    XFRM_MODE_SKB_CB(skb)->tos);
 
+	flags = x->props.flags;
 	if (flags & XFRM_STATE_NOECN)
 		IP_ECN_clear(top_iph);
 
-	if (!top_iph->frag_off)
-		__ip_select_ident(top_iph, dst->child, 0);
+	top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+			    0 : XFRM_MODE_SKB_CB(skb)->frag_off;
+	ip_select_ident(top_iph, dst->child, NULL);
 
 	top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
 
 	top_iph->saddr = x->props.saddr.a4;
 	top_iph->daddr = x->id.daddr.a4;
 
-	skb->protocol = htons(ETH_P_IP);
-
-	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 	return 0;
 }
 
@@ -136,7 +120,8 @@ out:
 
 static struct xfrm_mode xfrm4_tunnel_mode = {
 	.input = xfrm4_tunnel_input,
-	.output = xfrm4_tunnel_output,
+	.output2 = xfrm4_tunnel_output,
+	.output = xfrm4_prepare_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_TUNNEL,
 	.flags = XFRM_MODE_FLAG_TUNNEL,
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c4a7156..13fd113 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -8,11 +8,12 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/compiler.h>
 #include <linux/if_ether.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4.h>
+#include <net/dst.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/icmp.h>
@@ -25,8 +26,6 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
 	if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
 		goto out;
 
-	IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
-
 	if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
 		goto out;
 
@@ -40,19 +39,39 @@ out:
 	return ret;
 }
 
+int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err;
+
+	err = xfrm4_tunnel_check_size(skb);
+	if (err)
+		return err;
+
+	return xfrm4_extract_header(skb);
+}
+
+int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err;
+
+	err = x->inner_mode->afinfo->extract_output(x, skb);
+	if (err)
+		return err;
+
+	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+	IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
+
+	skb->protocol = htons(ETH_P_IP);
+
+	return x->outer_mode->output2(x, skb);
+}
+EXPORT_SYMBOL(xfrm4_prepare_output);
+
 static inline int xfrm4_output_one(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb->dst;
-	struct xfrm_state *x = dst->xfrm;
 	struct iphdr *iph;
 	int err;
 
-	if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-		err = xfrm4_tunnel_check_size(skb);
-		if (err)
-			goto error_nolock;
-	}
-
 	err = xfrm_output(skb);
 	if (err)
 		goto error_nolock;
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 13d54a1..e6030e7 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -47,12 +47,29 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
 	x->props.family = AF_INET;
 }
 
+int xfrm4_extract_header(struct sk_buff *skb)
+{
+	struct iphdr *iph = ip_hdr(skb);
+
+	XFRM_MODE_SKB_CB(skb)->id = iph->id;
+	XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
+	XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
+	XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
+	XFRM_MODE_SKB_CB(skb)->protocol = iph->protocol;
+	memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
+	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
+
+	return 0;
+}
+
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
+	.proto			= IPPROTO_IPIP,
 	.owner			= THIS_MODULE,
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
 	.output			= xfrm4_output,
+	.extract_output		= xfrm4_extract_output,
 };
 
 void __init xfrm4_state_init(void)
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 2bfb4f0..4988ed9 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -25,25 +25,24 @@
  */
 static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-	struct ipv6hdr *iph, *top_iph;
-	u8 *prevhdr;
-	int hdr_len;
+	struct ipv6hdr *top_iph;
 
-	iph = ipv6_hdr(skb);
-
-	hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
-
-	skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
 	skb_set_network_header(skb, -x->props.header_len);
-	skb->transport_header = skb->network_header + hdr_len;
-	__skb_pull(skb, hdr_len);
-
+	skb->mac_header = skb->network_header +
+			  offsetof(struct ipv6hdr, nexthdr);
+	skb->transport_header = skb->network_header + sizeof(*top_iph);
 	top_iph = ipv6_hdr(skb);
-	memmove(top_iph, iph, hdr_len);
 
+	top_iph->version = 6;
+
+	memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
+	       sizeof(top_iph->flow_lbl));
+	top_iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
+
+	ipv6_change_dsfield(top_iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
+	top_iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
 	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
 	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
-
 	return 0;
 }
 
@@ -76,7 +75,8 @@ out:
 
 static struct xfrm_mode xfrm6_beet_mode = {
 	.input = xfrm6_beet_input,
-	.output = xfrm6_beet_output,
+	.output2 = xfrm6_beet_output,
+	.output = xfrm6_prepare_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_BEET,
 	.flags = XFRM_MODE_FLAG_TUNNEL,
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 9a43ea7..d45ce5d 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -38,33 +38,22 @@ static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
 static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
-	struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-	struct ipv6hdr *iph, *top_iph;
+	struct ipv6hdr *top_iph;
 	int dsfield;
 
-	iph = ipv6_hdr(skb);
-
 	skb_set_network_header(skb, -x->props.header_len);
 	skb->mac_header = skb->network_header +
 			  offsetof(struct ipv6hdr, nexthdr);
-	skb->transport_header = skb->network_header + sizeof(*iph);
+	skb->transport_header = skb->network_header + sizeof(*top_iph);
 	top_iph = ipv6_hdr(skb);
 
 	top_iph->version = 6;
-	if (xdst->route->ops->family == AF_INET6) {
-		top_iph->priority = iph->priority;
-		top_iph->flow_lbl[0] = iph->flow_lbl[0];
-		top_iph->flow_lbl[1] = iph->flow_lbl[1];
-		top_iph->flow_lbl[2] = iph->flow_lbl[2];
-		top_iph->nexthdr = IPPROTO_IPV6;
-	} else {
-		top_iph->priority = 0;
-		top_iph->flow_lbl[0] = 0;
-		top_iph->flow_lbl[1] = 0;
-		top_iph->flow_lbl[2] = 0;
-		top_iph->nexthdr = IPPROTO_IPIP;
-	}
-	dsfield = ipv6_get_dsfield(top_iph);
+
+	memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
+	       sizeof(top_iph->flow_lbl));
+	top_iph->nexthdr = x->inner_mode->afinfo->proto;
+
+	dsfield = XFRM_MODE_SKB_CB(skb)->tos;
 	dsfield = INET_ECN_encapsulate(dsfield, dsfield);
 	if (x->props.flags & XFRM_STATE_NOECN)
 		dsfield &= ~INET_ECN_MASK;
@@ -72,7 +61,6 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 	top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
 	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
 	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
-	skb->protocol = htons(ETH_P_IPV6);
 	return 0;
 }
 
@@ -116,7 +104,8 @@ out:
 
 static struct xfrm_mode xfrm6_tunnel_mode = {
 	.input = xfrm6_tunnel_input,
-	.output = xfrm6_tunnel_output,
+	.output2 = xfrm6_tunnel_output,
+	.output = xfrm6_prepare_output,
 	.owner = THIS_MODULE,
 	.encap = XFRM_MODE_TUNNEL,
 	.flags = XFRM_MODE_FLAG_TUNNEL,
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6569767..bc2e80e 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -10,10 +10,12 @@
  */
 
 #include <linux/if_ether.h>
-#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/icmpv6.h>
 #include <linux/netfilter_ipv6.h>
+#include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
@@ -43,19 +45,38 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
 	return ret;
 }
 
+int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err;
+
+	err = xfrm6_tunnel_check_size(skb);
+	if (err)
+		return err;
+
+	return xfrm6_extract_header(skb);
+}
+
+int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err;
+
+	err = x->inner_mode->afinfo->extract_output(x, skb);
+	if (err)
+		return err;
+
+	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+
+	skb->protocol = htons(ETH_P_IPV6);
+
+	return x->outer_mode->output2(x, skb);
+}
+EXPORT_SYMBOL(xfrm6_prepare_output);
+
 static inline int xfrm6_output_one(struct sk_buff *skb)
 {
-	struct dst_entry *dst = skb->dst;
-	struct xfrm_state *x = dst->xfrm;
 	struct ipv6hdr *iph;
 	int err;
 
-	if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-		err = xfrm6_tunnel_check_size(skb);
-		if (err)
-			goto error_nolock;
-	}
-
 	err = xfrm_output(skb);
 	if (err)
 		goto error_nolock;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index b392bee..98b05f4 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -14,6 +14,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <net/dsfield.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 
@@ -168,13 +169,30 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
 	return 0;
 }
 
+int xfrm6_extract_header(struct sk_buff *skb)
+{
+	struct ipv6hdr *iph = ipv6_hdr(skb);
+
+	XFRM_MODE_SKB_CB(skb)->id = 0;
+	XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
+	XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
+	XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
+	XFRM_MODE_SKB_CB(skb)->protocol = iph->nexthdr;
+	memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
+	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
+
+	return 0;
+}
+
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.family			= AF_INET6,
+	.proto			= IPPROTO_IPV6,
 	.owner			= THIS_MODULE,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.tmpl_sort		= __xfrm6_tmpl_sort,
 	.state_sort		= __xfrm6_state_sort,
 	.output			= xfrm6_output,
+	.extract_output		= xfrm6_extract_output,
 };
 
 void __init xfrm6_state_init(void)

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

* [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (14 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:41   ` David Miller
  2007-11-07 14:08 ` [PATCH 17/24] [IPV4]: Add ip_local_out Herbert Xu
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Separate inner/outer mode processing on input

With inter-family transforms the inner mode differs from the outer mode.
Attempting to handle both sides from the same function means that it
needs to handle both IPv4 and IPv6 which creates duplication and confusion.

This patch separates the two parts on the input path so that each function
deals with one family only.

In particular, the functions xfrm4_extract_inut/xfrm6_extract_inut
moves the pertinent fields from the IPv4/IPv6 IP headers into a neutral
format stored in skb->cb.  This is then used by the inner mode input
functions to modify the inner IP header.  In this way the input function
no longer has to know about the outer address family.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h           |   27 +++++++++++++++++
 net/ipv4/xfrm4_input.c       |    7 +++-
 net/ipv4/xfrm4_mode_beet.c   |   67 +++++++++++++++++++++++++------------------
 net/ipv4/xfrm4_mode_tunnel.c |   44 ++++++----------------------
 net/ipv4/xfrm4_state.c       |    2 +
 net/ipv6/xfrm6_input.c       |    7 +++-
 net/ipv6/xfrm6_mode_beet.c   |   36 +++++++++++++++--------
 net/ipv6/xfrm6_mode_tunnel.c |   31 +++++--------------
 net/ipv6/xfrm6_output.c      |    1 
 net/ipv6/xfrm6_state.c       |    5 ++-
 net/xfrm/xfrm_input.c        |   13 ++++++++
 11 files changed, 141 insertions(+), 99 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9115baa..448a57f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -258,6 +258,7 @@ extern int __xfrm_state_delete(struct xfrm_state *x);
 struct xfrm_state_afinfo {
 	unsigned int		family;
 	unsigned int		proto;
+	unsigned int		eth_proto;
 	struct module		*owner;
 	struct xfrm_type	*type_map[IPPROTO_MAX];
 	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
@@ -268,6 +269,8 @@ struct xfrm_state_afinfo {
 	int			(*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
 	int			(*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
 	int			(*output)(struct sk_buff *skb);
+	int			(*extract_input)(struct xfrm_state *x,
+						 struct sk_buff *skb);
 	int			(*extract_output)(struct xfrm_state *x,
 						  struct sk_buff *skb);
 };
@@ -302,6 +305,27 @@ extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
 extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
 
 struct xfrm_mode {
+	/*
+	 * Remove encapsulation header.
+	 *
+	 * The IP header will be moved over the top of the encapsulation
+	 * header.
+	 *
+	 * On entry, the transport header shall point to where the IP header
+	 * should be and the network header shall be set to where the IP
+	 * header currently is.  skb->data shall point to the start of the
+	 * payload.
+	 */
+	int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
+
+	/*
+	 * This is the actual input entry point.
+	 *
+	 * For transport mode and equivalent this would be identical to
+	 * input2 (which does not need to be set).  While tunnel mode
+	 * and equivalent would set this to the tunnel encapsulation function
+	 * xfrm4_prepare_input that would in turn call input2.
+	 */
 	int (*input)(struct xfrm_state *x, struct sk_buff *skb);
 
 	/*
@@ -1093,8 +1117,10 @@ extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
 extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
+extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm_output(struct sk_buff *skb);
 extern int xfrm4_extract_header(struct sk_buff *skb);
+extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 			   int encap_type);
 extern int xfrm4_rcv(struct sk_buff *skb);
@@ -1110,6 +1136,7 @@ extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm6_extract_header(struct sk_buff *skb);
+extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5e95c8a..c0323d0 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,6 +16,11 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 
+int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	return xfrm4_extract_header(skb);
+}
+
 #ifdef CONFIG_NETFILTER
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
@@ -91,7 +96,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 
 		xfrm_vec[xfrm_nr++] = x;
 
-		if (x->outer_mode->input(x, skb))
+		if (x->inner_mode->input(x, skb))
 			goto drop;
 
 		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 94842ad..e093a7b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -17,6 +17,21 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 
+static void xfrm4_beet_make_header(struct sk_buff *skb)
+{
+	struct iphdr *iph = ip_hdr(skb);
+
+	iph->ihl = 5;
+	iph->version = 4;
+
+	iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
+	iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
+
+	iph->id = XFRM_MODE_SKB_CB(skb)->id;
+	iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
+	iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
+}
+
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
@@ -40,20 +55,12 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 			  offsetof(struct iphdr, protocol);
 	skb->transport_header = skb->network_header + sizeof(*iph);
 
+	xfrm4_beet_make_header(skb);
+
 	ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
 
 	top_iph = ip_hdr(skb);
 
-	top_iph->ihl = 5;
-	top_iph->version = 4;
-
-	top_iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
-	top_iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
-
-	top_iph->id = XFRM_MODE_SKB_CB(skb)->id;
-	top_iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
-	top_iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
-
 	if (unlikely(optlen)) {
 		BUG_ON(optlen < 0);
 
@@ -75,43 +82,46 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 
 static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-	struct iphdr *iph = ip_hdr(skb);
-	int phlen = 0;
+	struct iphdr *iph;
 	int optlen = 0;
-	u8 ph_nexthdr = 0;
 	int err = -EINVAL;
 
-	if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
+	if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) {
 		struct ip_beet_phdr *ph;
+		int phlen;
 
 		if (!pskb_may_pull(skb, sizeof(*ph)))
 			goto out;
-		ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);
+
+		ph = (struct ip_beet_phdr *)skb->data;
 
 		phlen = sizeof(*ph) + ph->padlen;
 		optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
 		if (optlen < 0 || optlen & 3 || optlen > 250)
 			goto out;
 
-		if (!pskb_may_pull(skb, phlen + optlen))
-			goto out;
-		skb->len -= phlen + optlen;
+		XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
 
-		ph_nexthdr = ph->nexthdr;
+		if (!pskb_may_pull(skb, phlen));
+			goto out;
+		__skb_pull(skb, phlen);
 	}
 
-	skb_set_network_header(skb, phlen - sizeof(*iph));
-	memmove(skb_network_header(skb), iph, sizeof(*iph));
-	skb_set_transport_header(skb, phlen + optlen);
-	skb->data = skb_transport_header(skb);
+	skb_push(skb, sizeof(*iph));
+	skb_reset_network_header(skb);
+
+	memmove(skb->data - skb->mac_len, skb_mac_header(skb),
+		skb->mac_len);
+	skb_set_mac_header(skb, -skb->mac_len);
+
+	xfrm4_beet_make_header(skb);
 
 	iph = ip_hdr(skb);
-	iph->ihl = (sizeof(*iph) + optlen) / 4;
-	iph->tot_len = htons(skb->len + iph->ihl * 4);
+
+	iph->ihl += optlen / 4;
+	iph->tot_len = htons(skb->len);
 	iph->daddr = x->sel.daddr.a4;
 	iph->saddr = x->sel.saddr.a4;
-	if (ph_nexthdr)
-		iph->protocol = ph_nexthdr;
 	iph->check = 0;
 	iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
 	err = 0;
@@ -120,7 +130,8 @@ out:
 }
 
 static struct xfrm_mode xfrm4_beet_mode = {
-	.input = xfrm4_beet_input,
+	.input2 = xfrm4_beet_input,
+	.input = xfrm_prepare_input,
 	.output2 = xfrm4_beet_output,
 	.output = xfrm4_prepare_output,
 	.owner = THIS_MODULE,
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index cc8bbb2..aa335db 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -16,19 +16,12 @@
 
 static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
 {
-	struct iphdr *outer_iph = ip_hdr(skb);
 	struct iphdr *inner_iph = ipip_hdr(skb);
 
-	if (INET_ECN_is_ce(outer_iph->tos))
+	if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
 		IP_ECN_set_ce(inner_iph);
 }
 
-static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
-{
-	if (INET_ECN_is_ce(iph->tos))
-		IP6_ECN_set_ce(ipv6_hdr(skb));
-}
-
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per RFC 2401.
@@ -72,20 +65,11 @@ static int xfrm4_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 
 static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-	struct iphdr *iph = ip_hdr(skb);
 	const unsigned char *old_mac;
 	int err = -EINVAL;
 
-	switch (iph->protocol){
-		case IPPROTO_IPIP:
-			break;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		case IPPROTO_IPV6:
-			break;
-#endif
-		default:
-			goto out;
-	}
+	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
+		goto out;
 
 	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
 		goto out;
@@ -94,20 +78,11 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 	    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
 		goto out;
 
-	iph = ip_hdr(skb);
-	if (iph->protocol == IPPROTO_IPIP) {
-		if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-			ipv4_copy_dscp(ipv4_get_dsfield(iph), ipip_hdr(skb));
-		if (!(x->props.flags & XFRM_STATE_NOECN))
-			ipip_ecn_decapsulate(skb);
-	}
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-	else {
-		if (!(x->props.flags & XFRM_STATE_NOECN))
-			ipip6_ecn_decapsulate(iph, skb);
-		skb->protocol = htons(ETH_P_IPV6);
-	}
-#endif
+	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+		ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
+	if (!(x->props.flags & XFRM_STATE_NOECN))
+		ipip_ecn_decapsulate(skb);
+
 	old_mac = skb_mac_header(skb);
 	skb_set_mac_header(skb, -skb->mac_len);
 	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
@@ -119,7 +94,8 @@ out:
 }
 
 static struct xfrm_mode xfrm4_tunnel_mode = {
-	.input = xfrm4_tunnel_input,
+	.input2 = xfrm4_tunnel_input,
+	.input = xfrm_prepare_input,
 	.output2 = xfrm4_tunnel_output,
 	.output = xfrm4_prepare_output,
 	.owner = THIS_MODULE,
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index e6030e7..85f04b7 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -65,10 +65,12 @@ int xfrm4_extract_header(struct sk_buff *skb)
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
 	.proto			= IPPROTO_IPIP,
+	.eth_proto		= htons(ETH_P_IP),
 	.owner			= THIS_MODULE,
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
 	.output			= xfrm4_output,
+	.extract_input		= xfrm4_extract_input,
 	.extract_output		= xfrm4_extract_output,
 };
 
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 5157837..c458d0a 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -16,6 +16,11 @@
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
+int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	return xfrm6_extract_header(skb);
+}
+
 int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 {
 	int err;
@@ -68,7 +73,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 
 		xfrm_vec[xfrm_nr++] = x;
 
-		if (x->outer_mode->input(x, skb))
+		if (x->inner_mode->input(x, skb))
 			goto drop;
 
 		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 4988ed9..0527d11 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -19,6 +19,20 @@
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
+static void xfrm6_beet_make_header(struct sk_buff *skb)
+{
+	struct ipv6hdr *iph = ipv6_hdr(skb);
+
+	iph->version = 6;
+
+	memcpy(iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
+	       sizeof(iph->flow_lbl));
+	iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
+
+	ipv6_change_dsfield(iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
+	iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
+}
+
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
@@ -31,16 +45,11 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 	skb->mac_header = skb->network_header +
 			  offsetof(struct ipv6hdr, nexthdr);
 	skb->transport_header = skb->network_header + sizeof(*top_iph);
-	top_iph = ipv6_hdr(skb);
 
-	top_iph->version = 6;
+	xfrm6_beet_make_header(skb);
 
-	memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
-	       sizeof(top_iph->flow_lbl));
-	top_iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
+	top_iph = ipv6_hdr(skb);
 
-	ipv6_change_dsfield(top_iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
-	top_iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
 	ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
 	ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
 	return 0;
@@ -51,19 +60,21 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 	struct ipv6hdr *ip6h;
 	const unsigned char *old_mac;
 	int size = sizeof(struct ipv6hdr);
-	int err = -EINVAL;
+	int err;
 
-	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+	err = skb_cow_head(skb, size + skb->mac_len);
+	if (err)
 		goto out;
 
-	skb_push(skb, size);
-	memmove(skb->data, skb_network_header(skb), size);
+	__skb_push(skb, size);
 	skb_reset_network_header(skb);
 
 	old_mac = skb_mac_header(skb);
 	skb_set_mac_header(skb, -skb->mac_len);
 	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
 
+	xfrm6_beet_make_header(skb);
+
 	ip6h = ipv6_hdr(skb);
 	ip6h->payload_len = htons(skb->len - size);
 	ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);
@@ -74,7 +85,8 @@ out:
 }
 
 static struct xfrm_mode xfrm6_beet_mode = {
-	.input = xfrm6_beet_input,
+	.input2 = xfrm6_beet_input,
+	.input = xfrm_prepare_input,
 	.output2 = xfrm6_beet_output,
 	.output = xfrm6_prepare_output,
 	.owner = THIS_MODULE,
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index d45ce5d..f7d0d66 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -25,12 +25,6 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
 		IP6_ECN_set_ce(inner_iph);
 }
 
-static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
-{
-	if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6_hdr(skb))))
-			IP_ECN_set_ce(ipip_hdr(skb));
-}
-
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per RFC 2401.
@@ -68,10 +62,8 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	int err = -EINVAL;
 	const unsigned char *old_mac;
-	const unsigned char *nh = skb_network_header(skb);
 
-	if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
-	    nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
+	if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
 		goto out;
 	if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
 		goto out;
@@ -80,18 +72,12 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 	    (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
 		goto out;
 
-	nh = skb_network_header(skb);
-	if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
-		if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-			ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
-				       ipipv6_hdr(skb));
-		if (!(x->props.flags & XFRM_STATE_NOECN))
-			ipip6_ecn_decapsulate(skb);
-	} else {
-		if (!(x->props.flags & XFRM_STATE_NOECN))
-			ip6ip_ecn_decapsulate(skb);
-		skb->protocol = htons(ETH_P_IP);
-	}
+	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+		ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
+			       ipipv6_hdr(skb));
+	if (!(x->props.flags & XFRM_STATE_NOECN))
+		ipip6_ecn_decapsulate(skb);
+
 	old_mac = skb_mac_header(skb);
 	skb_set_mac_header(skb, -skb->mac_len);
 	memmove(skb_mac_header(skb), old_mac, skb->mac_len);
@@ -103,7 +89,8 @@ out:
 }
 
 static struct xfrm_mode xfrm6_tunnel_mode = {
-	.input = xfrm6_tunnel_input,
+	.input2 = xfrm6_tunnel_input,
+	.input = xfrm_prepare_input,
 	.output2 = xfrm6_tunnel_output,
 	.output = xfrm6_prepare_output,
 	.owner = THIS_MODULE,
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index bc2e80e..c45050c 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -53,6 +53,7 @@ int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 	if (err)
 		return err;
 
+	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 	return xfrm6_extract_header(skb);
 }
 
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 98b05f4..90fef0a 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -177,7 +177,8 @@ int xfrm6_extract_header(struct sk_buff *skb)
 	XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
 	XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
 	XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
-	XFRM_MODE_SKB_CB(skb)->protocol = iph->nexthdr;
+	XFRM_MODE_SKB_CB(skb)->protocol =
+		skb_network_header(skb)[IP6CB(skb)->nhoff];
 	memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
@@ -187,11 +188,13 @@ int xfrm6_extract_header(struct sk_buff *skb)
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.family			= AF_INET6,
 	.proto			= IPPROTO_IPV6,
+	.eth_proto		= htons(ETH_P_IPV6),
 	.owner			= THIS_MODULE,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.tmpl_sort		= __xfrm6_tmpl_sort,
 	.state_sort		= __xfrm6_state_sort,
 	.output			= xfrm6_output,
+	.extract_input		= xfrm6_extract_input,
 	.extract_output		= xfrm6_extract_output,
 };
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index cb97fda..4c803f7 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -81,6 +81,19 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 }
 EXPORT_SYMBOL(xfrm_parse_spi);
 
+int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+	int err;
+
+	err = x->outer_mode->afinfo->extract_input(x, skb);
+	if (err)
+		return err;
+
+	skb->protocol = x->inner_mode->afinfo->eth_proto;
+	return x->inner_mode->input2(x, skb);
+}
+EXPORT_SYMBOL(xfrm_prepare_input);
+
 void __init xfrm_input_init(void)
 {
 	secpath_cachep = kmem_cache_create("secpath_cache",

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

* [PATCH 17/24] [IPV4]: Add ip_local_out
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (15 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:42   ` David Miller
  2007-11-07 14:08 ` [PATCH 18/24] [IPV6]: Add ip6_local_out Herbert Xu
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPV4]: Add ip_local_out

Most callers of the LOCAL_OUT chain will set the IP packet length
and header checksum before doing so.  They also share the same output
function dst_output.

This patch creates a new function called ip_local_out which does all
of that and converts the appropriate users over to it.

Apart from removing duplicate code, it will also help in merging the
IPsec output path once the same thing is done for IPv6.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/ip.h                |    6 +++++
 include/net/ipip.h              |    5 +---
 net/ipv4/igmp.c                 |   12 +----------
 net/ipv4/ip_output.c            |   41 ++++++++++++++++++++++++++--------------
 net/ipv4/ipvs/ip_vs_xmit.c      |    6 +----
 net/ipv4/netfilter/ipt_REJECT.c |    8 -------
 net/ipv4/xfrm4_output.c         |    8 -------
 7 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/include/net/ip.h b/include/net/ip.h
index 840dd91..dc60ea4 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -102,6 +102,12 @@ extern int		ip_mc_output(struct sk_buff *skb);
 extern int		ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 extern int		ip_do_nat(struct sk_buff *skb);
 extern void		ip_send_check(struct iphdr *ip);
+extern int		__ip_local_out(struct sk_buff *skb);
+#ifdef CONFIG_NETFILTER
+extern int		ip_local_out(struct sk_buff *skb);
+#else
+#define ip_local_out	__ip_local_out
+#endif
 extern int		ip_queue_xmit(struct sk_buff *skb, int ipfragok);
 extern void		ip_init(void);
 extern int		ip_append_data(struct sock *sk,
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 7cdc914..549e132 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -2,6 +2,7 @@
 #define __NET_IPIP_H 1
 
 #include <linux/if_tunnel.h>
+#include <net/ip.h>
 
 /* Keep error state on tunnel for 30 sec */
 #define IPTUNNEL_ERR_TIMEO	(30*HZ)
@@ -30,11 +31,9 @@ struct ip_tunnel
 	int pkt_len = skb->len;						\
 									\
 	skb->ip_summed = CHECKSUM_NONE;					\
-	iph->tot_len = htons(skb->len);					\
 	ip_select_ident(iph, &rt->u.dst, NULL);				\
-	ip_send_check(iph);						\
 									\
-	err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
+	err = ip_local_out(skb);					\
 	if (net_xmit_eval(err) == 0) {					\
 		stats->tx_bytes += pkt_len;				\
 		stats->tx_packets++;					\
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 7dbc282..77fa2a8 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -349,17 +349,12 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
 
 static int igmpv3_sendpack(struct sk_buff *skb)
 {
-	struct iphdr *pip = ip_hdr(skb);
 	struct igmphdr *pig = igmp_hdr(skb);
-	const int iplen = skb->tail - skb->network_header;
 	const int igmplen = skb->tail - skb->transport_header;
 
-	pip->tot_len = htons(iplen);
-	ip_send_check(pip);
 	pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
-		       dst_output);
+	return ip_local_out(skb);
 }
 
 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
@@ -680,13 +675,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
 	iph->daddr    = dst;
 	iph->saddr    = rt->rt_src;
 	iph->protocol = IPPROTO_IGMP;
-	iph->tot_len  = htons(IGMP_SIZE);
 	ip_select_ident(iph, &rt->u.dst, NULL);
 	((u8*)&iph[1])[0] = IPOPT_RA;
 	((u8*)&iph[1])[1] = 4;
 	((u8*)&iph[1])[2] = 0;
 	((u8*)&iph[1])[3] = 0;
-	ip_send_check(iph);
 
 	ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
 	ih->type=type;
@@ -695,8 +688,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
 	ih->group=group;
 	ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-		       dst_output);
+	return ip_local_out(skb);
 }
 
 static void igmp_gq_timer_expire(unsigned long data)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e5f7dc2..c652ddb 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -91,6 +91,30 @@ __inline__ void ip_send_check(struct iphdr *iph)
 	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
 }
 
+int __ip_local_out(struct sk_buff *skb)
+{
+	struct iphdr *iph = ip_hdr(skb);
+
+	iph->tot_len = htons(skb->len);
+	ip_send_check(iph);
+	return nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev,
+		       dst_output);
+}
+
+#ifdef CONFIG_NETFILTER
+int ip_local_out(struct sk_buff *skb)
+{
+	int err;
+
+	err = __ip_local_out(skb);
+	if (likely(err == 1))
+		err = dst_output(skb);
+
+	return err;
+}
+#endif
+EXPORT_SYMBOL_GPL(ip_local_out);
+
 /* dev_loopback_xmit for use with netfilter. */
 static int ip_dev_loopback_xmit(struct sk_buff *newskb)
 {
@@ -138,20 +162,17 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
 	iph->daddr    = rt->rt_dst;
 	iph->saddr    = rt->rt_src;
 	iph->protocol = sk->sk_protocol;
-	iph->tot_len  = htons(skb->len);
 	ip_select_ident(iph, &rt->u.dst, sk);
 
 	if (opt && opt->optlen) {
 		iph->ihl += opt->optlen>>2;
 		ip_options_build(skb, opt, daddr, rt, 0);
 	}
-	ip_send_check(iph);
 
 	skb->priority = sk->sk_priority;
 
 	/* Send it out. */
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-		       dst_output);
+	return ip_local_out(skb);
 }
 
 EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
@@ -347,7 +368,6 @@ packet_routed:
 	skb_reset_network_header(skb);
 	iph = ip_hdr(skb);
 	*((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
-	iph->tot_len = htons(skb->len);
 	if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
 		iph->frag_off = htons(IP_DF);
 	else
@@ -366,13 +386,9 @@ packet_routed:
 	ip_select_ident_more(iph, &rt->u.dst, sk,
 			     (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
-	/* Add an IP checksum. */
-	ip_send_check(iph);
-
 	skb->priority = sk->sk_priority;
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-		       dst_output);
+	return ip_local_out(skb);
 
 no_route:
 	IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
@@ -1249,14 +1265,12 @@ int ip_push_pending_frames(struct sock *sk)
 		ip_options_build(skb, opt, inet->cork.addr, rt, 0);
 	}
 	iph->tos = inet->tos;
-	iph->tot_len = htons(skb->len);
 	iph->frag_off = df;
 	ip_select_ident(iph, &rt->u.dst, sk);
 	iph->ttl = ttl;
 	iph->protocol = sk->sk_protocol;
 	iph->saddr = rt->rt_src;
 	iph->daddr = rt->rt_dst;
-	ip_send_check(iph);
 
 	skb->priority = sk->sk_priority;
 	skb->dst = dst_clone(&rt->u.dst);
@@ -1266,8 +1280,7 @@ int ip_push_pending_frames(struct sock *sk)
 			skb_transport_header(skb))->type);
 
 	/* Netfilter gets whole the not fragmented skb. */
-	err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
-		      skb->dst->dev, dst_output);
+	err = ip_local_out(skb);
 	if (err) {
 		if (err > 0)
 			err = inet->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 7c074e3..66775ad 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -16,8 +16,8 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/ip.h>
 #include <linux/tcp.h>                  /* for tcphdr */
+#include <net/ip.h>
 #include <net/tcp.h>                    /* for csum_tcpudp_magic */
 #include <net/udp.h>
 #include <net/icmp.h>                   /* for icmp_send */
@@ -406,14 +406,12 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	iph->daddr		=	rt->rt_dst;
 	iph->saddr		=	rt->rt_src;
 	iph->ttl		=	old_iph->ttl;
-	iph->tot_len		=	htons(skb->len);
 	ip_select_ident(iph, &rt->u.dst, NULL);
-	ip_send_check(iph);
 
 	/* Another hack: avoid icmp_send in ip_fragment */
 	skb->local_df = 1;
 
-	IP_VS_XMIT(skb, rt);
+	ip_local_out(skb);
 
 	LeaveFunction(10);
 
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index dcf4d21..ccb2a03 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -90,7 +90,6 @@ static void send_reset(struct sk_buff *oldskb, int hook)
 	/* Truncate to length (no data) */
 	tcph->doff = sizeof(struct tcphdr)/4;
 	skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr));
-	niph->tot_len = htons(nskb->len);
 
 	if (tcph->ack) {
 		needs_ack = 0;
@@ -139,18 +138,13 @@ static void send_reset(struct sk_buff *oldskb, int hook)
 	/* Adjust IP TTL */
 	niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
 
-	/* Adjust IP checksum */
-	niph->check = 0;
-	niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
-
 	/* "Never happens" */
 	if (nskb->len > dst_mtu(nskb->dst))
 		goto free_nskb;
 
 	nf_ct_attach(nskb, oldskb);
 
-	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
-		dst_output);
+	ip_local_out(nskb);
 	return;
 
  free_nskb:
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 13fd113..0ffc3d0 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -69,17 +69,12 @@ EXPORT_SYMBOL(xfrm4_prepare_output);
 
 static inline int xfrm4_output_one(struct sk_buff *skb)
 {
-	struct iphdr *iph;
 	int err;
 
 	err = xfrm_output(skb);
 	if (err)
 		goto error_nolock;
 
-	iph = ip_hdr(skb);
-	iph->tot_len = htons(skb->len);
-	ip_send_check(iph);
-
 	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
 	err = 0;
 
@@ -97,8 +92,7 @@ static int xfrm4_output_finish2(struct sk_buff *skb)
 	while (likely((err = xfrm4_output_one(skb)) == 0)) {
 		nf_reset(skb);
 
-		err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
-			      skb->dst->dev, dst_output);
+		err = __ip_local_out(skb);
 		if (unlikely(err != 1))
 			break;
 

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

* [PATCH 18/24] [IPV6]: Add ip6_local_out
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (16 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 17/24] [IPV4]: Add ip_local_out Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:42   ` David Miller
  2007-11-07 14:08 ` [PATCH 19/24] [IPSEC]: Merge most of the output path Herbert Xu
                   ` (5 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPV6]: Add ip6_local_out

Most callers of the LOCAL_OUT chain will set the IP packet length
before doing so.  They also share the same output function dst_output.

This patch creates a new function called ip6_local_out which does all
of that and converts the appropriate users over to it.

Apart from removing duplicate code, it will also help in merging the
IPsec output path.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/ipv6.h               |    7 +++++++
 net/ipv6/ip6_output.c            |   35 +++++++++++++++++++++++++++++------
 net/ipv6/ip6_tunnel.c            |    4 +---
 net/ipv6/netfilter/ip6t_REJECT.c |    4 +---
 net/ipv6/xfrm6_output.c          |    7 +------
 5 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ae328b6..5078605 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -509,6 +509,13 @@ extern int			ip6_forward(struct sk_buff *skb);
 extern int			ip6_input(struct sk_buff *skb);
 extern int			ip6_mc_input(struct sk_buff *skb);
 
+extern int			__ip6_local_out(struct sk_buff *skb);
+#ifdef CONFIG_NETFILTER
+extern int			ip6_local_out(struct sk_buff *skb);
+#else
+#define ip6_local_out		__ip6_local_out
+#endif
+
 /*
  *	Extension header (options) processing
  */
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 698d9d2..a0a366f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -29,7 +29,7 @@
  */
 
 #include <linux/errno.h>
-#include <linux/types.h>
+#include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/net.h>
@@ -70,6 +70,33 @@ static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *f
 	spin_unlock_bh(&ip6_id_lock);
 }
 
+int __ip6_local_out(struct sk_buff *skb)
+{
+	int len;
+
+	len = skb->len - sizeof(struct ipv6hdr);
+	if (len > IPV6_MAXPLEN)
+		len = 0;
+	ipv6_hdr(skb)->payload_len = htons(len);
+
+	return nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev,
+		       dst_output);
+}
+
+#ifdef CONFIG_NETFILTER
+int ip6_local_out(struct sk_buff *skb)
+{
+	int err;
+
+	err = __ip6_local_out(skb);
+	if (likely(err == 1))
+		err = dst_output(skb);
+
+	return err;
+}
+#endif
+EXPORT_SYMBOL_GPL(ip6_local_out);
+
 static int ip6_output_finish(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
@@ -1388,10 +1415,6 @@ int ip6_push_pending_frames(struct sock *sk)
 	*(__be32*)hdr = fl->fl6_flowlabel |
 		     htonl(0x60000000 | ((int)np->cork.tclass << 20));
 
-	if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
-		hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-	else
-		hdr->payload_len = 0;
 	hdr->hop_limit = np->cork.hop_limit;
 	hdr->nexthdr = proto;
 	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
@@ -1408,7 +1431,7 @@ int ip6_push_pending_frames(struct sock *sk)
 		ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
 	}
 
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
+	err = ip6_local_out(skb);
 	if (err) {
 		if (err > 0)
 			err = np->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a4051af..29b5321 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -910,15 +910,13 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 	*(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000);
 	dsfield = INET_ECN_encapsulate(0, dsfield);
 	ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
-	ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 	ipv6h->hop_limit = t->parms.hop_limit;
 	ipv6h->nexthdr = proto;
 	ipv6_addr_copy(&ipv6h->saddr, &fl->fl6_src);
 	ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst);
 	nf_reset(skb);
 	pkt_len = skb->len;
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
-		      skb->dst->dev, dst_output);
+	err = ip6_local_out(skb);
 
 	if (net_xmit_eval(err) == 0) {
 		stats->tx_bytes += pkt_len;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 1a7d291..c1c6634 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -121,7 +121,6 @@ static void send_reset(struct sk_buff *oldskb)
 	ip6h->version = 6;
 	ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
 	ip6h->nexthdr = IPPROTO_TCP;
-	ip6h->payload_len = htons(sizeof(struct tcphdr));
 	ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
 	ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
 
@@ -159,8 +158,7 @@ static void send_reset(struct sk_buff *oldskb)
 
 	nf_ct_attach(nskb, oldskb);
 
-	NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
-		dst_output);
+	ip6_local_out(nskb);
 }
 
 static inline void
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index c45050c..0f0ff51 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -75,16 +75,12 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
 
 static inline int xfrm6_output_one(struct sk_buff *skb)
 {
-	struct ipv6hdr *iph;
 	int err;
 
 	err = xfrm_output(skb);
 	if (err)
 		goto error_nolock;
 
-	iph = ipv6_hdr(skb);
-	iph->payload_len = htons(skb->len - sizeof(*iph));
-
 	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
 	err = 0;
 
@@ -102,8 +98,7 @@ static int xfrm6_output_finish2(struct sk_buff *skb)
 	while (likely((err = xfrm6_output_one(skb)) == 0)) {
 		nf_reset(skb);
 
-		err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
-			      skb->dst->dev, dst_output);
+		err = __ip6_local_out(skb);
 		if (unlikely(err != 1))
 			break;
 

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

* [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (17 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 18/24] [IPV6]: Add ip6_local_out Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-08 11:23   ` Patrick McHardy
  2007-11-14  5:43   ` David Miller
  2007-11-07 14:08 ` [PATCH 20/24] [IPSEC]: Add async resume support on output Herbert Xu
                   ` (4 subsequent siblings)
  23 siblings, 2 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Merge most of the output path

As part of the work on asynchrnous cryptographic operations, we need to
be able to resume from the spot where they occur.  As such, it helps if
we isolate them to one spot.

This patch moves most of the remaining family-specific processing into
the common output code.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/dst.h       |    1 
 include/net/xfrm.h      |    1 
 net/ipv4/route.c        |    1 
 net/ipv4/xfrm4_output.c |   76 ++---------------------------------------------
 net/ipv4/xfrm4_policy.c |    1 
 net/ipv4/xfrm4_state.c  |    2 +
 net/ipv6/route.c        |    1 
 net/ipv6/xfrm6_output.c |   77 ++++--------------------------------------------
 net/ipv6/xfrm6_policy.c |    1 
 net/ipv6/xfrm6_state.c  |    2 +
 net/xfrm/xfrm_output.c  |   70 +++++++++++++++++++++++++++++++++++++++++--
 11 files changed, 88 insertions(+), 145 deletions(-)

diff --git a/include/net/dst.h b/include/net/dst.h
index 4df103b..13f7e32 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -98,6 +98,7 @@ struct dst_ops
 	struct dst_entry *	(*negative_advice)(struct dst_entry *);
 	void			(*link_failure)(struct sk_buff *);
 	void			(*update_pmtu)(struct dst_entry *dst, u32 mtu);
+	int			(*local_out)(struct sk_buff *skb);
 	int			entry_size;
 
 	atomic_t		entries;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 448a57f..e674a78 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -259,6 +259,7 @@ struct xfrm_state_afinfo {
 	unsigned int		family;
 	unsigned int		proto;
 	unsigned int		eth_proto;
+	unsigned int		nf_post_routing;
 	struct module		*owner;
 	struct xfrm_type	*type_map[IPPROTO_MAX];
 	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d5cbcee..db484a2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -166,6 +166,7 @@ static struct dst_ops ipv4_dst_ops = {
 	.negative_advice =	ipv4_negative_advice,
 	.link_failure =		ipv4_link_failure,
 	.update_pmtu =		ip_rt_update_pmtu,
+	.local_out =		ip_local_out,
 	.entry_size =		sizeof(struct rtable),
 };
 
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 0ffc3d0..2fb4efa 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -59,7 +59,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 		return err;
 
 	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
-	IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
+	IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED;
 
 	skb->protocol = htons(ETH_P_IP);
 
@@ -67,87 +67,19 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(xfrm4_prepare_output);
 
-static inline int xfrm4_output_one(struct sk_buff *skb)
-{
-	int err;
-
-	err = xfrm_output(skb);
-	if (err)
-		goto error_nolock;
-
-	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
-	err = 0;
-
-out_exit:
-	return err;
-error_nolock:
-	kfree_skb(skb);
-	goto out_exit;
-}
-
-static int xfrm4_output_finish2(struct sk_buff *skb)
-{
-	int err;
-
-	while (likely((err = xfrm4_output_one(skb)) == 0)) {
-		nf_reset(skb);
-
-		err = __ip_local_out(skb);
-		if (unlikely(err != 1))
-			break;
-
-		if (!skb->dst->xfrm)
-			return dst_output(skb);
-
-		err = nf_hook(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
-			      skb->dst->dev, xfrm4_output_finish2);
-		if (unlikely(err != 1))
-			break;
-	}
-
-	return err;
-}
-
 static int xfrm4_output_finish(struct sk_buff *skb)
 {
-	struct sk_buff *segs;
-
 #ifdef CONFIG_NETFILTER
 	if (!skb->dst->xfrm) {
 		IPCB(skb)->flags |= IPSKB_REROUTED;
 		return dst_output(skb);
 	}
-#endif
 
-	if (!skb_is_gso(skb))
-		return xfrm4_output_finish2(skb);
+	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
+#endif
 
 	skb->protocol = htons(ETH_P_IP);
-	segs = skb_gso_segment(skb, 0);
-	kfree_skb(skb);
-	if (unlikely(IS_ERR(segs)))
-		return PTR_ERR(segs);
-
-	do {
-		struct sk_buff *nskb = segs->next;
-		int err;
-
-		segs->next = NULL;
-		err = xfrm4_output_finish2(segs);
-
-		if (unlikely(err)) {
-			while ((segs = nskb)) {
-				nskb = segs->next;
-				segs->next = NULL;
-				kfree_skb(segs);
-			}
-			return err;
-		}
-
-		segs = nskb;
-	} while (segs);
-
-	return 0;
+	return xfrm_output(skb);
 }
 
 int xfrm4_output(struct sk_buff *skb)
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 1d75243..d6232df 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -237,6 +237,7 @@ static struct dst_ops xfrm4_dst_ops = {
 	.update_pmtu =		xfrm4_update_pmtu,
 	.destroy =		xfrm4_dst_destroy,
 	.ifdown =		xfrm4_dst_ifdown,
+	.local_out =		ip_local_out,
 	.gc_thresh =		1024,
 	.entry_size =		sizeof(struct xfrm_dst),
 };
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 85f04b7..80292fb 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -11,6 +11,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <linux/netfilter_ipv4.h>
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo;
 
@@ -66,6 +67,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
 	.proto			= IPPROTO_IPIP,
 	.eth_proto		= htons(ETH_P_IP),
+	.nf_post_routing	= NF_IP_POST_ROUTING,
 	.owner			= THIS_MODULE,
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7db3cdf..2c91ce6 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -117,6 +117,7 @@ static struct dst_ops ip6_dst_ops = {
 	.negative_advice	=	ip6_negative_advice,
 	.link_failure		=	ip6_link_failure,
 	.update_pmtu		=	ip6_rt_update_pmtu,
+	.local_out		=	ip6_local_out,
 	.entry_size		=	sizeof(struct rt6_info),
 };
 
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 0f0ff51..a0a9249 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -66,6 +66,9 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 		return err;
 
 	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+#ifdef CONFIG_NETFILTER
+	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
+#endif
 
 	skb->protocol = htons(ETH_P_IPV6);
 
@@ -73,80 +76,14 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(xfrm6_prepare_output);
 
-static inline int xfrm6_output_one(struct sk_buff *skb)
-{
-	int err;
-
-	err = xfrm_output(skb);
-	if (err)
-		goto error_nolock;
-
-	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
-	err = 0;
-
-out_exit:
-	return err;
-error_nolock:
-	kfree_skb(skb);
-	goto out_exit;
-}
-
-static int xfrm6_output_finish2(struct sk_buff *skb)
-{
-	int err;
-
-	while (likely((err = xfrm6_output_one(skb)) == 0)) {
-		nf_reset(skb);
-
-		err = __ip6_local_out(skb);
-		if (unlikely(err != 1))
-			break;
-
-		if (!skb->dst->xfrm)
-			return dst_output(skb);
-
-		err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
-			      skb->dst->dev, xfrm6_output_finish2);
-		if (unlikely(err != 1))
-			break;
-	}
-
-	return err;
-}
-
 static int xfrm6_output_finish(struct sk_buff *skb)
 {
-	struct sk_buff *segs;
-
-	if (!skb_is_gso(skb))
-		return xfrm6_output_finish2(skb);
+#ifdef CONFIG_NETFILTER
+	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
+#endif
 
 	skb->protocol = htons(ETH_P_IPV6);
-	segs = skb_gso_segment(skb, 0);
-	kfree_skb(skb);
-	if (unlikely(IS_ERR(segs)))
-		return PTR_ERR(segs);
-
-	do {
-		struct sk_buff *nskb = segs->next;
-		int err;
-
-		segs->next = NULL;
-		err = xfrm6_output_finish2(segs);
-
-		if (unlikely(err)) {
-			while ((segs = nskb)) {
-				nskb = segs->next;
-				segs->next = NULL;
-				kfree_skb(segs);
-			}
-			return err;
-		}
-
-		segs = nskb;
-	} while (segs);
-
-	return 0;
+	return xfrm_output(skb);
 }
 
 int xfrm6_output(struct sk_buff *skb)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 50a3841..6ee0de1 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -253,6 +253,7 @@ static struct dst_ops xfrm6_dst_ops = {
 	.update_pmtu =		xfrm6_update_pmtu,
 	.destroy =		xfrm6_dst_destroy,
 	.ifdown =		xfrm6_dst_ifdown,
+	.local_out =		ip6_local_out,
 	.gc_thresh =		1024,
 	.entry_size =		sizeof(struct xfrm_dst),
 };
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 90fef0a..bb09e85 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -14,6 +14,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <linux/netfilter_ipv6.h>
 #include <net/dsfield.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
@@ -189,6 +190,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.family			= AF_INET6,
 	.proto			= IPPROTO_IPV6,
 	.eth_proto		= htons(ETH_P_IPV6),
+	.nf_post_routing	= NF_IP6_POST_ROUTING,
 	.owner			= THIS_MODULE,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.tmpl_sort		= __xfrm6_tmpl_sort,
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index b1efdc8..bcb3701 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -12,6 +12,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/netfilter.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <net/dst.h>
@@ -40,7 +41,7 @@ err:
 	return err;
 }
 
-int xfrm_output(struct sk_buff *skb)
+static int xfrm_output_one(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
@@ -87,10 +88,73 @@ int xfrm_output(struct sk_buff *skb)
 
 	err = 0;
 
-error_nolock:
+out_exit:
 	return err;
 error:
 	spin_unlock_bh(&x->lock);
-	goto error_nolock;
+error_nolock:
+	kfree_skb(skb);
+	goto out_exit;
+}
+
+static int xfrm_output2(struct sk_buff *skb)
+{
+	int err;
+
+	while (likely((err = xfrm_output_one(skb)) == 0)) {
+		struct xfrm_state *x;
+
+		nf_reset(skb);
+
+		err = skb->dst->ops->local_out(skb);
+		if (unlikely(err != 1))
+			break;
+
+		x = skb->dst->xfrm;
+		if (!x)
+			return dst_output(skb);
+
+		err = nf_hook(x->inner_mode->afinfo->family,
+			      x->inner_mode->afinfo->nf_post_routing, skb,
+			      NULL, skb->dst->dev, xfrm_output2);
+		if (unlikely(err != 1))
+			break;
+	}
+
+	return err;
+}
+
+int xfrm_output(struct sk_buff *skb)
+{
+	struct sk_buff *segs;
+
+	if (!skb_is_gso(skb))
+		return xfrm_output2(skb);
+
+	segs = skb_gso_segment(skb, 0);
+	kfree_skb(skb);
+	if (unlikely(IS_ERR(segs)))
+		return PTR_ERR(segs);
+
+	do {
+		struct sk_buff *nskb = segs->next;
+		int err;
+
+		segs->next = NULL;
+		err = xfrm_output2(segs);
+
+		if (unlikely(err)) {
+			while ((segs = nskb)) {
+				nskb = segs->next;
+				segs->next = NULL;
+				kfree_skb(segs);
+			}
+			return err;
+		}
+
+		segs = nskb;
+	} while (segs);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(xfrm_output);

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

* [PATCH 20/24] [IPSEC]: Add async resume support on output
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (18 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 19/24] [IPSEC]: Merge most of the output path Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:44   ` David Miller
  2007-11-07 14:08 ` [PATCH 21/24] [IPSEC]: Merge most of the input path Herbert Xu
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Add async resume support on output

This patch adds support for async resumptions on output.  To do so, the
transform would return -EINPROGRESS and subsequently invoke the function
xfrm_output_resume to resume processing.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h     |    1 
 net/xfrm/xfrm_output.c |   57 ++++++++++++++++++++++++++++++++++---------------
 2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e674a78..b6c26da 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1119,6 +1119,7 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(struct sk_buff *skb);
 extern int xfrm4_extract_header(struct sk_buff *skb);
 extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index bcb3701..048d240 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -18,6 +18,8 @@
 #include <net/dst.h>
 #include <net/xfrm.h>
 
+static int xfrm_output2(struct sk_buff *skb);
+
 static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
@@ -41,17 +43,13 @@ err:
 	return err;
 }
 
-static int xfrm_output_one(struct sk_buff *skb)
+static int xfrm_output_one(struct sk_buff *skb, int err)
 {
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
-	int err;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		err = skb_checksum_help(skb);
-		if (err)
-			goto error_nolock;
-	}
+	if (err <= 0)
+		goto resume;
 
 	do {
 		err = x->outer_mode->output(x, skb);
@@ -75,6 +73,8 @@ static int xfrm_output_one(struct sk_buff *skb)
 		spin_unlock_bh(&x->lock);
 
 		err = x->type->output(x, skb);
+
+resume:
 		if (err)
 			goto error_nolock;
 
@@ -97,18 +97,16 @@ error_nolock:
 	goto out_exit;
 }
 
-static int xfrm_output2(struct sk_buff *skb)
+int xfrm_output_resume(struct sk_buff *skb, int err)
 {
-	int err;
-
-	while (likely((err = xfrm_output_one(skb)) == 0)) {
+	while (likely((err = xfrm_output_one(skb, err)) == 0)) {
 		struct xfrm_state *x;
 
 		nf_reset(skb);
 
 		err = skb->dst->ops->local_out(skb);
 		if (unlikely(err != 1))
-			break;
+			goto out;
 
 		x = skb->dst->xfrm;
 		if (!x)
@@ -118,18 +116,25 @@ static int xfrm_output2(struct sk_buff *skb)
 			      x->inner_mode->afinfo->nf_post_routing, skb,
 			      NULL, skb->dst->dev, xfrm_output2);
 		if (unlikely(err != 1))
-			break;
+			goto out;
 	}
 
+	if (err == -EINPROGRESS)
+		err = 0;
+
+out:
 	return err;
 }
+EXPORT_SYMBOL_GPL(xfrm_output_resume);
 
-int xfrm_output(struct sk_buff *skb)
+static int xfrm_output2(struct sk_buff *skb)
 {
-	struct sk_buff *segs;
+	return xfrm_output_resume(skb, 1);
+}
 
-	if (!skb_is_gso(skb))
-		return xfrm_output2(skb);
+static int xfrm_output_gso(struct sk_buff *skb)
+{
+	struct sk_buff *segs;
 
 	segs = skb_gso_segment(skb, 0);
 	kfree_skb(skb);
@@ -157,4 +162,22 @@ int xfrm_output(struct sk_buff *skb)
 
 	return 0;
 }
+
+int xfrm_output(struct sk_buff *skb)
+{
+	int err;
+
+	if (skb_is_gso(skb))
+		return xfrm_output_gso(skb);
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		err = skb_checksum_help(skb);
+		if (err) {
+			kfree_skb(skb);
+			return err;
+		}
+	}
+
+	return xfrm_output2(skb);
+}
 EXPORT_SYMBOL_GPL(xfrm_output);

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

* [PATCH 21/24] [IPSEC]: Merge most of the input path
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (19 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 20/24] [IPSEC]: Add async resume support on output Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:44   ` David Miller
  2007-11-07 14:08 ` [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly Herbert Xu
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Merge most of the input path

As part of the work on asynchrnous cryptographic operations, we need to
be able to resume from the spot where they occur.  As such, it helps if
we isolate them to one spot.

This patch moves most of the remaining family-specific processing into
the common input code.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h     |   22 ++++++++
 net/ipv4/xfrm4_input.c |  126 +++++--------------------------------------------
 net/ipv4/xfrm4_state.c |    1 
 net/ipv6/xfrm6_input.c |  118 +++++----------------------------------------
 net/ipv6/xfrm6_state.c |    1 
 net/xfrm/xfrm_input.c  |  113 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 164 insertions(+), 217 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index b6c26da..5c457b0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -274,6 +274,8 @@ struct xfrm_state_afinfo {
 						 struct sk_buff *skb);
 	int			(*extract_output)(struct xfrm_state *x,
 						  struct sk_buff *skb);
+	int			(*transport_finish)(struct sk_buff *skb,
+						    int async);
 };
 
 extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -522,6 +524,22 @@ struct xfrm_mode_skb_cb {
 
 #define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
 
+/*
+ * This structure is used by the input processing to locate the SPI and
+ * related information.
+ */
+struct xfrm_spi_skb_cb {
+	union {
+		struct inet_skb_parm h4;
+		struct inet6_skb_parm h6;
+	} header;
+
+	unsigned int nhoff;
+	unsigned int daddroff;
+};
+
+#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
+
 /* Audit Information */
 struct xfrm_audit
 {
@@ -1119,12 +1137,15 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi,
+		      int encap_type);
 extern int xfrm_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(struct sk_buff *skb);
 extern int xfrm4_extract_header(struct sk_buff *skb);
 extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 			   int encap_type);
+extern int xfrm4_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm4_rcv(struct sk_buff *skb);
 
 static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
@@ -1140,6 +1161,7 @@ extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short f
 extern int xfrm6_extract_header(struct sk_buff *skb);
 extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+extern int xfrm6_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
 			    xfrm_address_t *saddr, u8 proto);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index c0323d0..e374903 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -41,124 +41,26 @@ drop:
 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 		    int encap_type)
 {
-	int err;
-	__be32 seq;
-	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-	struct xfrm_state *x;
-	int xfrm_nr = 0;
-	int decaps = 0;
-	unsigned int nhoff = offsetof(struct iphdr, protocol);
-
-	seq = 0;
-	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
-		goto drop;
-
-	do {
-		const struct iphdr *iph = ip_hdr(skb);
-
-		if (xfrm_nr == XFRM_MAX_DEPTH)
-			goto drop;
-
-		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-				      nexthdr, AF_INET);
-		if (x == NULL)
-			goto drop;
-
-		spin_lock(&x->lock);
-		if (unlikely(x->km.state != XFRM_STATE_VALID))
-			goto drop_unlock;
-
-		if ((x->encap ? x->encap->encap_type : 0) != encap_type)
-			goto drop_unlock;
-
-		if (x->props.replay_window && xfrm_replay_check(x, seq))
-			goto drop_unlock;
-
-		if (xfrm_state_check_expire(x))
-			goto drop_unlock;
-
-		nexthdr = x->type->input(x, skb);
-		if (nexthdr <= 0)
-			goto drop_unlock;
-
-		skb_network_header(skb)[nhoff] = nexthdr;
-
-		/* only the first xfrm gets the encap type */
-		encap_type = 0;
-
-		if (x->props.replay_window)
-			xfrm_replay_advance(x, seq);
-
-		x->curlft.bytes += skb->len;
-		x->curlft.packets++;
-
-		spin_unlock(&x->lock);
-
-		xfrm_vec[xfrm_nr++] = x;
-
-		if (x->inner_mode->input(x, skb))
-			goto drop;
-
-		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-			decaps = 1;
-			break;
-		}
-
-		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
-		if (err < 0)
-			goto drop;
-	} while (!err);
-
-	/* Allocate new secpath or COW existing one. */
-
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = secpath_dup(skb->sp);
-		if (!sp)
-			goto drop;
-		if (skb->sp)
-			secpath_put(skb->sp);
-		skb->sp = sp;
-	}
-	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
-
-	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-	       xfrm_nr * sizeof(xfrm_vec[0]));
-	skb->sp->len += xfrm_nr;
-
-	nf_reset(skb);
+	XFRM_SPI_SKB_CB(skb)->nhoff = offsetof(struct iphdr, protocol);
+	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
+	return xfrm_input(skb, nexthdr, spi, encap_type);
+}
+EXPORT_SYMBOL(xfrm4_rcv_encap);
 
-	if (decaps) {
-		dst_release(skb->dst);
-		skb->dst = NULL;
-		netif_rx(skb);
-		return 0;
-	} else {
+int xfrm4_transport_finish(struct sk_buff *skb, int async)
+{
 #ifdef CONFIG_NETFILTER
-		__skb_push(skb, skb->data - skb_network_header(skb));
-		ip_hdr(skb)->tot_len = htons(skb->len);
-		ip_send_check(ip_hdr(skb));
+	__skb_push(skb, skb->data - skb_network_header(skb));
+	ip_hdr(skb)->tot_len = htons(skb->len);
+	ip_send_check(ip_hdr(skb));
 
-		NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
-			xfrm4_rcv_encap_finish);
-		return 0;
+	NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+		xfrm4_rcv_encap_finish);
+	return 0;
 #else
-		return -ip_hdr(skb)->protocol;
+	return -ip_hdr(skb)->protocol;
 #endif
-	}
-
-drop_unlock:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	while (--xfrm_nr >= 0)
-		xfrm_state_put(xfrm_vec[xfrm_nr]);
-
-	kfree_skb(skb);
-	return 0;
 }
-EXPORT_SYMBOL(xfrm4_rcv_encap);
 
 /* If it's a keepalive packet, then just eat it.
  * If it's an encapsulated packet, then pass it to the
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 80292fb..3b067e8 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -74,6 +74,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.output			= xfrm4_output,
 	.extract_input		= xfrm4_extract_input,
 	.extract_output		= xfrm4_extract_output,
+	.transport_finish	= xfrm4_transport_finish,
 };
 
 void __init xfrm4_state_init(void)
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index c458d0a..3b9eedf 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -23,118 +23,26 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 
 int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 {
-	int err;
-	__be32 seq;
-	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-	struct xfrm_state *x;
-	int xfrm_nr = 0;
-	int decaps = 0;
-	unsigned int nhoff;
-
-	nhoff = IP6CB(skb)->nhoff;
-
-	seq = 0;
-	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
-		goto drop;
-
-	do {
-		struct ipv6hdr *iph = ipv6_hdr(skb);
-
-		if (xfrm_nr == XFRM_MAX_DEPTH)
-			goto drop;
-
-		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-				      nexthdr, AF_INET6);
-		if (x == NULL)
-			goto drop;
-		spin_lock(&x->lock);
-		if (unlikely(x->km.state != XFRM_STATE_VALID))
-			goto drop_unlock;
-
-		if (x->props.replay_window && xfrm_replay_check(x, seq))
-			goto drop_unlock;
-
-		if (xfrm_state_check_expire(x))
-			goto drop_unlock;
-
-		nexthdr = x->type->input(x, skb);
-		if (nexthdr <= 0)
-			goto drop_unlock;
-
-		skb_network_header(skb)[nhoff] = nexthdr;
-
-		if (x->props.replay_window)
-			xfrm_replay_advance(x, seq);
-
-		x->curlft.bytes += skb->len;
-		x->curlft.packets++;
-
-		spin_unlock(&x->lock);
-
-		xfrm_vec[xfrm_nr++] = x;
-
-		if (x->inner_mode->input(x, skb))
-			goto drop;
-
-		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-			decaps = 1;
-			break;
-		}
-
-		if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) < 0)
-			goto drop;
-	} while (!err);
-
-	/* Allocate new secpath or COW existing one. */
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = secpath_dup(skb->sp);
-		if (!sp)
-			goto drop;
-		if (skb->sp)
-			secpath_put(skb->sp);
-		skb->sp = sp;
-	}
-
-	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
-
-	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-	       xfrm_nr * sizeof(xfrm_vec[0]));
-	skb->sp->len += xfrm_nr;
-
-	nf_reset(skb);
+	XFRM_SPI_SKB_CB(skb)->nhoff = IP6CB(skb)->nhoff;
+	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+	return xfrm_input(skb, nexthdr, spi, 0);
+}
+EXPORT_SYMBOL(xfrm6_rcv_spi);
 
-	if (decaps) {
-		dst_release(skb->dst);
-		skb->dst = NULL;
-		netif_rx(skb);
-		return -1;
-	} else {
+int xfrm6_transport_finish(struct sk_buff *skb, int async)
+{
 #ifdef CONFIG_NETFILTER
-		ipv6_hdr(skb)->payload_len = htons(skb->len);
-		__skb_push(skb, skb->data - skb_network_header(skb));
+	ipv6_hdr(skb)->payload_len = htons(skb->len);
+	__skb_push(skb, skb->data - skb_network_header(skb));
 
-		NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
-			ip6_rcv_finish);
-		return -1;
+	NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+		ip6_rcv_finish);
+	return -1;
 #else
-		return 1;
+	return 1;
 #endif
-	}
-
-drop_unlock:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	while (--xfrm_nr >= 0)
-		xfrm_state_put(xfrm_vec[xfrm_nr]);
-	kfree_skb(skb);
-	return -1;
 }
 
-EXPORT_SYMBOL(xfrm6_rcv_spi);
-
 int xfrm6_rcv(struct sk_buff *skb)
 {
 	return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index bb09e85..00360b5 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -198,6 +198,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.output			= xfrm6_output,
 	.extract_input		= xfrm6_extract_input,
 	.extract_output		= xfrm6_extract_output,
+	.transport_finish	= xfrm6_transport_finish,
 };
 
 void __init xfrm6_state_init(void)
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 4c803f7..b980095 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -9,6 +9,8 @@
 
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/dst.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 
@@ -94,6 +96,117 @@ int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(xfrm_prepare_input);
 
+int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+	int err;
+	__be32 seq;
+	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
+	struct xfrm_state *x;
+	int xfrm_nr = 0;
+	int decaps = 0;
+	unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
+	unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
+
+	seq = 0;
+	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
+		goto drop;
+
+	do {
+		if (xfrm_nr == XFRM_MAX_DEPTH)
+			goto drop;
+
+		x = xfrm_state_lookup((xfrm_address_t *)
+				      (skb_network_header(skb) + daddroff),
+				      spi, nexthdr, AF_INET);
+		if (x == NULL)
+			goto drop;
+
+		spin_lock(&x->lock);
+		if (unlikely(x->km.state != XFRM_STATE_VALID))
+			goto drop_unlock;
+
+		if ((x->encap ? x->encap->encap_type : 0) != encap_type)
+			goto drop_unlock;
+
+		if (x->props.replay_window && xfrm_replay_check(x, seq))
+			goto drop_unlock;
+
+		if (xfrm_state_check_expire(x))
+			goto drop_unlock;
+
+		nexthdr = x->type->input(x, skb);
+		if (nexthdr <= 0)
+			goto drop_unlock;
+
+		skb_network_header(skb)[nhoff] = nexthdr;
+
+		/* only the first xfrm gets the encap type */
+		encap_type = 0;
+
+		if (x->props.replay_window)
+			xfrm_replay_advance(x, seq);
+
+		x->curlft.bytes += skb->len;
+		x->curlft.packets++;
+
+		spin_unlock(&x->lock);
+
+		xfrm_vec[xfrm_nr++] = x;
+
+		if (x->inner_mode->input(x, skb))
+			goto drop;
+
+		if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
+			decaps = 1;
+			break;
+		}
+
+		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
+		if (err < 0)
+			goto drop;
+	} while (!err);
+
+	/* Allocate new secpath or COW existing one. */
+
+	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+		struct sec_path *sp;
+		sp = secpath_dup(skb->sp);
+		if (!sp)
+			goto drop;
+		if (skb->sp)
+			secpath_put(skb->sp);
+		skb->sp = sp;
+	}
+	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
+		goto drop;
+
+	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
+	       xfrm_nr * sizeof(xfrm_vec[0]));
+	skb->sp->len += xfrm_nr;
+
+	nf_reset(skb);
+
+	if (decaps) {
+		dst_release(skb->dst);
+		skb->dst = NULL;
+		netif_rx(skb);
+		return 0;
+	} else {
+		return x->inner_mode->afinfo->transport_finish(skb, 0);
+	}
+
+drop_unlock:
+	spin_unlock(&x->lock);
+	xfrm_state_put(x);
+drop:
+	while (--xfrm_nr >= 0)
+		xfrm_state_put(xfrm_vec[xfrm_nr]);
+
+	kfree_skb(skb);
+	return 0;
+}
+EXPORT_SYMBOL(xfrm_input);
+
 void __init xfrm_input_init(void)
 {
 	secpath_cachep = kmem_cache_create("secpath_cache",

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

* [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (20 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 21/24] [IPSEC]: Merge most of the input path Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:45   ` David Miller
  2007-11-07 14:08 ` [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input Herbert Xu
  2007-11-07 14:08 ` [PATCH 24/24] [IPSEC]: Move state lock into x->type->input Herbert Xu
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Store xfrm states in security path directly

As it is xfrm_input first collects a list of xfrm states on the stack
before storing them in the packet's security path just before it returns.
For async crypto, this construction presents an obstacle since we may
need to leave the loop after each transform.

In fact, it's much easier to just skip the stack completely and always
store to the security path.  This is proven by the fact that this patch
actually shrinks the code.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/xfrm/xfrm_input.c |   42 +++++++++++++++---------------------------
 1 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index b980095..587f347 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -100,19 +100,29 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 {
 	int err;
 	__be32 seq;
-	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
 	struct xfrm_state *x;
-	int xfrm_nr = 0;
 	int decaps = 0;
 	unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
 	unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
 
+	/* Allocate new secpath or COW existing one. */
+	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+		struct sec_path *sp;
+
+		sp = secpath_dup(skb->sp);
+		if (!sp)
+			goto drop;
+		if (skb->sp)
+			secpath_put(skb->sp);
+		skb->sp = sp;
+	}
+
 	seq = 0;
 	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
 		goto drop;
 
 	do {
-		if (xfrm_nr == XFRM_MAX_DEPTH)
+		if (skb->sp->len == XFRM_MAX_DEPTH)
 			goto drop;
 
 		x = xfrm_state_lookup((xfrm_address_t *)
@@ -121,6 +131,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		if (x == NULL)
 			goto drop;
 
+		skb->sp->xvec[skb->sp->len++] = x;
+
 		spin_lock(&x->lock);
 		if (unlikely(x->km.state != XFRM_STATE_VALID))
 			goto drop_unlock;
@@ -151,8 +163,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		spin_unlock(&x->lock);
 
-		xfrm_vec[xfrm_nr++] = x;
-
 		if (x->inner_mode->input(x, skb))
 			goto drop;
 
@@ -166,24 +176,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop;
 	} while (!err);
 
-	/* Allocate new secpath or COW existing one. */
-
-	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-		struct sec_path *sp;
-		sp = secpath_dup(skb->sp);
-		if (!sp)
-			goto drop;
-		if (skb->sp)
-			secpath_put(skb->sp);
-		skb->sp = sp;
-	}
-	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-		goto drop;
-
-	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-	       xfrm_nr * sizeof(xfrm_vec[0]));
-	skb->sp->len += xfrm_nr;
-
 	nf_reset(skb);
 
 	if (decaps) {
@@ -197,11 +189,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 drop_unlock:
 	spin_unlock(&x->lock);
-	xfrm_state_put(x);
 drop:
-	while (--xfrm_nr >= 0)
-		xfrm_state_put(xfrm_vec[xfrm_nr]);
-
 	kfree_skb(skb);
 	return 0;
 }

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

* [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (21 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:45   ` David Miller
  2007-11-07 14:08 ` [PATCH 24/24] [IPSEC]: Move state lock into x->type->input Herbert Xu
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Move integrity stat collection into xfrm_input

Similar to the moving out of the replay processing on the output,
this patch moves the integrity stat collectin from x->type->input
into xfrm_input.

This would eventually allow transforms such as AH/ESP to be lockless.

The error value EBADMSG (currently unused in the crypto layer) is used
to indicate a failed integrity check.  In future this error can be
directly returned by the crypto layer once we switch to aead algorithms.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/ah4.c        |    3 +--
 net/ipv4/esp4.c       |   13 ++++++++-----
 net/ipv6/ah6.c        |    3 +--
 net/ipv6/esp6.c       |    3 +--
 net/xfrm/xfrm_input.c |    5 ++++-
 5 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 5fc346d..a989d29 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -177,9 +177,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
 		err = ah_mac_digest(ahp, skb, ah->auth_data);
 		if (err)
 			goto out;
-		err = -EINVAL;
 		if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
-			x->stats.integrity_failed++;
+			err = -EBADMSG;
 			goto out;
 		}
 	}
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index c31bccb..7f1854c 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -162,7 +162,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	u8 nexthdr[2];
 	struct scatterlist *sg;
 	int padlen;
-	int err;
+	int err = -EINVAL;
 
 	if (!pskb_may_pull(skb, sizeof(*esph)))
 		goto out;
@@ -182,13 +182,14 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 			BUG();
 
 		if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-			x->stats.integrity_failed++;
+			err = -EBADMSG;
 			goto out;
 		}
 	}
 
-	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)
+	if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
 		goto out;
+	nfrags = err;
 
 	skb->ip_summed = CHECKSUM_NONE;
 
@@ -201,6 +202,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	sg = &esp->sgbuf[0];
 
 	if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
+		err = -ENOMEM;
 		sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
 		if (!sg)
 			goto out;
@@ -213,11 +215,12 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	if (unlikely(sg != &esp->sgbuf[0]))
 		kfree(sg);
 	if (unlikely(err))
-		return err;
+		goto out;
 
 	if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
 		BUG();
 
+	err = -EINVAL;
 	padlen = nexthdr[0];
 	if (padlen+2 >= elen)
 		goto out;
@@ -271,7 +274,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	return nexthdr[1];
 
 out:
-	return -EINVAL;
+	return err;
 }
 
 static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 4eaf550..d4b59ec 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -379,10 +379,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
 		err = ah_mac_digest(ahp, skb, ah->auth_data);
 		if (err)
 			goto free_out;
-		err = -EINVAL;
 		if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
 			LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
-			x->stats.integrity_failed++;
+			err = -EBADMSG;
 			goto free_out;
 		}
 	}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 7db66f1..c37982b 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -177,8 +177,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 			BUG();
 
 		if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-			x->stats.integrity_failed++;
-			ret = -EINVAL;
+			ret = -EBADMSG;
 			goto out;
 		}
 	}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 587f347..b7d68eb 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -147,8 +147,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop_unlock;
 
 		nexthdr = x->type->input(x, skb);
-		if (nexthdr <= 0)
+		if (nexthdr <= 0) {
+			if (nexthdr == -EBADMSG)
+				x->stats.integrity_failed++;
 			goto drop_unlock;
+		}
 
 		skb_network_header(skb)[nhoff] = nexthdr;
 

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

* [PATCH 24/24] [IPSEC]: Move state lock into x->type->input
  2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
                   ` (22 preceding siblings ...)
  2007-11-07 14:08 ` [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input Herbert Xu
@ 2007-11-07 14:08 ` Herbert Xu
  2007-11-14  5:46   ` David Miller
  23 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-07 14:08 UTC (permalink / raw)
  To: David S. Miller, netdev

[IPSEC]: Move state lock into x->type->input

This patch releases the lock on the state before calling x->type->input.
It also adds the lock to the spots where they're currently needed.

Most of those places (all except mip6) are expected to disappear with
async crypto.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 net/ipv4/ah4.c        |   14 ++++++++++----
 net/ipv4/esp4.c       |   24 +++++++++++++++---------
 net/ipv6/ah6.c        |    9 +++++++--
 net/ipv6/esp6.c       |   37 +++++++++++++++++++++++--------------
 net/ipv6/mip6.c       |   14 ++++++++++----
 net/xfrm/xfrm_input.c |    4 ++++
 6 files changed, 69 insertions(+), 33 deletions(-)

diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index a989d29..d76803a 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -169,6 +169,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
 		if (ip_clear_mutable_options(iph, &dummy))
 			goto out;
 	}
+
+	spin_lock(&x->lock);
 	{
 		u8 auth_data[MAX_AH_AUTH_LEN];
 
@@ -176,12 +178,16 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
 		skb_push(skb, ihl);
 		err = ah_mac_digest(ahp, skb, ah->auth_data);
 		if (err)
-			goto out;
-		if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
+			goto unlock;
+		if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len))
 			err = -EBADMSG;
-			goto out;
-		}
 	}
+unlock:
+	spin_unlock(&x->lock);
+
+	if (err)
+		goto out;
+
 	skb->network_header += ah_hlen;
 	memcpy(skb_network_header(skb), work_buf, ihl);
 	skb->transport_header = skb->network_header;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 7f1854c..de4592c 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -170,29 +170,31 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	if (elen <= 0 || (elen & (blksize-1)))
 		goto out;
 
+	if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+		goto out;
+	nfrags = err;
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	spin_lock(&x->lock);
+
 	/* If integrity check is required, do this. */
 	if (esp->auth.icv_full_len) {
 		u8 sum[alen];
 
 		err = esp_mac_digest(esp, skb, 0, skb->len - alen);
 		if (err)
-			goto out;
+			goto unlock;
 
 		if (skb_copy_bits(skb, skb->len - alen, sum, alen))
 			BUG();
 
 		if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
 			err = -EBADMSG;
-			goto out;
+			goto unlock;
 		}
 	}
 
-	if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
-		goto out;
-	nfrags = err;
-
-	skb->ip_summed = CHECKSUM_NONE;
-
 	esph = (struct ip_esp_hdr *)skb->data;
 
 	/* Get ivec. This can be wrong, check against another impls. */
@@ -205,7 +207,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 		err = -ENOMEM;
 		sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
 		if (!sg)
-			goto out;
+			goto unlock;
 	}
 	sg_init_table(sg, nfrags);
 	skb_to_sgvec(skb, sg,
@@ -214,6 +216,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
 	err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
 	if (unlikely(sg != &esp->sgbuf[0]))
 		kfree(sg);
+
+unlock:
+	spin_unlock(&x->lock);
+
 	if (unlikely(err))
 		goto out;
 
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index d4b59ec..1b51d1e 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -370,6 +370,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
 	ip6h->flow_lbl[2] = 0;
 	ip6h->hop_limit   = 0;
 
+	spin_lock(&x->lock);
 	{
 		u8 auth_data[MAX_AH_AUTH_LEN];
 
@@ -378,13 +379,17 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
 		skb_push(skb, hdr_len);
 		err = ah_mac_digest(ahp, skb, ah->auth_data);
 		if (err)
-			goto free_out;
+			goto unlock;
 		if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
 			LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
 			err = -EBADMSG;
-			goto free_out;
 		}
 	}
+unlock:
+	spin_unlock(&x->lock);
+
+	if (err)
+		goto free_out;
 
 	skb->network_header += ah_hlen;
 	memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index c37982b..bb0e562 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -165,30 +165,32 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 		goto out;
 	}
 
+	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	spin_lock(&x->lock);
+
 	/* If integrity check is required, do this. */
 	if (esp->auth.icv_full_len) {
 		u8 sum[alen];
 
 		ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
 		if (ret)
-			goto out;
+			goto unlock;
 
 		if (skb_copy_bits(skb, skb->len - alen, sum, alen))
 			BUG();
 
 		if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
 			ret = -EBADMSG;
-			goto out;
+			goto unlock;
 		}
 	}
 
-	if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	skb->ip_summed = CHECKSUM_NONE;
-
 	esph = (struct ip_esp_hdr *)skb->data;
 	iph = ipv6_hdr(skb);
 
@@ -197,15 +199,13 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 		crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
 
 	{
-		u8 nexthdr[2];
 		struct scatterlist *sg = &esp->sgbuf[0];
-		u8 padlen;
 
 		if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
 			sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
 			if (!sg) {
 				ret = -ENOMEM;
-				goto out;
+				goto unlock;
 			}
 		}
 		sg_init_table(sg, nfrags);
@@ -215,8 +215,17 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
 		ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
 		if (unlikely(sg != &esp->sgbuf[0]))
 			kfree(sg);
-		if (unlikely(ret))
-			goto out;
+	}
+
+unlock:
+	spin_unlock(&x->lock);
+
+	if (unlikely(ret))
+		goto out;
+
+	{
+		u8 nexthdr[2];
+		u8 padlen;
 
 		if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
 			BUG();
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index edfd9cd..49d3966 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -128,12 +128,15 @@ static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct ipv6hdr *iph = ipv6_hdr(skb);
 	struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
+	int err = destopt->nexthdr;
 
+	spin_lock(&x->lock);
 	if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
 	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
-		return -ENOENT;
+		err = -ENOENT;
+	spin_unlock(&x->lock);
 
-	return destopt->nexthdr;
+	return err;
 }
 
 /* Destination Option Header is inserted.
@@ -344,12 +347,15 @@ static struct xfrm_type mip6_destopt_type =
 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 	struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
+	int err = rt2->rt_hdr.nexthdr;
 
+	spin_lock(&x->lock);
 	if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
 	    !ipv6_addr_any((struct in6_addr *)x->coaddr))
-		return -ENOENT;
+		err = -ENOENT;
+	spin_unlock(&x->lock);
 
-	return rt2->rt_hdr.nexthdr;
+	return err;
 }
 
 /* Routing Header type 2 is inserted.
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index b7d68eb..5cad522 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -146,7 +146,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		if (xfrm_state_check_expire(x))
 			goto drop_unlock;
 
+		spin_unlock(&x->lock);
+
 		nexthdr = x->type->input(x, skb);
+
+		spin_lock(&x->lock);
 		if (nexthdr <= 0) {
 			if (nexthdr == -EBADMSG)
 				x->stats.integrity_failed++;

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-07 14:08 ` [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section Herbert Xu
@ 2007-11-07 16:17   ` Ingo Oeser
  2007-11-08  0:39     ` Herbert Xu
  2007-11-14  5:39   ` David Miller
  1 sibling, 1 reply; 71+ messages in thread
From: Ingo Oeser @ 2007-11-07 16:17 UTC (permalink / raw)
  To: Herbert Xu; +Cc: David S. Miller, netdev

Hi Herbert,

Herbert Xu schrieb:
> diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
> index a7bc8c6..4a01cb3 100644
> --- a/net/ipv6/xfrm6_mode_ro.c
> +++ b/net/ipv6/xfrm6_mode_ro.c
> @@ -53,7 +54,9 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
>  	__skb_pull(skb, hdr_len);
>  	memmove(ipv6_hdr(skb), iph, hdr_len);
>  
> +	spin_lock_bh(&x->lock);
>  	x->lastused = get_seconds();
> +	spin_unlock_bh(&x->lock);
>  
>  	return 0;
>  }

Can you move the retrieval of the seconds outside the spinlock?

e.g.

tmp = get_seconds();
spin_lock_bh(&x->lock);
x->lastused = tmp;
spin_unlock_bh(&x->lock);

or is it not really worth it?

Best Regards

Ingo Oeser

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-07 16:17   ` Ingo Oeser
@ 2007-11-08  0:39     ` Herbert Xu
  2007-11-13 11:33       ` David Miller
  0 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-08  0:39 UTC (permalink / raw)
  To: Ingo Oeser; +Cc: David S. Miller, netdev

On Wed, Nov 07, 2007 at 05:17:42PM +0100, Ingo Oeser wrote:
> Hi Herbert,
> 
> Herbert Xu schrieb:
> > diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
> > index a7bc8c6..4a01cb3 100644
> > --- a/net/ipv6/xfrm6_mode_ro.c
> > +++ b/net/ipv6/xfrm6_mode_ro.c
> > @@ -53,7 +54,9 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
> >  	__skb_pull(skb, hdr_len);
> >  	memmove(ipv6_hdr(skb), iph, hdr_len);
> >  
> > +	spin_lock_bh(&x->lock);
> >  	x->lastused = get_seconds();
> > +	spin_unlock_bh(&x->lock);
> >  
> >  	return 0;
> >  }
> 
> Can you move the retrieval of the seconds outside the spinlock?

You certainly could.  Whether it's worth it I won't speculate :)

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-07 14:08 ` [PATCH 19/24] [IPSEC]: Merge most of the output path Herbert Xu
@ 2007-11-08 11:23   ` Patrick McHardy
  2007-11-08 11:29     ` Herbert Xu
  2007-11-14  5:43   ` David Miller
  1 sibling, 1 reply; 71+ messages in thread
From: Patrick McHardy @ 2007-11-08 11:23 UTC (permalink / raw)
  To: Herbert Xu; +Cc: David S. Miller, netdev

[-- Attachment #1: Type: text/plain, Size: 910 bytes --]

Herbert Xu wrote:
> [IPSEC]: Merge most of the output path
> 
> As part of the work on asynchrnous cryptographic operations, we need to
> be able to resume from the spot where they occur.  As such, it helps if
> we isolate them to one spot.
> 
> This patch moves most of the remaining family-specific processing into
> the common output code.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> ---
> 
>  include/net/dst.h       |    1 
> @@ -66,6 +67,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
>  	.family			= AF_INET,
>  	.proto			= IPPROTO_IPIP,
>  	.eth_proto		= htons(ETH_P_IP),
> +	.nf_post_routing	= NF_IP_POST_ROUTING,


We have a few places that go though the trouble of selecting the
"correct" hook value for the address family, even though the numerical
values are identical. How about we just get rid of the different
naming and use NF_INET_... for both IPv4 and IPv6?


[-- Attachment #2: x --]
[-- Type: text/plain, Size: 90309 bytes --]

[NETFILTER]: Introduce NF_INET_ hook values

The IPv4 and IPv6 hook values are identical, yet some code tries to figure
out the "correct" value by looking at the address family. Introduce NF_INET_*
values for both IPv4 and IPv6. The old values are kept in a #ifndef __KERNEL__
section for userspace compatibility.

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

---
commit 0c0a9878960e19a0ce8fe56e616c6f55799a2538
tree d7fc8398f685b44de23914d4c6a48a2f53646a7a
parent d79d569958a561da92975784ab7afc8440c96007
author Patrick McHardy <kaber@trash.net> Thu, 08 Nov 2007 12:22:30 +0100
committer Patrick McHardy <kaber@trash.net> Thu, 08 Nov 2007 12:22:30 +0100

 include/linux/netfilter.h                      |    9 +++++
 include/linux/netfilter/x_tables.h             |    4 +-
 include/linux/netfilter_ipv4.h                 |    2 +
 include/linux/netfilter_ipv4/ip_tables.h       |    8 ++--
 include/linux/netfilter_ipv6.h                 |    3 +-
 include/linux/netfilter_ipv6/ip6_tables.h      |    8 ++--
 include/net/ipip.h                             |    2 +
 include/net/netfilter/nf_nat.h                 |    3 +-
 net/bridge/br_netfilter.c                      |   12 +++----
 net/compat.c                                   |    6 ++-
 net/ipv4/igmp.c                                |    4 +-
 net/ipv4/ip_forward.c                          |    2 +
 net/ipv4/ip_input.c                            |    4 +-
 net/ipv4/ip_output.c                           |   16 ++++-----
 net/ipv4/ipmr.c                                |    2 +
 net/ipv4/ipvs/ip_vs_core.c                     |   18 +++++-----
 net/ipv4/ipvs/ip_vs_xmit.c                     |    2 +
 net/ipv4/netfilter.c                           |    8 ++--
 net/ipv4/netfilter/ip_tables.c                 |   44 ++++++++++++------------
 net/ipv4/netfilter/ipt_MASQUERADE.c            |    4 +-
 net/ipv4/netfilter/ipt_NETMAP.c                |   13 ++++---
 net/ipv4/netfilter/ipt_REDIRECT.c              |    8 ++--
 net/ipv4/netfilter/ipt_REJECT.c                |    8 ++--
 net/ipv4/netfilter/ipt_SAME.c                  |    7 ++--
 net/ipv4/netfilter/ipt_owner.c                 |    3 +-
 net/ipv4/netfilter/iptable_filter.c            |   22 +++++++-----
 net/ipv4/netfilter/iptable_mangle.c            |   40 +++++++++++-----------
 net/ipv4/netfilter/iptable_raw.c               |   14 ++++----
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |   18 +++++-----
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |    2 +
 net/ipv4/netfilter/nf_nat_core.c               |   14 ++++----
 net/ipv4/netfilter/nf_nat_h323.c               |    8 ++--
 net/ipv4/netfilter/nf_nat_helper.c             |    4 +-
 net/ipv4/netfilter/nf_nat_pptp.c               |    4 +-
 net/ipv4/netfilter/nf_nat_rule.c               |   28 ++++++++-------
 net/ipv4/netfilter/nf_nat_sip.c                |    4 +-
 net/ipv4/netfilter/nf_nat_standalone.c         |   14 ++++----
 net/ipv4/raw.c                                 |    2 +
 net/ipv4/xfrm4_input.c                         |    2 +
 net/ipv4/xfrm4_output.c                        |    8 ++--
 net/ipv6/ip6_input.c                           |    6 ++-
 net/ipv6/ip6_output.c                          |   15 +++++---
 net/ipv6/ip6_tunnel.c                          |    2 +
 net/ipv6/mcast.c                               |    6 ++-
 net/ipv6/ndisc.c                               |    6 ++-
 net/ipv6/netfilter.c                           |    6 ++-
 net/ipv6/netfilter/ip6_tables.c                |   26 +++++++-------
 net/ipv6/netfilter/ip6t_REJECT.c               |    8 ++--
 net/ipv6/netfilter/ip6t_eui64.c                |    4 +-
 net/ipv6/netfilter/ip6t_owner.c                |    3 +-
 net/ipv6/netfilter/ip6table_filter.c           |   22 +++++++-----
 net/ipv6/netfilter/ip6table_mangle.c           |   40 +++++++++++-----------
 net/ipv6/netfilter/ip6table_raw.c              |   14 ++++----
 net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c |   12 +++----
 net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c |    2 +
 net/ipv6/raw.c                                 |    2 +
 net/ipv6/xfrm6_input.c                         |    2 +
 net/ipv6/xfrm6_output.c                        |    6 ++-
 net/netfilter/nf_conntrack_netlink.c           |    8 ++--
 net/netfilter/nf_conntrack_proto_tcp.c         |    4 +-
 net/netfilter/nf_conntrack_proto_udp.c         |    4 +-
 net/netfilter/nf_conntrack_proto_udplite.c     |    3 +-
 net/netfilter/xt_CLASSIFY.c                    |   12 +++----
 net/netfilter/xt_TCPMSS.c                      |   12 +++----
 net/netfilter/xt_mac.c                         |   12 +++----
 net/netfilter/xt_physdev.c                     |    6 ++-
 net/netfilter/xt_policy.c                      |    5 +--
 net/netfilter/xt_realm.c                       |    4 +-
 net/sched/sch_ingress.c                        |    4 +-
 security/selinux/hooks.c                       |    4 +-
 70 files changed, 332 insertions(+), 312 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 16adac6..25fc122 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -39,6 +39,15 @@
 #define NFC_ALTERED 0x8000
 #endif
 
+enum nf_inet_hooks {
+	NF_INET_PRE_ROUTING,
+	NF_INET_LOCAL_IN,
+	NF_INET_FORWARD,
+	NF_INET_LOCAL_OUT,
+	NF_INET_POST_ROUTING,
+	NF_INET_NUMHOOKS
+};
+
 #ifdef __KERNEL__
 #ifdef CONFIG_NETFILTER
 
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 03e6ce9..9657c4e 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -265,8 +265,8 @@ struct xt_table_info
 	unsigned int initial_entries;
 
 	/* Entry points and underflows */
-	unsigned int hook_entry[NF_IP_NUMHOOKS];
-	unsigned int underflow[NF_IP_NUMHOOKS];
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+	unsigned int underflow[NF_INET_NUMHOOKS];
 
 	/* ipt_entry tables: one per CPU */
 	char *entries[NR_CPUS];
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index 1a63adf..9a10092 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -36,7 +36,6 @@
 #define NFC_IP_DST_PT		0x0400
 /* Something else about the proto */
 #define NFC_IP_PROTO_UNKNOWN	0x2000
-#endif /* ! __KERNEL__ */
 
 /* IP Hooks */
 /* After promisc drops, checksum checks. */
@@ -50,6 +49,7 @@
 /* Packets about to hit the wire. */
 #define NF_IP_POST_ROUTING	4
 #define NF_IP_NUMHOOKS		5
+#endif /* ! __KERNEL__ */
 
 enum nf_ip_hook_priorities {
 	NF_IP_PRI_FIRST = INT_MIN,
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index d79ed69..54da616 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -156,10 +156,10 @@ struct ipt_getinfo
 	unsigned int valid_hooks;
 
 	/* Hook entry points: one per netfilter hook. */
-	unsigned int hook_entry[NF_IP_NUMHOOKS];
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
 
 	/* Underflow points. */
-	unsigned int underflow[NF_IP_NUMHOOKS];
+	unsigned int underflow[NF_INET_NUMHOOKS];
 
 	/* Number of entries */
 	unsigned int num_entries;
@@ -185,10 +185,10 @@ struct ipt_replace
 	unsigned int size;
 
 	/* Hook entry points. */
-	unsigned int hook_entry[NF_IP_NUMHOOKS];
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
 
 	/* Underflow points. */
-	unsigned int underflow[NF_IP_NUMHOOKS];
+	unsigned int underflow[NF_INET_NUMHOOKS];
 
 	/* Information about old entries: */
 	/* Number of counters (must be equal to current number of entries). */
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index 66ca8e3..3475a65 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -40,8 +40,6 @@
 #define NFC_IP6_DST_PT           0x0400
 /* Something else about the proto */
 #define NFC_IP6_PROTO_UNKNOWN    0x2000
-#endif /* ! __KERNEL__ */
-
 
 /* IP6 Hooks */
 /* After promisc drops, checksum checks. */
@@ -55,6 +53,7 @@
 /* Packets about to hit the wire. */
 #define NF_IP6_POST_ROUTING	4
 #define NF_IP6_NUMHOOKS		5
+#endif /* ! __KERNEL__ */
 
 
 enum nf_ip6_hook_priorities {
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 7dc481c..2e98654 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -216,10 +216,10 @@ struct ip6t_getinfo
 	unsigned int valid_hooks;
 
 	/* Hook entry points: one per netfilter hook. */
-	unsigned int hook_entry[NF_IP6_NUMHOOKS];
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
 
 	/* Underflow points. */
-	unsigned int underflow[NF_IP6_NUMHOOKS];
+	unsigned int underflow[NF_INET_NUMHOOKS];
 
 	/* Number of entries */
 	unsigned int num_entries;
@@ -245,10 +245,10 @@ struct ip6t_replace
 	unsigned int size;
 
 	/* Hook entry points. */
-	unsigned int hook_entry[NF_IP6_NUMHOOKS];
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
 
 	/* Underflow points. */
-	unsigned int underflow[NF_IP6_NUMHOOKS];
+	unsigned int underflow[NF_INET_NUMHOOKS];
 
 	/* Information about old entries: */
 	/* Number of counters (must be equal to current number of entries). */
diff --git a/include/net/ipip.h b/include/net/ipip.h
index 7cdc914..27a32a8 100644
--- a/include/net/ipip.h
+++ b/include/net/ipip.h
@@ -34,7 +34,7 @@ struct ip_tunnel
 	ip_select_ident(iph, &rt->u.dst, NULL);				\
 	ip_send_check(iph);						\
 									\
-	err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
+	err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
 	if (net_xmit_eval(err) == 0) {					\
 		stats->tx_bytes += pkt_len;				\
 		stats->tx_packets++;					\
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 6ae52f7..76da322 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -12,7 +12,8 @@ enum nf_nat_manip_type
 };
 
 /* SRC manip occurs POST_ROUTING or LOCAL_IN */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
+#define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \
+			     (hooknum) != NF_INET_LOCAL_IN)
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index da22f90..f941aab 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -488,7 +488,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
 	if (!setup_pre_routing(skb))
 		return NF_DROP;
 
-	NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+	NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
 		br_nf_pre_routing_finish_ipv6);
 
 	return NF_STOLEN;
@@ -561,7 +561,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
 		return NF_DROP;
 	store_orig_dstaddr(skb);
 
-	NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+	NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
 		br_nf_pre_routing_finish);
 
 	return NF_STOLEN;
@@ -653,7 +653,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
 	nf_bridge->mask |= BRNF_BRIDGED;
 	nf_bridge->physoutdev = skb->dev;
 
-	NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), parent,
+	NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
 		br_nf_forward_finish);
 
 	return NF_STOLEN;
@@ -796,7 +796,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
 	if (nf_bridge->netoutdev)
 		realoutdev = nf_bridge->netoutdev;
 #endif
-	NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
+	NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
 		br_nf_dev_queue_xmit);
 
 	return NF_STOLEN;
@@ -869,12 +869,12 @@ static struct nf_hook_ops br_nf_ops[] = {
 	{ .hook = ip_sabotage_in,
 	  .owner = THIS_MODULE,
 	  .pf = PF_INET,
-	  .hooknum = NF_IP_PRE_ROUTING,
+	  .hooknum = NF_INET_PRE_ROUTING,
 	  .priority = NF_IP_PRI_FIRST, },
 	{ .hook = ip_sabotage_in,
 	  .owner = THIS_MODULE,
 	  .pf = PF_INET6,
-	  .hooknum = NF_IP6_PRE_ROUTING,
+	  .hooknum = NF_INET_PRE_ROUTING,
 	  .priority = NF_IP6_PRI_FIRST, },
 };
 
diff --git a/net/compat.c b/net/compat.c
index d74d821..b599cf1 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -323,8 +323,8 @@ struct compat_ipt_replace {
 	u32			valid_hooks;
 	u32			num_entries;
 	u32			size;
-	u32			hook_entry[NF_IP_NUMHOOKS];
-	u32			underflow[NF_IP_NUMHOOKS];
+	u32			hook_entry[NF_INET_NUMHOOKS];
+	u32			underflow[NF_INET_NUMHOOKS];
 	u32			num_counters;
 	compat_uptr_t		counters;	/* struct ipt_counters * */
 	struct ipt_entry	entries[0];
@@ -389,7 +389,7 @@ static int do_netfilter_replace(int fd, int level, int optname,
 			   origsize))
 		goto out;
 
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		if (__get_user(tmp32, &urepl->hook_entry[i]) ||
 		    __put_user(tmp32, &repl_nat->hook_entry[i]) ||
 		    __get_user(tmp32, &urepl->underflow[i]) ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 7dbc282..d1733f4 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -358,7 +358,7 @@ static int igmpv3_sendpack(struct sk_buff *skb)
 	ip_send_check(pip);
 	pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
+	return NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
 		       dst_output);
 }
 
@@ -695,7 +695,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
 	ih->group=group;
 	ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+	return NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		       dst_output);
 }
 
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 877da3e..0b3b328 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -110,7 +110,7 @@ int ip_forward(struct sk_buff *skb)
 
 	skb->priority = rt_tos2priority(iph->tos);
 
-	return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
+	return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev,
 		       ip_forward_finish);
 
 sr_failed:
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 168c871..5b8a760 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -268,7 +268,7 @@ int ip_local_deliver(struct sk_buff *skb)
 			return 0;
 	}
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
+	return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
 		       ip_local_deliver_finish);
 }
 
@@ -442,7 +442,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
 	/* Remove any debris in the socket control block */
 	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
-	return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
+	return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL,
 		       ip_rcv_finish);
 
 inhdr_error:
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e5f7dc2..3305c56 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -150,7 +150,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
 	skb->priority = sk->sk_priority;
 
 	/* Send it out. */
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+	return NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		       dst_output);
 }
 
@@ -251,8 +251,8 @@ int ip_mc_output(struct sk_buff *skb)
 		) {
 			struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 			if (newskb)
-				NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
-					newskb->dev,
+				NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb,
+					NULL, newskb->dev,
 					ip_dev_loopback_xmit);
 		}
 
@@ -267,11 +267,11 @@ int ip_mc_output(struct sk_buff *skb)
 	if (rt->rt_flags&RTCF_BROADCAST) {
 		struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
 		if (newskb)
-			NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
+			NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL,
 				newskb->dev, ip_dev_loopback_xmit);
 	}
 
-	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+	return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
 			    ip_finish_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
@@ -285,7 +285,7 @@ int ip_output(struct sk_buff *skb)
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_IP);
 
-	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+	return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev,
 			    ip_finish_output,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
@@ -371,7 +371,7 @@ packet_routed:
 
 	skb->priority = sk->sk_priority;
 
-	return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+	return NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		       dst_output);
 
 no_route:
@@ -1266,7 +1266,7 @@ int ip_push_pending_frames(struct sock *sk)
 			skb_transport_header(skb))->type);
 
 	/* Netfilter gets whole the not fragmented skb. */
-	err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
+	err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL,
 		      skb->dst->dev, dst_output);
 	if (err) {
 		if (err > 0)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 37bb497..7c1bd0c 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1245,7 +1245,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
 	 * not mrouter) cannot join to more than one interface - it will
 	 * result in receiving multiple packets.
 	 */
-	NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev,
+	NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev,
 		ipmr_forward_finish);
 	return;
 
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index c6ed765..e2c883f 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -481,7 +481,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
 
 
 /*
- *      It is hooked before NF_IP_PRI_NAT_SRC at the NF_IP_POST_ROUTING
+ *      It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING
  *      chain, and is used for VS/NAT.
  *      It detects packets for VS/NAT connections and sends the packets
  *      immediately. This can avoid that iptable_nat mangles the packets
@@ -679,7 +679,7 @@ static inline int is_tcp_reset(const struct sk_buff *skb)
 }
 
 /*
- *	It is hooked at the NF_IP_FORWARD chain, used only for VS/NAT.
+ *	It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT.
  *	Check if outgoing packet belongs to the established ip_vs_conn,
  *      rewrite addresses of the packet and send it on its way...
  */
@@ -814,7 +814,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
 
 	/* reassemble IP fragments */
 	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-		if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
+		if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ?
 					    IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
 			return NF_STOLEN;
 	}
@@ -995,12 +995,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 
 
 /*
- *	It is hooked at the NF_IP_FORWARD chain, in order to catch ICMP
+ *	It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP
  *      related packets destined for 0.0.0.0/0.
  *      When fwmark-based virtual service is used, such as transparent
  *      cache cluster, TCP packets can be marked and routed to ip_vs_in,
  *      but ICMP destined for 0.0.0.0/0 cannot not be easily marked and
- *      sent to ip_vs_in_icmp. So, catch them at the NF_IP_FORWARD chain
+ *      sent to ip_vs_in_icmp. So, catch them at the NF_INET_FORWARD chain
  *      and send them to ip_vs_in_icmp.
  */
 static unsigned int
@@ -1024,7 +1024,7 @@ static struct nf_hook_ops ip_vs_in_ops = {
 	.hook		= ip_vs_in,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
-	.hooknum        = NF_IP_LOCAL_IN,
+	.hooknum        = NF_INET_LOCAL_IN,
 	.priority       = 100,
 };
 
@@ -1033,7 +1033,7 @@ static struct nf_hook_ops ip_vs_out_ops = {
 	.hook		= ip_vs_out,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
-	.hooknum        = NF_IP_FORWARD,
+	.hooknum        = NF_INET_FORWARD,
 	.priority       = 100,
 };
 
@@ -1043,7 +1043,7 @@ static struct nf_hook_ops ip_vs_forward_icmp_ops = {
 	.hook		= ip_vs_forward_icmp,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
-	.hooknum        = NF_IP_FORWARD,
+	.hooknum        = NF_INET_FORWARD,
 	.priority       = 99,
 };
 
@@ -1052,7 +1052,7 @@ static struct nf_hook_ops ip_vs_post_routing_ops = {
 	.hook		= ip_vs_post_routing,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
-	.hooknum        = NF_IP_POST_ROUTING,
+	.hooknum        = NF_INET_POST_ROUTING,
 	.priority       = NF_IP_PRI_NAT_SRC-1,
 };
 
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 7c074e3..526e48e 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -129,7 +129,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
 do {							\
 	(skb)->ipvs_property = 1;			\
 	skb_forward_csum(skb);				\
-	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL,	\
+	NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, (skb), NULL,	\
 		(rt)->u.dst.dev, dst_output);		\
 } while (0)
 
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 5539deb..d902246 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -23,7 +23,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 		addr_type = type;
 
 	/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
-	 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
+	 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
 	 */
 	if (addr_type == RTN_LOCAL) {
 		fl.nl_u.ip4_u.daddr = iph->daddr;
@@ -126,7 +126,7 @@ static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info)
 {
 	struct ip_rt_info *rt_info = nf_info_reroute(info);
 
-	if (info->hook == NF_IP_LOCAL_OUT) {
+	if (info->hook == NF_INET_LOCAL_OUT) {
 		const struct iphdr *iph = ip_hdr(skb);
 
 		rt_info->tos = iph->tos;
@@ -139,7 +139,7 @@ static int nf_ip_reroute(struct sk_buff *skb, const struct nf_info *info)
 {
 	const struct ip_rt_info *rt_info = nf_info_reroute(info);
 
-	if (info->hook == NF_IP_LOCAL_OUT) {
+	if (info->hook == NF_INET_LOCAL_OUT) {
 		const struct iphdr *iph = ip_hdr(skb);
 
 		if (!(iph->tos == rt_info->tos
@@ -158,7 +158,7 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
 
 	switch (skb->ip_summed) {
 	case CHECKSUM_COMPLETE:
-		if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN)
+		if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
 			break;
 		if ((protocol == 0 && !csum_fold(skb->csum)) ||
 		    !csum_tcpudp_magic(iph->saddr, iph->daddr,
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4b10b98..a99fe89 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -220,11 +220,11 @@ unconditional(const struct ipt_ip *ip)
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
 static const char *hooknames[] = {
-	[NF_IP_PRE_ROUTING]		= "PREROUTING",
-	[NF_IP_LOCAL_IN]		= "INPUT",
-	[NF_IP_FORWARD]			= "FORWARD",
-	[NF_IP_LOCAL_OUT]		= "OUTPUT",
-	[NF_IP_POST_ROUTING]		= "POSTROUTING",
+	[NF_INET_PRE_ROUTING]		= "PREROUTING",
+	[NF_INET_LOCAL_IN]		= "INPUT",
+	[NF_INET_FORWARD]			= "FORWARD",
+	[NF_INET_LOCAL_OUT]		= "OUTPUT",
+	[NF_INET_POST_ROUTING]		= "POSTROUTING",
 };
 
 enum nf_ip_trace_comments {
@@ -465,7 +465,7 @@ mark_source_chains(struct xt_table_info *newinfo,
 
 	/* No recursion; use packet counter to save back ptrs (reset
 	   to 0 as we leave), and comefrom to save source hook bitmask */
-	for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
+	for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ipt_entry *e
 			= (struct ipt_entry *)(entry0 + pos);
@@ -481,13 +481,13 @@ mark_source_chains(struct xt_table_info *newinfo,
 				= (void *)ipt_get_target(e);
 			int visited = e->comefrom & (1 << hook);
 
-			if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
+			if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
 				printk("iptables: loop hook %u pos %u %08X.\n",
 				       hook, pos, e->comefrom);
 				return 0;
 			}
 			e->comefrom
-				|= ((1 << hook) | (1 << NF_IP_NUMHOOKS));
+				|= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
 			/* Unconditional return/END. */
 			if ((e->target_offset == sizeof(struct ipt_entry)
@@ -507,10 +507,10 @@ mark_source_chains(struct xt_table_info *newinfo,
 				/* Return: backtrack through the last
 				   big jump. */
 				do {
-					e->comefrom ^= (1<<NF_IP_NUMHOOKS);
+					e->comefrom ^= (1<<NF_INET_NUMHOOKS);
 #ifdef DEBUG_IP_FIREWALL_USER
 					if (e->comefrom
-					    & (1 << NF_IP_NUMHOOKS)) {
+					    & (1 << NF_INET_NUMHOOKS)) {
 						duprintf("Back unset "
 							 "on hook %u "
 							 "rule %u\n",
@@ -741,7 +741,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 	}
 
 	/* Check hooks & underflows */
-	for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h])
@@ -795,7 +795,7 @@ translate_table(const char *name,
 	newinfo->number = number;
 
 	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = 0xFFFFFFFF;
 		newinfo->underflow[i] = 0xFFFFFFFF;
 	}
@@ -819,7 +819,7 @@ translate_table(const char *name,
 	}
 
 	/* Check hooks all assigned */
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
 		if (!(valid_hooks & (1 << i)))
 			continue;
@@ -1107,7 +1107,7 @@ static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info,
 	if (ret)
 		return ret;
 
-	for (i = 0; i< NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		if (info->hook_entry[i] && (e < (struct ipt_entry *)
 				(base + info->hook_entry[i])))
 			newinfo->hook_entry[i] -= off;
@@ -1130,7 +1130,7 @@ static int compat_table_info(struct xt_table_info *info,
 	memset(newinfo, 0, sizeof(struct xt_table_info));
 	newinfo->size = info->size;
 	newinfo->number = info->number;
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = info->hook_entry[i];
 		newinfo->underflow[i] = info->underflow[i];
 	}
@@ -1479,8 +1479,8 @@ struct compat_ipt_replace {
 	u32			valid_hooks;
 	u32			num_entries;
 	u32			size;
-	u32			hook_entry[NF_IP_NUMHOOKS];
-	u32			underflow[NF_IP_NUMHOOKS];
+	u32			hook_entry[NF_INET_NUMHOOKS];
+	u32			underflow[NF_INET_NUMHOOKS];
 	u32			num_counters;
 	compat_uptr_t		counters;	/* struct ipt_counters * */
 	struct compat_ipt_entry	entries[0];
@@ -1638,7 +1638,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 		goto out;
 
 	/* Check hooks & underflows */
-	for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h])
@@ -1693,7 +1693,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
 	xt_compat_target_from_user(t, dstptr, size);
 
 	de->next_offset = e->next_offset - (origsize - *size);
-	for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)de - base < newinfo->hook_entry[h])
 			newinfo->hook_entry[h] -= origsize - *size;
 		if ((unsigned char *)de - base < newinfo->underflow[h])
@@ -1746,7 +1746,7 @@ translate_compat_table(const char *name,
 	info->number = number;
 
 	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		info->hook_entry[i] = 0xFFFFFFFF;
 		info->underflow[i] = 0xFFFFFFFF;
 	}
@@ -1771,7 +1771,7 @@ translate_compat_table(const char *name,
 	}
 
 	/* Check hooks all assigned */
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
 		if (!(valid_hooks & (1 << i)))
 			continue;
@@ -1793,7 +1793,7 @@ translate_compat_table(const char *name,
 		goto out_unlock;
 
 	newinfo->number = number;
-	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = info->hook_entry[i];
 		newinfo->underflow[i] = info->underflow[i];
 	}
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 44b516e..5a18997 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -67,7 +67,7 @@ masquerade_target(struct sk_buff *skb,
 	const struct rtable *rt;
 	__be32 newsrc;
 
-	NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
+	NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
 
 	ct = nf_ct_get(skb, &ctinfo);
 	nat = nfct_nat(ct);
@@ -172,7 +172,7 @@ static struct xt_target masquerade __read_mostly = {
 	.target		= masquerade_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
-	.hooks		= 1 << NF_IP_POST_ROUTING,
+	.hooks		= 1 << NF_INET_POST_ROUTING,
 	.checkentry	= masquerade_check,
 	.me		= THIS_MODULE,
 };
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index f869929..973bbee 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -56,14 +56,14 @@ target(struct sk_buff *skb,
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 	struct nf_nat_range newrange;
 
-	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
-		     || hooknum == NF_IP_POST_ROUTING
-		     || hooknum == NF_IP_LOCAL_OUT);
+	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
+		     || hooknum == NF_INET_POST_ROUTING
+		     || hooknum == NF_INET_LOCAL_OUT);
 	ct = nf_ct_get(skb, &ctinfo);
 
 	netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
 
-	if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT)
+	if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT)
 		new_ip = ip_hdr(skb)->daddr & ~netmask;
 	else
 		new_ip = ip_hdr(skb)->saddr & ~netmask;
@@ -84,8 +84,9 @@ static struct xt_target target_module __read_mostly = {
 	.target 	= target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
-	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) |
-			  (1 << NF_IP_LOCAL_OUT),
+	.hooks		= (1 << NF_INET_PRE_ROUTING) |
+			  (1 << NF_INET_POST_ROUTING) |
+			  (1 << NF_INET_LOCAL_OUT),
 	.checkentry 	= check,
 	.me 		= THIS_MODULE
 };
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index f7cf7d6..4757af2 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -60,14 +60,14 @@ redirect_target(struct sk_buff *skb,
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 	struct nf_nat_range newrange;
 
-	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
-		     || hooknum == NF_IP_LOCAL_OUT);
+	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
+		     || hooknum == NF_INET_LOCAL_OUT);
 
 	ct = nf_ct_get(skb, &ctinfo);
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
 	/* Local packets: make them go to loopback */
-	if (hooknum == NF_IP_LOCAL_OUT)
+	if (hooknum == NF_INET_LOCAL_OUT)
 		newdst = htonl(0x7F000001);
 	else {
 		struct in_device *indev;
@@ -101,7 +101,7 @@ static struct xt_target redirect_reg __read_mostly = {
 	.target		= redirect_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
-	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
+	.hooks		= (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
 	.checkentry	= redirect_check,
 	.me		= THIS_MODULE,
 };
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index dcf4d21..8351183 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -124,7 +124,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
 	niph->id = 0;
 
 	addr_type = RTN_UNSPEC;
-	if (hook != NF_IP_FORWARD
+	if (hook != NF_INET_FORWARD
 #ifdef CONFIG_BRIDGE_NETFILTER
 	    || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
 #endif
@@ -149,7 +149,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
 
 	nf_ct_attach(nskb, oldskb);
 
-	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+	NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
 		dst_output);
 	return;
 
@@ -240,8 +240,8 @@ static struct xt_target ipt_reject_reg __read_mostly = {
 	.target		= reject,
 	.targetsize	= sizeof(struct ipt_reject_info),
 	.table		= "filter",
-	.hooks		= (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
-			  (1 << NF_IP_LOCAL_OUT),
+	.hooks		= (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
+			  (1 << NF_INET_LOCAL_OUT),
 	.checkentry	= check,
 	.me		= THIS_MODULE,
 };
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index 8988571..f2f62b5 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -119,8 +119,8 @@ same_target(struct sk_buff *skb,
 	struct nf_nat_range newrange;
 	const struct nf_conntrack_tuple *t;
 
-	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-			hooknum == NF_IP_POST_ROUTING);
+	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
+			hooknum == NF_INET_POST_ROUTING);
 	ct = nf_ct_get(skb, &ctinfo);
 
 	t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
@@ -158,7 +158,8 @@ static struct xt_target same_reg __read_mostly = {
 	.target		= same_target,
 	.targetsize	= sizeof(struct ipt_same_info),
 	.table		= "nat",
-	.hooks		= (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_POST_ROUTING),
+	.hooks		= (1 << NF_INET_PRE_ROUTING) |
+			  (1 << NF_INET_POST_ROUTING),
 	.checkentry	= same_check,
 	.destroy	= same_destroy,
 	.me		= THIS_MODULE,
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index b14e77d..6bc4bfe 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -73,7 +73,8 @@ static struct xt_match owner_match __read_mostly = {
 	.family		= AF_INET,
 	.match		= match,
 	.matchsize	= sizeof(struct ipt_owner_info),
-	.hooks		= (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING),
+	.hooks		= (1 << NF_INET_LOCAL_OUT) |
+			  (1 << NF_INET_POST_ROUTING),
 	.checkentry	= checkentry,
 	.me		= THIS_MODULE,
 };
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index ba3262c..06ab64e 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -19,7 +19,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables filter table");
 
-#define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
+			    (1 << NF_INET_FORWARD) | \
+			    (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -33,14 +35,14 @@ static struct
 		.num_entries = 4,
 		.size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
 		.hook_entry = {
-			[NF_IP_LOCAL_IN] = 0,
-			[NF_IP_FORWARD] = sizeof(struct ipt_standard),
-			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+			[NF_INET_LOCAL_IN] = 0,
+			[NF_INET_FORWARD] = sizeof(struct ipt_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
 		},
 		.underflow = {
-			[NF_IP_LOCAL_IN] = 0,
-			[NF_IP_FORWARD] = sizeof(struct ipt_standard),
-			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+			[NF_INET_LOCAL_IN] = 0,
+			[NF_INET_FORWARD] = sizeof(struct ipt_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
 		},
 	},
 	.entries = {
@@ -94,21 +96,21 @@ static struct nf_hook_ops ipt_ops[] = {
 		.hook		= ipt_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	{
 		.hook		= ipt_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_FORWARD,
+		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	{
 		.hook		= ipt_local_out_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 };
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index b4360a6..0335827 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -21,11 +21,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables mangle table");
 
-#define MANGLE_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | \
-			    (1 << NF_IP_LOCAL_IN) | \
-			    (1 << NF_IP_FORWARD) | \
-			    (1 << NF_IP_LOCAL_OUT) | \
-			    (1 << NF_IP_POST_ROUTING))
+#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+			    (1 << NF_INET_LOCAL_IN) | \
+			    (1 << NF_INET_FORWARD) | \
+			    (1 << NF_INET_LOCAL_OUT) | \
+			    (1 << NF_INET_POST_ROUTING))
 
 /* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
 static struct
@@ -40,18 +40,18 @@ static struct
 		.num_entries = 6,
 		.size = sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
 		.hook_entry = {
-			[NF_IP_PRE_ROUTING] 	= 0,
-			[NF_IP_LOCAL_IN] 	= sizeof(struct ipt_standard),
-			[NF_IP_FORWARD] 	= sizeof(struct ipt_standard) * 2,
-			[NF_IP_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
-			[NF_IP_POST_ROUTING] 	= sizeof(struct ipt_standard) * 4,
+			[NF_INET_PRE_ROUTING] 	= 0,
+			[NF_INET_LOCAL_IN] 	= sizeof(struct ipt_standard),
+			[NF_INET_FORWARD] 	= sizeof(struct ipt_standard) * 2,
+			[NF_INET_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
+			[NF_INET_POST_ROUTING] 	= sizeof(struct ipt_standard) * 4,
 		},
 		.underflow = {
-			[NF_IP_PRE_ROUTING] 	= 0,
-			[NF_IP_LOCAL_IN] 	= sizeof(struct ipt_standard),
-			[NF_IP_FORWARD] 	= sizeof(struct ipt_standard) * 2,
-			[NF_IP_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
-			[NF_IP_POST_ROUTING]	= sizeof(struct ipt_standard) * 4,
+			[NF_INET_PRE_ROUTING] 	= 0,
+			[NF_INET_LOCAL_IN] 	= sizeof(struct ipt_standard),
+			[NF_INET_FORWARD] 	= sizeof(struct ipt_standard) * 2,
+			[NF_INET_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
+			[NF_INET_POST_ROUTING]	= sizeof(struct ipt_standard) * 4,
 		},
 	},
 	.entries = {
@@ -133,35 +133,35 @@ static struct nf_hook_ops ipt_ops[] = {
 		.hook		= ipt_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_FORWARD,
+		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_local_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 };
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 5de6e57..11be0ee 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -7,7 +7,7 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <net/ip.h>
 
-#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
+#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -21,12 +21,12 @@ static struct
 		.num_entries = 3,
 		.size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
 		.hook_entry = {
-			[NF_IP_PRE_ROUTING] = 0,
-			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard)
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard)
 		},
 		.underflow = {
-			[NF_IP_PRE_ROUTING] = 0,
-			[NF_IP_LOCAL_OUT]  = sizeof(struct ipt_standard)
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_LOCAL_OUT]  = sizeof(struct ipt_standard)
 		},
 	},
 	.entries = {
@@ -78,14 +78,14 @@ static struct nf_hook_ops ipt_ops[] = {
 	{
 		.hook = ipt_hook,
 		.pf = PF_INET,
-		.hooknum = NF_IP_PRE_ROUTING,
+		.hooknum = NF_INET_PRE_ROUTING,
 		.priority = NF_IP_PRI_RAW,
 		.owner = THIS_MODULE,
 	},
 	{
 		.hook = ipt_local_hook,
 		.pf = PF_INET,
-		.hooknum = NF_IP_LOCAL_OUT,
+		.hooknum = NF_INET_LOCAL_OUT,
 		.priority = NF_IP_PRI_RAW,
 		.owner = THIS_MODULE,
 	},
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 831e9b2..9ac3020 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -150,7 +150,7 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
 	/* Gather fragments. */
 	if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
 		if (nf_ct_ipv4_gather_frags(skb,
-					    hooknum == NF_IP_PRE_ROUTING ?
+					    hooknum == NF_INET_PRE_ROUTING ?
 					    IP_DEFRAG_CONNTRACK_IN :
 					    IP_DEFRAG_CONNTRACK_OUT))
 			return NF_STOLEN;
@@ -190,56 +190,56 @@ static struct nf_hook_ops ipv4_conntrack_ops[] = {
 		.hook		= ipv4_conntrack_defrag,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv4_conntrack_in,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK,
 	},
 	{
 		.hook           = ipv4_conntrack_defrag,
 		.owner          = THIS_MODULE,
 		.pf             = PF_INET,
-		.hooknum        = NF_IP_LOCAL_OUT,
+		.hooknum        = NF_INET_LOCAL_OUT,
 		.priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv4_conntrack_local,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv4_conntrack_help,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK_HELPER,
 	},
 	{
 		.hook		= ipv4_conntrack_help,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_CONNTRACK_HELPER,
 	},
 	{
 		.hook		= ipv4_confirm,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 	},
 	{
 		.hook		= ipv4_confirm,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 	},
 };
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index adcbaf6..0e2c448 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -195,7 +195,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
 	}
 
 	/* See ip_conntrack_proto_tcp.c */
-	if (nf_conntrack_checksum && hooknum == NF_IP_PRE_ROUTING &&
+	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_ip_checksum(skb, hooknum, dataoff, 0)) {
 		if (LOG_INVALID(IPPROTO_ICMP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 70e7997..eac75eb 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -213,9 +213,9 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
 	*var_ipp = htonl(minip + j % (maxip - minip + 1));
 }
 
-/* Manipulate the tuple into the range given.  For NF_IP_POST_ROUTING,
- * we change the source to map into the range.  For NF_IP_PRE_ROUTING
- * and NF_IP_LOCAL_OUT, we change the destination to map into the
+/* Manipulate the tuple into the range given.  For NF_INET_POST_ROUTING,
+ * we change the source to map into the range.  For NF_INET_PRE_ROUTING
+ * and NF_INET_LOCAL_OUT, we change the destination to map into the
  * range.  It might not be possible to get a unique tuple, but we try.
  * At worst (or if we race), we will end up with a final duplicate in
  * __ip_conntrack_confirm and drop the packet. */
@@ -293,10 +293,10 @@ nf_nat_setup_info(struct nf_conn *ct,
 		}
 	}
 
-	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-		     hooknum == NF_IP_POST_ROUTING ||
-		     hooknum == NF_IP_LOCAL_IN ||
-		     hooknum == NF_IP_LOCAL_OUT);
+	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
+		     hooknum == NF_INET_POST_ROUTING ||
+		     hooknum == NF_INET_LOCAL_IN ||
+		     hooknum == NF_INET_LOCAL_OUT);
 	BUG_ON(nf_nat_initialized(ct, maniptype));
 
 	/* What we've got will look like inverse of reply. Normally
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index 93e18ef..0f226df 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -391,7 +391,7 @@ static void ip_nat_q931_expect(struct nf_conn *new,
 	range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
 
 	/* hook doesn't matter, but it has to do source manip */
-	nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
+	nf_nat_setup_info(new, &range, NF_INET_POST_ROUTING);
 
 	/* For DST manip, map port here to where it's expected. */
 	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
@@ -400,7 +400,7 @@ static void ip_nat_q931_expect(struct nf_conn *new,
 	    new->master->tuplehash[!this->dir].tuple.src.u3.ip;
 
 	/* hook doesn't matter, but it has to do destination manip */
-	nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
+	nf_nat_setup_info(new, &range, NF_INET_PRE_ROUTING);
 }
 
 /****************************************************************************/
@@ -481,7 +481,7 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new,
 	range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
 
 	/* hook doesn't matter, but it has to do source manip */
-	nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
+	nf_nat_setup_info(new, &range, NF_INET_POST_ROUTING);
 
 	/* For DST manip, map port here to where it's expected. */
 	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
@@ -489,7 +489,7 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new,
 	range.min_ip = range.max_ip = this->saved_ip;
 
 	/* hook doesn't matter, but it has to do destination manip */
-	nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
+	nf_nat_setup_info(new, &range, NF_INET_PRE_ROUTING);
 }
 
 /****************************************************************************/
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 8718da0..d00b8b2 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -431,7 +431,7 @@ void nf_nat_follow_master(struct nf_conn *ct,
 	range.min_ip = range.max_ip
 		= ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
 	/* hook doesn't matter, but it has to do source manip */
-	nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_POST_ROUTING);
 
 	/* For DST manip, map port here to where it's expected. */
 	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
@@ -439,6 +439,6 @@ void nf_nat_follow_master(struct nf_conn *ct,
 	range.min_ip = range.max_ip
 		= ct->master->tuplehash[!exp->dir].tuple.src.u3.ip;
 	/* hook doesn't matter, but it has to do destination manip */
-	nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_PRE_ROUTING);
 }
 EXPORT_SYMBOL(nf_nat_follow_master);
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index 6817e79..c540999 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -94,7 +94,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
 		range.min = range.max = exp->saved_proto;
 	}
 	/* hook doesn't matter, but it has to do source manip */
-	nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_POST_ROUTING);
 
 	/* For DST manip, map port here to where it's expected. */
 	range.flags = IP_NAT_RANGE_MAP_IPS;
@@ -105,7 +105,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
 		range.min = range.max = exp->saved_proto;
 	}
 	/* hook doesn't matter, but it has to do destination manip */
-	nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_PRE_ROUTING);
 }
 
 /* outbound packets == from PNS to PAC */
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 46b25ab..ee39ed8 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -24,7 +24,9 @@
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
+#define NAT_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+			 (1 << NF_INET_POST_ROUTING) | \
+			 (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -38,14 +40,14 @@ static struct
 		.num_entries = 4,
 		.size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
 		.hook_entry = {
-			[NF_IP_PRE_ROUTING] = 0,
-			[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
-			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
 		},
 		.underflow = {
-			[NF_IP_PRE_ROUTING] = 0,
-			[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
-			[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
 		},
 	},
 	.entries = {
@@ -76,7 +78,7 @@ static unsigned int ipt_snat_target(struct sk_buff *skb,
 	enum ip_conntrack_info ctinfo;
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 
-	NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
+	NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
 
 	ct = nf_ct_get(skb, &ctinfo);
 
@@ -118,15 +120,15 @@ static unsigned int ipt_dnat_target(struct sk_buff *skb,
 	enum ip_conntrack_info ctinfo;
 	const struct nf_nat_multi_range_compat *mr = targinfo;
 
-	NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-		     hooknum == NF_IP_LOCAL_OUT);
+	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
+		     hooknum == NF_INET_LOCAL_OUT);
 
 	ct = nf_ct_get(skb, &ctinfo);
 
 	/* Connection must be valid and new. */
 	NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
-	if (hooknum == NF_IP_LOCAL_OUT &&
+	if (hooknum == NF_INET_LOCAL_OUT &&
 	    mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
 		warn_if_extra_mangle(ip_hdr(skb)->daddr,
 				     mr->range[0].min_ip);
@@ -227,7 +229,7 @@ static struct xt_target ipt_snat_reg __read_mostly = {
 	.target		= ipt_snat_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
-	.hooks		= 1 << NF_IP_POST_ROUTING,
+	.hooks		= 1 << NF_INET_POST_ROUTING,
 	.checkentry	= ipt_snat_checkentry,
 	.family		= AF_INET,
 };
@@ -237,7 +239,7 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
 	.target		= ipt_dnat_target,
 	.targetsize	= sizeof(struct nf_nat_multi_range_compat),
 	.table		= "nat",
-	.hooks		= (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
+	.hooks		= (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
 	.checkentry	= ipt_dnat_checkentry,
 	.family		= AF_INET,
 };
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index 3ca9897..6ebf509 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -229,14 +229,14 @@ static void ip_nat_sdp_expect(struct nf_conn *ct,
 	range.min_ip = range.max_ip
 		= ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
 	/* hook doesn't matter, but it has to do source manip */
-	nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_POST_ROUTING);
 
 	/* For DST manip, map port here to where it's expected. */
 	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
 	range.min = range.max = exp->saved_proto;
 	range.min_ip = range.max_ip = exp->saved_ip;
 	/* hook doesn't matter, but it has to do destination manip */
-	nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+	nf_nat_setup_info(ct, &range, NF_INET_PRE_ROUTING);
 }
 
 /* So, this packet has hit the connection tracking matching code.
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 7db76ea..84172e9 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -137,7 +137,7 @@ nf_nat_fn(unsigned int hooknum,
 			if (unlikely(nf_ct_is_confirmed(ct)))
 				/* NAT module was loaded late */
 				ret = alloc_null_binding_confirmed(ct, hooknum);
-			else if (hooknum == NF_IP_LOCAL_IN)
+			else if (hooknum == NF_INET_LOCAL_IN)
 				/* LOCAL_IN hook doesn't have a chain!  */
 				ret = alloc_null_binding(ct, hooknum);
 			else
@@ -279,7 +279,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_in,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_NAT_DST,
 	},
 	/* After packet filtering, change source */
@@ -287,7 +287,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_out,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_NAT_SRC,
 	},
 	/* After conntrack, adjust sequence number */
@@ -295,7 +295,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_adjust,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_NAT_SEQ_ADJUST,
 	},
 	/* Before packet filtering, change destination */
@@ -303,7 +303,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_local_fn,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_NAT_DST,
 	},
 	/* After packet filtering, change source */
@@ -311,7 +311,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_fn,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_NAT_SRC,
 	},
 	/* After conntrack, adjust sequence number */
@@ -319,7 +319,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
 		.hook		= nf_nat_adjust,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET,
-		.hooknum	= NF_IP_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_NAT_SEQ_ADJUST,
 	},
 };
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 3916fac..cb12204 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -318,7 +318,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 		icmp_out_count(((struct icmphdr *)
 			skb_transport_header(skb))->type);
 
-	err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+	err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
 		err = inet->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5e95c8a..f1ca855 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -135,7 +135,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 		ip_hdr(skb)->tot_len = htons(skb->len);
 		ip_send_check(ip_hdr(skb));
 
-		NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+		NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
 			xfrm4_rcv_encap_finish);
 		return 0;
 #else
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c4a7156..28c7f9d 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -78,7 +78,7 @@ static int xfrm4_output_finish2(struct sk_buff *skb)
 	while (likely((err = xfrm4_output_one(skb)) == 0)) {
 		nf_reset(skb);
 
-		err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
+		err = nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL,
 			      skb->dst->dev, dst_output);
 		if (unlikely(err != 1))
 			break;
@@ -86,7 +86,7 @@ static int xfrm4_output_finish2(struct sk_buff *skb)
 		if (!skb->dst->xfrm)
 			return dst_output(skb);
 
-		err = nf_hook(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
+		err = nf_hook(PF_INET, NF_INET_POST_ROUTING, skb, NULL,
 			      skb->dst->dev, xfrm4_output_finish2);
 		if (unlikely(err != 1))
 			break;
@@ -139,7 +139,7 @@ static int xfrm4_output_finish(struct sk_buff *skb)
 
 int xfrm4_output(struct sk_buff *skb)
 {
-	return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
-			    xfrm4_output_finish,
+	return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb,
+			    NULL, skb->dst->dev, xfrm4_output_finish,
 			    !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index fac6f7f..79610b4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -134,7 +134,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 
 	rcu_read_unlock();
 
-	return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
+	return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL,
+		       ip6_rcv_finish);
 err:
 	IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
 drop:
@@ -229,7 +230,8 @@ discard:
 
 int ip6_input(struct sk_buff *skb)
 {
-	return NF_HOOK(PF_INET6,NF_IP6_LOCAL_IN, skb, skb->dev, NULL, ip6_input_finish);
+	return NF_HOOK(PF_INET6, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
+		       ip6_input_finish);
 }
 
 int ip6_mc_input(struct sk_buff *skb)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 653fc0a..1a84b74 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -120,8 +120,8 @@ static int ip6_output2(struct sk_buff *skb)
 			   is not supported in any case.
 			 */
 			if (newskb)
-				NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, newskb, NULL,
-					newskb->dev,
+				NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, newskb,
+					NULL, newskb->dev,
 					ip6_dev_loopback_xmit);
 
 			if (ipv6_hdr(skb)->hop_limit == 0) {
@@ -134,7 +134,8 @@ static int ip6_output2(struct sk_buff *skb)
 		IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
 	}
 
-	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
+	return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
+		       ip6_output_finish);
 }
 
 static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
@@ -236,7 +237,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
 	if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
 		IP6_INC_STATS(ip6_dst_idev(skb->dst),
 			      IPSTATS_MIB_OUTREQUESTS);
-		return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
+		return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
 				dst_output);
 	}
 
@@ -500,7 +501,8 @@ int ip6_forward(struct sk_buff *skb)
 	hdr->hop_limit--;
 
 	IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
-	return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
+	return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
+		       ip6_forward_finish);
 
 error:
 	IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
@@ -1406,7 +1408,8 @@ int ip6_push_pending_frames(struct sock *sk)
 		ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
 	}
 
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev,
+		      dst_output);
 	if (err) {
 		if (err > 0)
 			err = np->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 5383b33..2f30ca2 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -917,7 +917,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 	ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst);
 	nf_reset(skb);
 	pkt_len = skb->len;
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL,
 		      skb->dst->dev, dst_output);
 
 	if (net_xmit_eval(err) == 0) {
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 331d728..27e2821 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1450,7 +1450,7 @@ static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
 
 static inline int mld_dev_queue_xmit(struct sk_buff *skb)
 {
-	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
+	return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
 		       mld_dev_queue_xmit2);
 }
 
@@ -1471,7 +1471,7 @@ static void mld_sendpack(struct sk_buff *skb)
 	pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
 		IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
 					     mldlen, 0));
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
 		mld_dev_queue_xmit);
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
@@ -1815,7 +1815,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 
 	idev = in6_dev_get(skb->dev);
 
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
 		mld_dev_queue_xmit);
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS(idev, type);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 36f7dbf..0ed3216 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -533,7 +533,8 @@ static void __ndisc_send(struct net_device *dev,
 	idev = in6_dev_get(dst->dev);
 	IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
 
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
+		      dst_output);
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS(idev, type);
 		ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -1537,7 +1538,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 	buff->dst = dst;
 	idev = in6_dev_get(dst->dev);
 	IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
+		      dst_output);
 	if (!err) {
 		ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT);
 		ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index b1326c2..175e19f 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -60,7 +60,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, struct nf_info *info)
 {
 	struct ip6_rt_info *rt_info = nf_info_reroute(info);
 
-	if (info->hook == NF_IP6_LOCAL_OUT) {
+	if (info->hook == NF_INET_LOCAL_OUT) {
 		struct ipv6hdr *iph = ipv6_hdr(skb);
 
 		rt_info->daddr = iph->daddr;
@@ -72,7 +72,7 @@ static int nf_ip6_reroute(struct sk_buff *skb, const struct nf_info *info)
 {
 	struct ip6_rt_info *rt_info = nf_info_reroute(info);
 
-	if (info->hook == NF_IP6_LOCAL_OUT) {
+	if (info->hook == NF_INET_LOCAL_OUT) {
 		struct ipv6hdr *iph = ipv6_hdr(skb);
 		if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
 		    !ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
@@ -89,7 +89,7 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
 
 	switch (skb->ip_summed) {
 	case CHECKSUM_COMPLETE:
-		if (hook != NF_IP6_PRE_ROUTING && hook != NF_IP6_LOCAL_IN)
+		if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
 			break;
 		if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
 				     skb->len - dataoff, protocol,
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index acaba15..e1e87ef 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -258,11 +258,11 @@ unconditional(const struct ip6t_ip6 *ipv6)
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
 /* This cries for unification! */
 static const char *hooknames[] = {
-	[NF_IP6_PRE_ROUTING]		= "PREROUTING",
-	[NF_IP6_LOCAL_IN]		= "INPUT",
-	[NF_IP6_FORWARD]		= "FORWARD",
-	[NF_IP6_LOCAL_OUT]		= "OUTPUT",
-	[NF_IP6_POST_ROUTING]		= "POSTROUTING",
+	[NF_INET_PRE_ROUTING]		= "PREROUTING",
+	[NF_INET_LOCAL_IN]		= "INPUT",
+	[NF_INET_FORWARD]		= "FORWARD",
+	[NF_INET_LOCAL_OUT]		= "OUTPUT",
+	[NF_INET_POST_ROUTING]		= "POSTROUTING",
 };
 
 enum nf_ip_trace_comments {
@@ -502,7 +502,7 @@ mark_source_chains(struct xt_table_info *newinfo,
 
 	/* No recursion; use packet counter to save back ptrs (reset
 	   to 0 as we leave), and comefrom to save source hook bitmask */
-	for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) {
+	for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ip6t_entry *e
 			= (struct ip6t_entry *)(entry0 + pos);
@@ -518,13 +518,13 @@ mark_source_chains(struct xt_table_info *newinfo,
 			struct ip6t_standard_target *t
 				= (void *)ip6t_get_target(e);
 
-			if (e->comefrom & (1 << NF_IP6_NUMHOOKS)) {
+			if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
 				printk("iptables: loop hook %u pos %u %08X.\n",
 				       hook, pos, e->comefrom);
 				return 0;
 			}
 			e->comefrom
-				|= ((1 << hook) | (1 << NF_IP6_NUMHOOKS));
+				|= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
 			/* Unconditional return/END. */
 			if ((e->target_offset == sizeof(struct ip6t_entry)
@@ -544,10 +544,10 @@ mark_source_chains(struct xt_table_info *newinfo,
 				/* Return: backtrack through the last
 				   big jump. */
 				do {
-					e->comefrom ^= (1<<NF_IP6_NUMHOOKS);
+					e->comefrom ^= (1<<NF_INET_NUMHOOKS);
 #ifdef DEBUG_IP_FIREWALL_USER
 					if (e->comefrom
-					    & (1 << NF_IP6_NUMHOOKS)) {
+					    & (1 << NF_INET_NUMHOOKS)) {
 						duprintf("Back unset "
 							 "on hook %u "
 							 "rule %u\n",
@@ -746,7 +746,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 	}
 
 	/* Check hooks & underflows */
-	for (h = 0; h < NF_IP6_NUMHOOKS; h++) {
+	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
 		if ((unsigned char *)e - base == underflows[h])
@@ -800,7 +800,7 @@ translate_table(const char *name,
 	newinfo->number = number;
 
 	/* Init all hooks to impossible value. */
-	for (i = 0; i < NF_IP6_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		newinfo->hook_entry[i] = 0xFFFFFFFF;
 		newinfo->underflow[i] = 0xFFFFFFFF;
 	}
@@ -824,7 +824,7 @@ translate_table(const char *name,
 	}
 
 	/* Check hooks all assigned */
-	for (i = 0; i < NF_IP6_NUMHOOKS; i++) {
+	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
 		/* Only hooks which are valid */
 		if (!(valid_hooks & (1 << i)))
 			continue;
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 1a7d291..9d45e9e 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -159,14 +159,14 @@ static void send_reset(struct sk_buff *oldskb)
 
 	nf_ct_attach(nskb, oldskb);
 
-	NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+	NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
 		dst_output);
 }
 
 static inline void
 send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
 {
-	if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL)
+	if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
 		skb_in->dev = init_net.loopback_dev;
 
 	icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
@@ -245,8 +245,8 @@ static struct xt_target ip6t_reject_reg __read_mostly = {
 	.target		= reject6_target,
 	.targetsize	= sizeof(struct ip6t_reject_info),
 	.table		= "filter",
-	.hooks		= (1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) |
-			  (1 << NF_IP6_LOCAL_OUT),
+	.hooks		= (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
+			  (1 << NF_INET_LOCAL_OUT),
 	.checkentry	= check,
 	.me		= THIS_MODULE
 };
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 34ba150..00084e8 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -67,8 +67,8 @@ static struct xt_match eui64_match __read_mostly = {
 	.family		= AF_INET6,
 	.match		= match,
 	.matchsize	= sizeof(int),
-	.hooks		= (1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
-			  (1 << NF_IP6_FORWARD),
+	.hooks		= (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
+			  (1 << NF_INET_FORWARD),
 	.me		= THIS_MODULE,
 };
 
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 6036613..1e0dc4a 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -73,7 +73,8 @@ static struct xt_match owner_match __read_mostly = {
 	.family		= AF_INET6,
 	.match		= match,
 	.matchsize	= sizeof(struct ip6t_owner_info),
-	.hooks		= (1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING),
+	.hooks		= (1 << NF_INET_LOCAL_OUT) |
+			  (1 << NF_INET_POST_ROUTING),
 	.checkentry	= checkentry,
 	.me		= THIS_MODULE,
 };
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 1d26b20..0ae072d 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -17,7 +17,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("ip6tables filter table");
 
-#define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
+			    (1 << NF_INET_FORWARD) | \
+			    (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -31,14 +33,14 @@ static struct
 		.num_entries = 4,
 		.size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
 		.hook_entry = {
-			[NF_IP6_LOCAL_IN] = 0,
-			[NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
-			[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+			[NF_INET_LOCAL_IN] = 0,
+			[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
 		},
 		.underflow = {
-			[NF_IP6_LOCAL_IN] = 0,
-			[NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
-			[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+			[NF_INET_LOCAL_IN] = 0,
+			[NF_INET_FORWARD] = sizeof(struct ip6t_standard),
+			[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
 		},
 	},
 	.entries = {
@@ -93,21 +95,21 @@ static struct nf_hook_ops ip6t_ops[] = {
 		.hook		= ip6t_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
 	{
 		.hook		= ip6t_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_FORWARD,
+		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
 	{
 		.hook		= ip6t_local_out_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
 };
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index a0b6381..8e62b23 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -15,11 +15,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("ip6tables mangle table");
 
-#define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | \
-			    (1 << NF_IP6_LOCAL_IN) | \
-			    (1 << NF_IP6_FORWARD) | \
-			    (1 << NF_IP6_LOCAL_OUT) | \
-			    (1 << NF_IP6_POST_ROUTING))
+#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+			    (1 << NF_INET_LOCAL_IN) | \
+			    (1 << NF_INET_FORWARD) | \
+			    (1 << NF_INET_LOCAL_OUT) | \
+			    (1 << NF_INET_POST_ROUTING))
 
 static struct
 {
@@ -33,18 +33,18 @@ static struct
 		.num_entries = 6,
 		.size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
 		.hook_entry = {
-			[NF_IP6_PRE_ROUTING] 	= 0,
-			[NF_IP6_LOCAL_IN]	= sizeof(struct ip6t_standard),
-			[NF_IP6_FORWARD]	= sizeof(struct ip6t_standard) * 2,
-			[NF_IP6_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
-			[NF_IP6_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4,
+			[NF_INET_PRE_ROUTING] 	= 0,
+			[NF_INET_LOCAL_IN]	= sizeof(struct ip6t_standard),
+			[NF_INET_FORWARD]	= sizeof(struct ip6t_standard) * 2,
+			[NF_INET_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
+			[NF_INET_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4,
 		},
 		.underflow = {
-			[NF_IP6_PRE_ROUTING] 	= 0,
-			[NF_IP6_LOCAL_IN]	= sizeof(struct ip6t_standard),
-			[NF_IP6_FORWARD]	= sizeof(struct ip6t_standard) * 2,
-			[NF_IP6_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
-			[NF_IP6_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4,
+			[NF_INET_PRE_ROUTING] 	= 0,
+			[NF_INET_LOCAL_IN]	= sizeof(struct ip6t_standard),
+			[NF_INET_FORWARD]	= sizeof(struct ip6t_standard) * 2,
+			[NF_INET_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
+			[NF_INET_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4,
 		},
 	},
 	.entries = {
@@ -125,35 +125,35 @@ static struct nf_hook_ops ip6t_ops[] = {
 		.hook		= ip6t_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_local_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_FORWARD,
+		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_local_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_route_hook,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 };
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 8f7109f..4fecd8d 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -6,7 +6,7 @@
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 
-#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
+#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -20,12 +20,12 @@ static struct
 		.num_entries = 3,
 		.size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
 		.hook_entry = {
-			[NF_IP6_PRE_ROUTING] = 0,
-			[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard)
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
 		},
 		.underflow = {
-			[NF_IP6_PRE_ROUTING] = 0,
-			[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard)
+			[NF_INET_PRE_ROUTING] = 0,
+			[NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
 		},
 	},
 	.entries = {
@@ -58,14 +58,14 @@ static struct nf_hook_ops ip6t_ops[] = {
 	{
 	  .hook = ip6t_hook,
 	  .pf = PF_INET6,
-	  .hooknum = NF_IP6_PRE_ROUTING,
+	  .hooknum = NF_INET_PRE_ROUTING,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .owner = THIS_MODULE,
 	},
 	{
 	  .hook = ip6t_hook,
 	  .pf = PF_INET6,
-	  .hooknum = NF_IP6_LOCAL_OUT,
+	  .hooknum = NF_INET_LOCAL_OUT,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .owner = THIS_MODULE,
 	},
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index ad74bab..50f4678 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -263,42 +263,42 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
 		.hook		= ipv6_defrag,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv6_conntrack_in,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_PRE_ROUTING,
+		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv6_conntrack_local,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv6_defrag,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_OUT,
+		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv6_confirm,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_POST_ROUTING,
+		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP6_PRI_LAST,
 	},
 	{
 		.hook		= ipv6_confirm,
 		.owner		= THIS_MODULE,
 		.pf		= PF_INET6,
-		.hooknum	= NF_IP6_LOCAL_IN,
+		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_LAST-1,
 	},
 };
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index fd9123f..e99384f 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -192,7 +192,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
 		return -NF_ACCEPT;
 	}
 
-	if (nf_conntrack_checksum && hooknum == NF_IP6_PRE_ROUTING &&
+	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
 		nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
 			      "nf_ct_icmpv6: ICMPv6 checksum failed\n");
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ca24ef1..fb804e0 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -618,7 +618,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
 		goto error_fault;
 
 	IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
-	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 5157837..a0e103b 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -110,7 +110,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 		ipv6_hdr(skb)->payload_len = htons(skb->len);
 		__skb_push(skb, skb->data - skb_network_header(skb));
 
-		NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+		NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
 			ip6_rcv_finish);
 		return -1;
 #else
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6569767..d6b05f9 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -80,7 +80,7 @@ static int xfrm6_output_finish2(struct sk_buff *skb)
 	while (likely((err = xfrm6_output_one(skb)) == 0)) {
 		nf_reset(skb);
 
-		err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
+		err = nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL,
 			      skb->dst->dev, dst_output);
 		if (unlikely(err != 1))
 			break;
@@ -88,7 +88,7 @@ static int xfrm6_output_finish2(struct sk_buff *skb)
 		if (!skb->dst->xfrm)
 			return dst_output(skb);
 
-		err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
+		err = nf_hook(PF_INET6, NF_INET_POST_ROUTING, skb, NULL,
 			      skb->dst->dev, xfrm6_output_finish2);
 		if (unlikely(err != 1))
 			break;
@@ -134,6 +134,6 @@ static int xfrm6_output_finish(struct sk_buff *skb)
 
 int xfrm6_output(struct sk_buff *skb)
 {
-	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
+	return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dst->dev,
 		       xfrm6_output_finish);
 }
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9be1826..628bd65 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -829,18 +829,18 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
 						&range) < 0)
 				return -EINVAL;
 			if (nf_nat_initialized(ct,
-					       HOOK2MANIP(NF_IP_PRE_ROUTING)))
+					       HOOK2MANIP(NF_INET_PRE_ROUTING)))
 				return -EEXIST;
-			nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+			nf_nat_setup_info(ct, &range, NF_INET_PRE_ROUTING);
 		}
 		if (cda[CTA_NAT_SRC]) {
 			if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
 						&range) < 0)
 				return -EINVAL;
 			if (nf_nat_initialized(ct,
-					       HOOK2MANIP(NF_IP_POST_ROUTING)))
+					       HOOK2MANIP(NF_INET_POST_ROUTING)))
 				return -EEXIST;
-			nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+			nf_nat_setup_info(ct, &range, NF_INET_POST_ROUTING);
 		}
 #endif
 	}
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 7a3f64c..d96f188 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -783,9 +783,7 @@ static int tcp_error(struct sk_buff *skb,
 	 * because the checksum is assumed to be correct.
 	 */
 	/* FIXME: Source route IP option packets --RR */
-	if (nf_conntrack_checksum &&
-	    ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-	     (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
 		if (LOG_INVALID(IPPROTO_TCP))
 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index b3e7ecb..570a2e1 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -128,9 +128,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
 	 * We skip checking packets on the outgoing path
 	 * because the checksum is assumed to be correct.
 	 * FIXME: Source route IP option packets --RR */
-	if (nf_conntrack_checksum &&
-	    ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-	     (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+	if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
 	    nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
 		if (LOG_INVALID(IPPROTO_UDP))
 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index b8981dd..7e116d5 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -133,8 +133,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
 
 	/* 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))) {
+	    hooknum == NF_INET_PRE_ROUTING) {
 		if (pf == PF_INET) {
 			struct iphdr *iph = ip_hdr(skb);
 
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 77eeae6..e4f7f86 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -47,9 +47,9 @@ static struct xt_target xt_classify_target[] __read_mostly = {
 		.target 	= target,
 		.targetsize	= sizeof(struct xt_classify_target_info),
 		.table		= "mangle",
-		.hooks		= (1 << NF_IP_LOCAL_OUT) |
-				  (1 << NF_IP_FORWARD) |
-				  (1 << NF_IP_POST_ROUTING),
+		.hooks		= (1 << NF_INET_LOCAL_OUT) |
+				  (1 << NF_INET_FORWARD) |
+				  (1 << NF_INET_POST_ROUTING),
 		.me 		= THIS_MODULE,
 	},
 	{
@@ -58,9 +58,9 @@ static struct xt_target xt_classify_target[] __read_mostly = {
 		.target 	= target,
 		.targetsize	= sizeof(struct xt_classify_target_info),
 		.table		= "mangle",
-		.hooks		= (1 << NF_IP6_LOCAL_OUT) |
-				  (1 << NF_IP6_FORWARD) |
-				  (1 << NF_IP6_POST_ROUTING),
+		.hooks		= (1 << NF_INET_LOCAL_OUT) |
+				  (1 << NF_INET_FORWARD) |
+				  (1 << NF_INET_POST_ROUTING),
 		.me 		= THIS_MODULE,
 	},
 };
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 07435a6..851e121 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -216,9 +216,9 @@ xt_tcpmss_checkentry4(const char *tablename,
 	const struct ipt_entry *e = entry;
 
 	if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
-	    (hook_mask & ~((1 << NF_IP_FORWARD) |
-			   (1 << NF_IP_LOCAL_OUT) |
-			   (1 << NF_IP_POST_ROUTING))) != 0) {
+	    (hook_mask & ~((1 << NF_INET_FORWARD) |
+			   (1 << NF_INET_LOCAL_OUT) |
+			   (1 << NF_INET_POST_ROUTING))) != 0) {
 		printk("xt_TCPMSS: path-MTU clamping only supported in "
 		       "FORWARD, OUTPUT and POSTROUTING hooks\n");
 		return false;
@@ -241,9 +241,9 @@ xt_tcpmss_checkentry6(const char *tablename,
 	const struct ip6t_entry *e = entry;
 
 	if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
-	    (hook_mask & ~((1 << NF_IP6_FORWARD) |
-			   (1 << NF_IP6_LOCAL_OUT) |
-			   (1 << NF_IP6_POST_ROUTING))) != 0) {
+	    (hook_mask & ~((1 << NF_INET_FORWARD) |
+			   (1 << NF_INET_LOCAL_OUT) |
+			   (1 << NF_INET_POST_ROUTING))) != 0) {
 		printk("xt_TCPMSS: path-MTU clamping only supported in "
 		       "FORWARD, OUTPUT and POSTROUTING hooks\n");
 		return false;
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index 00490d7..6ff4479 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -50,9 +50,9 @@ static struct xt_match xt_mac_match[] __read_mostly = {
 		.family		= AF_INET,
 		.match		= match,
 		.matchsize	= sizeof(struct xt_mac_info),
-		.hooks		= (1 << NF_IP_PRE_ROUTING) |
-				  (1 << NF_IP_LOCAL_IN) |
-				  (1 << NF_IP_FORWARD),
+		.hooks		= (1 << NF_INET_PRE_ROUTING) |
+				  (1 << NF_INET_LOCAL_IN) |
+				  (1 << NF_INET_FORWARD),
 		.me		= THIS_MODULE,
 	},
 	{
@@ -60,9 +60,9 @@ static struct xt_match xt_mac_match[] __read_mostly = {
 		.family		= AF_INET6,
 		.match		= match,
 		.matchsize	= sizeof(struct xt_mac_info),
-		.hooks		= (1 << NF_IP6_PRE_ROUTING) |
-				  (1 << NF_IP6_LOCAL_IN) |
-				  (1 << NF_IP6_FORWARD),
+		.hooks		= (1 << NF_INET_PRE_ROUTING) |
+				  (1 << NF_INET_LOCAL_IN) |
+				  (1 << NF_INET_FORWARD),
 		.me		= THIS_MODULE,
 	},
 };
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index a4bab04..e91aee7 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -113,12 +113,12 @@ checkentry(const char *tablename,
 	if (info->bitmask & XT_PHYSDEV_OP_OUT &&
 	    (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
 	     info->invert & XT_PHYSDEV_OP_BRIDGED) &&
-	    hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
-			 (1 << NF_IP_POST_ROUTING))) {
+	    hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
+			 (1 << NF_INET_POST_ROUTING))) {
 		printk(KERN_WARNING "physdev match: using --physdev-out in the "
 		       "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
 		       "traffic is not supported anymore.\n");
-		if (hook_mask & (1 << NF_IP_LOCAL_OUT))
+		if (hook_mask & (1 << NF_INET_LOCAL_OUT))
 			return false;
 	}
 	return true;
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 6d6d3b7..2eaa6fd 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -144,14 +144,13 @@ static bool checkentry(const char *tablename, const void *ip_void,
 				"outgoing policy selected\n");
 		return false;
 	}
-	/* hook values are equal for IPv4 and IPv6 */
-	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+	if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN)
 	    && info->flags & XT_POLICY_MATCH_OUT) {
 		printk(KERN_ERR "xt_policy: output policy not valid in "
 				"PRE_ROUTING and INPUT\n");
 		return false;
 	}
-	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+	if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT)
 	    && info->flags & XT_POLICY_MATCH_IN) {
 		printk(KERN_ERR "xt_policy: input policy not valid in "
 				"POST_ROUTING and OUTPUT\n");
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index cc3e76d..91113dc 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -41,8 +41,8 @@ static struct xt_match realm_match __read_mostly = {
 	.name		= "realm",
 	.match		= match,
 	.matchsize	= sizeof(struct xt_realm_info),
-	.hooks		= (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
-			  (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN),
+	.hooks		= (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) |
+			  (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN),
 	.family		= AF_INET,
 	.me		= THIS_MODULE
 };
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 3f8335e..d377dec 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -235,7 +235,7 @@ static struct nf_hook_ops ing_ops = {
 	.hook           = ing_hook,
 	.owner		= THIS_MODULE,
 	.pf             = PF_INET,
-	.hooknum        = NF_IP_PRE_ROUTING,
+	.hooknum        = NF_INET_PRE_ROUTING,
 	.priority       = NF_IP_PRI_FILTER + 1,
 };
 
@@ -243,7 +243,7 @@ static struct nf_hook_ops ing6_ops = {
 	.hook           = ing_hook,
 	.owner		= THIS_MODULE,
 	.pf             = PF_INET6,
-	.hooknum        = NF_IP6_PRE_ROUTING,
+	.hooknum        = NF_INET_PRE_ROUTING,
 	.priority       = NF_IP6_PRI_FILTER + 1,
 };
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..c3bb3e4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5035,7 +5035,7 @@ static struct nf_hook_ops selinux_ipv4_op = {
 	.hook =		selinux_ipv4_postroute_last,
 	.owner =	THIS_MODULE,
 	.pf =		PF_INET,
-	.hooknum =	NF_IP_POST_ROUTING,
+	.hooknum =	NF_INET_POST_ROUTING,
 	.priority =	NF_IP_PRI_SELINUX_LAST,
 };
 
@@ -5045,7 +5045,7 @@ static struct nf_hook_ops selinux_ipv6_op = {
 	.hook =		selinux_ipv6_postroute_last,
 	.owner =	THIS_MODULE,
 	.pf =		PF_INET6,
-	.hooknum =	NF_IP6_POST_ROUTING,
+	.hooknum =	NF_INET_POST_ROUTING,
 	.priority =	NF_IP6_PRI_SELINUX_LAST,
 };
 

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-08 11:23   ` Patrick McHardy
@ 2007-11-08 11:29     ` Herbert Xu
  2007-11-14  9:07       ` David Miller
  0 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-08 11:29 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David S. Miller, netdev

On Thu, Nov 08, 2007 at 12:23:29PM +0100, Patrick McHardy wrote:
>
> We have a few places that go though the trouble of selecting the
> "correct" hook value for the address family, even though the numerical
> values are identical. How about we just get rid of the different
> naming and use NF_INET_... for both IPv4 and IPv6?

Nice work! Thanks Patrick.
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-08  0:39     ` Herbert Xu
@ 2007-11-13 11:33       ` David Miller
  2007-11-13 11:51         ` Herbert Xu
  0 siblings, 1 reply; 71+ messages in thread
From: David Miller @ 2007-11-13 11:33 UTC (permalink / raw)
  To: herbert; +Cc: netdev, netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 8 Nov 2007 08:39:03 +0800

> On Wed, Nov 07, 2007 at 05:17:42PM +0100, Ingo Oeser wrote:
> > Hi Herbert,
> > 
> > Herbert Xu schrieb:
> > > diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
> > > index a7bc8c6..4a01cb3 100644
> > > --- a/net/ipv6/xfrm6_mode_ro.c
> > > +++ b/net/ipv6/xfrm6_mode_ro.c
> > > @@ -53,7 +54,9 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
> > >  	__skb_pull(skb, hdr_len);
> > >  	memmove(ipv6_hdr(skb), iph, hdr_len);
> > >  
> > > +	spin_lock_bh(&x->lock);
> > >  	x->lastused = get_seconds();
> > > +	spin_unlock_bh(&x->lock);
> > >  
> > >  	return 0;
> > >  }
> > 
> > Can you move the retrieval of the seconds outside the spinlock?
> 
> You certainly could.  Whether it's worth it I won't speculate :)

Make 'lastused' an 'unsigned long' (that's all that get_seconds()
gives to us anyways), fix up the nla_total_size(x->lastused) thing in
net/xfrm/xfrm_user.c, and then you can remove this lock acquisition
completely because the store into x->lastused will now be atomic and
therefore locks aren't protecting anything.

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-13 11:33       ` David Miller
@ 2007-11-13 11:51         ` Herbert Xu
  2007-11-14  5:47           ` David Miller
  0 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-13 11:51 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, netdev

On Tue, Nov 13, 2007 at 03:33:48AM -0800, David Miller wrote:
>
> Make 'lastused' an 'unsigned long' (that's all that get_seconds()
> gives to us anyways), fix up the nla_total_size(x->lastused) thing in
> net/xfrm/xfrm_user.c, and then you can remove this lock acquisition
> completely because the store into x->lastused will now be atomic and
> therefore locks aren't protecting anything.

Brilliant, make that patch 25/25 :)

[IPSEC]: Make x->lastused an unsigned long

Currently x->lastused is u64 which means that it cannot be read/written
atomically on all architectures.  David Miller observed that the value
stored in it is only an unsigned long which is always atomic.

So based on his suggestion this patch changes the internal representation
from u64 to unsigned long while the user-interface still refers to it as
u64.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h       |    2 +-
 net/ipv6/xfrm6_mode_ro.c |    2 --
 net/xfrm/xfrm_user.c     |    4 ++--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 944fdad..e184c11 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -183,7 +183,7 @@ struct xfrm_state
 	struct timer_list	timer;
 
 	/* Last used time */
-	u64			lastused;
+	unsigned long		lastused;
 
 	/* Reference to data common to all the instances of this
 	 * transformer. */
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index 4a01cb3..63d5d49 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -54,9 +54,7 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
 	__skb_pull(skb, hdr_len);
 	memmove(ipv6_hdr(skb), iph, hdr_len);
 
-	spin_lock_bh(&x->lock);
 	x->lastused = get_seconds();
-	spin_unlock_bh(&x->lock);
 
 	return 0;
 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d41588d..02cf26f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1993,8 +1993,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
 	if (x->coaddr)
 		l += nla_total_size(sizeof(*x->coaddr));
 
-	/* Must count this as this may become non-zero behind our back. */
-	l += nla_total_size(sizeof(x->lastused));
+	/* Must count x->lastused as it may become non-zero behind our back. */
+	l += nla_total_size(sizeof(u64));
 
 	return l;
 }

-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst
  2007-11-07 14:08 ` [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst Herbert Xu
@ 2007-11-14  5:32   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:32 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:16 +0800

> [IPV6]: Only set nfheader_len for top xfrm dst
> 
> We only need to set nfheader_len in the top xfrm dst.  This is because
> we only ever read the nfheader_len from the top xfrm dst.
> 
> It is also easier to count nfheader_len as part of header_len which
> then lets us remove the ugly wrapper functions for incrementing and
> decrementing header lengths in xfrm6_policy.c.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output
  2007-11-07 14:08 ` [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output Herbert Xu
@ 2007-11-14  5:33   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:33 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:18 +0800

> [IPSEC]: Use dst->header_len when resizing on output
> 
> Currently we use x->props.header_len when resizing on output.  However,
> if we're resizing at all we might as well go the whole hog and do it
> for the whole dst.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info
  2007-11-07 14:08 ` [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info Herbert Xu
@ 2007-11-14  5:33   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:33 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:19 +0800

> [IPV6]: Move nfheader_len into rt6_info
> 
> The dst member nfheader_len is only used by IPv6.  It's also currently
> creating a rather ugly alignment hole in struct dst.  Therefore this patch
> moves it from there into struct rt6_info.
> 
> It also reorders the fields in rt6_info to minimize holes.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard
  2007-11-07 14:08 ` [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard Herbert Xu
@ 2007-11-14  5:34   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:34 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:20 +0800

> [NET]: Eliminate duplicate copies of dst_discard
> 
> We have a number of copies of dst_discard scattered around the place which
> all do the same thing, namely free a packet on the input or output paths.
> 
> This patch deletes all of them except dst_discard and points all the users
> to it.
> 
> The only non-trivial bit is decnet where it returns an error.  However,
> conceptually this is identical to the blackhole functions used in IPv4
> and IPv6 which do not return errors.  So they should either all return
> errors or all return zero.  For now I've stuck with the majority and
> picked zero as the return value.
> 
> It doesn't really matter in practice since few if any driver would react
> differently depending on a zero return value or NET_RX_DROP.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h
  2007-11-07 14:08 ` [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h Herbert Xu
@ 2007-11-14  5:34   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:34 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:21 +0800

> [NET]: Remove unnecessary inclusion of dst.h
> 
> The file net/netevent.h only refers to struct dst_entry * so it doesn't
> need to include dst.h.  I've replaced it with a forward declaration.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst
  2007-11-07 14:08 ` [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst Herbert Xu
@ 2007-11-14  5:35   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:35 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:22 +0800

> [IPSEC]: Only set neighbour on top xfrm dst
> 
> The neighbour field is only used by dst_confirm which only ever happens on
> the top-most xfrm dst.  So it's a waste to duplicate for every other xfrm
> dst.  This patch moves its setting out of the loop so that only the top one
> gets set.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard
  2007-11-07 14:08 ` [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard Herbert Xu
@ 2007-11-14  5:35   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:35 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:23 +0800

> [IPSEC]: Set dst->input to dst_discard
> 
> The input function should never be invoked on IPsec dst objects.  This is
> because we don't apply IPsec on input until after we've made the routing
> decision.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst
  2007-11-07 14:08 ` [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst Herbert Xu
@ 2007-11-14  5:36   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:36 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:24 +0800

> [IPSEC]: Make sure idev is consistent with dev in xfrm_dst
> 
> Previously we took the device from the bottom route and idev from the top
> route.  This is bad because idev may well point to a different device.
> This patch changes it so that we get the idev from the device directly.
> 
> It also makes it an error if either dev or idev is NULL.  This is consistent
> with the rest of the routing code which also treats these cases as errors.
> 
> I've removed the err initialisation in xfrm6_policy.c because it achieves
> no purpose and hid a bug when an initial version of this patch neglected
> to set err to -ENODEV (fortunately the IPv4 version warned about it).
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags
  2007-11-07 14:08 ` [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags Herbert Xu
@ 2007-11-14  5:37   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:37 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:25 +0800

> [IPSEC]: Replace x->type->{local,remote}_addr with flags
> 
> The functions local_addr and remote_addr are more than what they're needed
> for.  The same thing can be done easily with flags on the type object.
> This patch does that and simplifies the wrapper functions in xfrm6_policy
> accordingly.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup
  2007-11-07 14:08 ` [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup Herbert Xu
@ 2007-11-14  5:37   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:37 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:26 +0800

> [IPSEC]: Move flow construction into xfrm_dst_lookup
> 
> This patch moves the flow construction from the callers of xfrm_dst_lookup
> into that function.  It also changes xfrm_dst_lookup so that it takes an
> xfrm state as its argument instead of explicit addresses.
> 
> This removes any address-specific logic from the callers of xfrm_dst_lookup
> which is needed to correctly support inter-family transforms.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create
  2007-11-07 14:08 ` [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create Herbert Xu
@ 2007-11-14  5:38   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:38 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:27 +0800

> [IPSEC]: Merge common code into xfrm_bundle_create
> 
> Half of the code in xfrm4_bundle_create and xfrm6_bundle_create are common.
> This patch extracts that logic and puts it into xfrm_bundle_create.  The
> rest of it are then accessed through afinfo.
> 
> As a result this fixes the problem with inter-family transforms where we
> treat every xfrm dst in the bundle as if it belongs to the top family.
> 
> This patch also fixes a long-standing error-path bug where we may free the
> xfrm states twice.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now
  2007-11-07 14:08 ` [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now Herbert Xu
@ 2007-11-14  5:39   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:39 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:28 +0800

> [IPSEC]: Forbid BEET + ipcomp for now
> 
> While BEET can theoretically work with IPComp the current code can't do that
> because it tries to construct a BEET mode tunnel type which doesn't (and
> cannot) exist.  In fact as it is it won't even attach a tunnel object at
> all for BEET which is bogus.
> 
> To support this fully we'd also need to change the policy checks on input
> to recognise a plain tunnel as a legal variant of an optional BEET transform.
> 
> This patch simply fails such constructions for now.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-07 14:08 ` [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section Herbert Xu
  2007-11-07 16:17   ` Ingo Oeser
@ 2007-11-14  5:39   ` David Miller
  1 sibling, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:39 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:29 +0800

> [IPSEC]: Move x->outer_mode->output out of locked section
> 
> RO mode is the only one that requires a locked output function.  So it's
> easier to move the lock into that function rather than requiring everyone
> else to run under the lock.
> 
> In particular, this allows us to move the size check into the output
> function without causing a potential dead-lock should the ICMP error
> somehow hit the same SA on transmission.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp
  2007-11-07 14:08 ` [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp Herbert Xu
@ 2007-11-14  5:40   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:40 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:30 +0800

> [INET]: Give outer DSCP directly to ip*_copy_dscp
> 
> This patch changes the prototype of ipv4_copy_dscp and ipv6_copy_dscp so
> that they directly take the outer DSCP rather than the outer IP header.
> This will help us to unify the code for inter-family tunnels.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output
  2007-11-07 14:08 ` [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output Herbert Xu
@ 2007-11-14  5:41   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:41 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:31 +0800

> [IPSEC]: Separate inner/outer mode processing on output
> 
> With inter-family transforms the inner mode differs from the outer mode.
> Attempting to handle both sides from the same function means that it
> needs to handle both IPv4 and IPv6 which creates duplication and confusion.
> 
> This patch separates the two parts on the output path so that each function
> deals with one family only.
> 
> In particular, the functions xfrm4_extract_output/xfrm6_extract_output
> moves the pertinent fields from the IPv4/IPv6 IP headers into a neutral
> format stored in skb->cb.  This is then used by the outer mode output
> functions to write the outer IP header.  In this way the output function
> no longer has to know about the inner address family.
> 
> Since the extract functions are only called by tunnel modes (the only
> modes that can support inter-family transforms), I've also moved the
> xfrm*_tunnel_check_size calls into them.  This allows the correct ICMP
> message to be sent as opposed to now where you might call icmp_send with
> an IPv6 packet and vice versa.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input
  2007-11-07 14:08 ` [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input Herbert Xu
@ 2007-11-14  5:41   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:41 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:32 +0800

> [IPSEC]: Separate inner/outer mode processing on input
> 
> With inter-family transforms the inner mode differs from the outer mode.
> Attempting to handle both sides from the same function means that it
> needs to handle both IPv4 and IPv6 which creates duplication and confusion.
> 
> This patch separates the two parts on the input path so that each function
> deals with one family only.
> 
> In particular, the functions xfrm4_extract_inut/xfrm6_extract_inut
> moves the pertinent fields from the IPv4/IPv6 IP headers into a neutral
> format stored in skb->cb.  This is then used by the inner mode input
> functions to modify the inner IP header.  In this way the input function
> no longer has to know about the outer address family.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 17/24] [IPV4]: Add ip_local_out
  2007-11-07 14:08 ` [PATCH 17/24] [IPV4]: Add ip_local_out Herbert Xu
@ 2007-11-14  5:42   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:42 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:33 +0800

> [IPV4]: Add ip_local_out
> 
> Most callers of the LOCAL_OUT chain will set the IP packet length
> and header checksum before doing so.  They also share the same output
> function dst_output.
> 
> This patch creates a new function called ip_local_out which does all
> of that and converts the appropriate users over to it.
> 
> Apart from removing duplicate code, it will also help in merging the
> IPsec output path once the same thing is done for IPv6.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 18/24] [IPV6]: Add ip6_local_out
  2007-11-07 14:08 ` [PATCH 18/24] [IPV6]: Add ip6_local_out Herbert Xu
@ 2007-11-14  5:42   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:42 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:34 +0800

> [IPV6]: Add ip6_local_out
> 
> Most callers of the LOCAL_OUT chain will set the IP packet length
> before doing so.  They also share the same output function dst_output.
> 
> This patch creates a new function called ip6_local_out which does all
> of that and converts the appropriate users over to it.
> 
> Apart from removing duplicate code, it will also help in merging the
> IPsec output path.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-07 14:08 ` [PATCH 19/24] [IPSEC]: Merge most of the output path Herbert Xu
  2007-11-08 11:23   ` Patrick McHardy
@ 2007-11-14  5:43   ` David Miller
  1 sibling, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:43 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:36 +0800

> [IPSEC]: Merge most of the output path
> 
> As part of the work on asynchrnous cryptographic operations, we need to
> be able to resume from the spot where they occur.  As such, it helps if
> we isolate them to one spot.
> 
> This patch moves most of the remaining family-specific processing into
> the common output code.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 20/24] [IPSEC]: Add async resume support on output
  2007-11-07 14:08 ` [PATCH 20/24] [IPSEC]: Add async resume support on output Herbert Xu
@ 2007-11-14  5:44   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:44 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:37 +0800

> [IPSEC]: Add async resume support on output
> 
> This patch adds support for async resumptions on output.  To do so, the
> transform would return -EINPROGRESS and subsequently invoke the function
> xfrm_output_resume to resume processing.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

This stuff is so nice now :-)

Applied to net-2.6.25

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

* Re: [PATCH 21/24] [IPSEC]: Merge most of the input path
  2007-11-07 14:08 ` [PATCH 21/24] [IPSEC]: Merge most of the input path Herbert Xu
@ 2007-11-14  5:44   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:44 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:38 +0800

> [IPSEC]: Merge most of the input path
> 
> As part of the work on asynchrnous cryptographic operations, we need to
> be able to resume from the spot where they occur.  As such, it helps if
> we isolate them to one spot.
> 
> This patch moves most of the remaining family-specific processing into
> the common input code.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly
  2007-11-07 14:08 ` [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly Herbert Xu
@ 2007-11-14  5:45   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:45 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:39 +0800

> [IPSEC]: Store xfrm states in security path directly
> 
> As it is xfrm_input first collects a list of xfrm states on the stack
> before storing them in the packet's security path just before it returns.
> For async crypto, this construction presents an obstacle since we may
> need to leave the loop after each transform.
> 
> In fact, it's much easier to just skip the stack completely and always
> store to the security path.  This is proven by the fact that this patch
> actually shrinks the code.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input
  2007-11-07 14:08 ` [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input Herbert Xu
@ 2007-11-14  5:45   ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:45 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:40 +0800

> [IPSEC]: Move integrity stat collection into xfrm_input
> 
> Similar to the moving out of the replay processing on the output,
> this patch moves the integrity stat collectin from x->type->input
> into xfrm_input.
> 
> This would eventually allow transforms such as AH/ESP to be lockless.
> 
> The error value EBADMSG (currently unused in the crypto layer) is used
> to indicate a failed integrity check.  In future this error can be
> directly returned by the crypto layer once we switch to aead algorithms.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 24/24] [IPSEC]: Move state lock into x->type->input
  2007-11-07 14:08 ` [PATCH 24/24] [IPSEC]: Move state lock into x->type->input Herbert Xu
@ 2007-11-14  5:46   ` David Miller
  2007-11-14  6:27     ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input Herbert Xu
  0 siblings, 1 reply; 71+ messages in thread
From: David Miller @ 2007-11-14  5:46 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 07 Nov 2007 22:08:41 +0800

> [IPSEC]: Move state lock into x->type->input
> 
> This patch releases the lock on the state before calling x->type->input.
> It also adds the lock to the spots where they're currently needed.
> 
> Most of those places (all except mip6) are expected to disappear with
> async crypto.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section
  2007-11-13 11:51         ` Herbert Xu
@ 2007-11-14  5:47           ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  5:47 UTC (permalink / raw)
  To: herbert; +Cc: netdev, netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 13 Nov 2007 19:51:19 +0800

> On Tue, Nov 13, 2007 at 03:33:48AM -0800, David Miller wrote:
> >
> > Make 'lastused' an 'unsigned long' (that's all that get_seconds()
> > gives to us anyways), fix up the nla_total_size(x->lastused) thing in
> > net/xfrm/xfrm_user.c, and then you can remove this lock acquisition
> > completely because the store into x->lastused will now be atomic and
> > therefore locks aren't protecting anything.
> 
> Brilliant, make that patch 25/25 :)
> 
> [IPSEC]: Make x->lastused an unsigned long
> 
> Currently x->lastused is u64 which means that it cannot be read/written
> atomically on all architectures.  David Miller observed that the value
> stored in it is only an unsigned long which is always atomic.
> 
> So based on his suggestion this patch changes the internal representation
> from u64 to unsigned long while the user-interface still refers to it as
> u64.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25 :)

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

* [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input
  2007-11-14  5:46   ` David Miller
@ 2007-11-14  6:27     ` Herbert Xu
  2007-11-14  6:28       ` [PATCH 2/2] [IPSEC]: Add async resume support on input Herbert Xu
  2007-11-14  6:32       ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input David Miller
  0 siblings, 2 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-14  6:27 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Tue, Nov 13, 2007 at 09:46:09PM -0800, David Miller wrote:
>
> Applied to net-2.6.25

Thanks for merging Dave!

It looks like I forgot to post the last 2 patches of the series
that complete the async support for the input path.  So here
they are.

[IPSEC]: Remove nhoff from xfrm_input

The nhoff field isn't actually necessary in xfrm_input.  For tunnel mode
transforms we now throw away the output IP header so it makes no sense to
fill in the nexthdr field.  For transport mode we can now let the function
transport_finish do the setting and it knows where the nexthdr field is.

The only other thing that needs the nexthdr field to be set is the header
extraction code.  However, we can simply move the protocol extraction out
of the generic header extraction.

We want to minimise the amount of info we have to carry around between
transforms as this simplifies the resumption process for async crypto.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h      |    1 -
 net/ipv4/xfrm4_input.c  |   11 +++++++----
 net/ipv4/xfrm4_output.c |    2 ++
 net/ipv4/xfrm4_state.c  |    1 -
 net/ipv6/xfrm6_input.c  |    4 +++-
 net/ipv6/xfrm6_output.c |    3 ++-
 net/ipv6/xfrm6_state.c  |    2 --
 net/xfrm/xfrm_input.c   |    5 ++---
 8 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5c457b0..8023795 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -534,7 +534,6 @@ struct xfrm_spi_skb_cb {
 		struct inet6_skb_parm h6;
 	} header;
 
-	unsigned int nhoff;
 	unsigned int daddroff;
 };
 
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index e374903..b19890f 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -41,7 +41,6 @@ drop:
 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 		    int encap_type)
 {
-	XFRM_SPI_SKB_CB(skb)->nhoff = offsetof(struct iphdr, protocol);
 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
 	return xfrm_input(skb, nexthdr, spi, encap_type);
 }
@@ -49,16 +48,20 @@ EXPORT_SYMBOL(xfrm4_rcv_encap);
 
 int xfrm4_transport_finish(struct sk_buff *skb, int async)
 {
+	struct iphdr *iph = ip_hdr(skb);
+
+	iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
+
 #ifdef CONFIG_NETFILTER
 	__skb_push(skb, skb->data - skb_network_header(skb));
-	ip_hdr(skb)->tot_len = htons(skb->len);
-	ip_send_check(ip_hdr(skb));
+	iph->tot_len = htons(skb->len);
+	ip_send_check(iph);
 
 	NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
 		xfrm4_rcv_encap_finish);
 	return 0;
 #else
-	return -ip_hdr(skb)->protocol;
+	return -nexthdr;
 #endif
 }
 
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 2fb4efa..1900200 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -47,6 +47,8 @@ int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 	if (err)
 		return err;
 
+	XFRM_MODE_SKB_CB(skb)->protocol = ip_hdr(skb)->protocol;
+
 	return xfrm4_extract_header(skb);
 }
 
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 3b067e8..d837784 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -56,7 +56,6 @@ int xfrm4_extract_header(struct sk_buff *skb)
 	XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
 	XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
 	XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
-	XFRM_MODE_SKB_CB(skb)->protocol = iph->protocol;
 	memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 3b9eedf..5c006c8 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -23,7 +23,6 @@ int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 
 int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
 {
-	XFRM_SPI_SKB_CB(skb)->nhoff = IP6CB(skb)->nhoff;
 	XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
 	return xfrm_input(skb, nexthdr, spi, 0);
 }
@@ -31,6 +30,9 @@ EXPORT_SYMBOL(xfrm6_rcv_spi);
 
 int xfrm6_transport_finish(struct sk_buff *skb, int async)
 {
+	skb_network_header(skb)[IP6CB(skb)->nhoff] =
+		XFRM_MODE_SKB_CB(skb)->protocol;
+
 #ifdef CONFIG_NETFILTER
 	ipv6_hdr(skb)->payload_len = htons(skb->len);
 	__skb_push(skb, skb->data - skb_network_header(skb));
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index a0a9249..318669a 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -53,7 +53,8 @@ int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 	if (err)
 		return err;
 
-	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
+	XFRM_MODE_SKB_CB(skb)->protocol = ipv6_hdr(skb)->nexthdr;
+
 	return xfrm6_extract_header(skb);
 }
 
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 00360b5..df7e98d 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -178,8 +178,6 @@ int xfrm6_extract_header(struct sk_buff *skb)
 	XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
 	XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
 	XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
-	XFRM_MODE_SKB_CB(skb)->protocol =
-		skb_network_header(skb)[IP6CB(skb)->nhoff];
 	memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
 	       sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 5cad522..cce9d45 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -102,7 +102,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	__be32 seq;
 	struct xfrm_state *x;
 	int decaps = 0;
-	unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
 	unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
 
 	/* Allocate new secpath or COW existing one. */
@@ -157,8 +156,6 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop_unlock;
 		}
 
-		skb_network_header(skb)[nhoff] = nexthdr;
-
 		/* only the first xfrm gets the encap type */
 		encap_type = 0;
 
@@ -170,6 +167,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		spin_unlock(&x->lock);
 
+		XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
+
 		if (x->inner_mode->input(x, skb))
 			goto drop;
 

-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:27     ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input Herbert Xu
@ 2007-11-14  6:28       ` Herbert Xu
  2007-11-14  6:33         ` David Miller
  2007-11-14  6:32       ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input David Miller
  1 sibling, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-14  6:28 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

[IPSEC]: Add async resume support on input

This patch adds support for async resumptions on input.  To do so, the
transform would return -EINPROGRESS and subsequently invoke the function
xfrm_input_resume to resume processing.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/net/xfrm.h     |    1 +
 net/ipv4/xfrm4_input.c |    3 +++
 net/ipv6/xfrm6_input.c |    3 +++
 net/xfrm/xfrm_input.c  |   38 +++++++++++++++++++++++++++++++++-----
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8023795..944fdad 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1138,6 +1138,7 @@ extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi,
 		      int encap_type);
+extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
 extern int xfrm_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(struct sk_buff *skb);
 extern int xfrm4_extract_header(struct sk_buff *skb);
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index b19890f..cd25351 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -61,6 +61,9 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
 		xfrm4_rcv_encap_finish);
 	return 0;
 #else
+	if (async)
+		return xfrm4_rcv_encap_finish(skb);
+
 	return -nexthdr;
 #endif
 }
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 5c006c8..e317d08 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -41,6 +41,9 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
 		ip6_rcv_finish);
 	return -1;
 #else
+	if (async)
+		return ip6_rcv_finish(skb);
+
 	return 1;
 #endif
 }
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index cce9d45..96f42c1 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -101,8 +101,17 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	int err;
 	__be32 seq;
 	struct xfrm_state *x;
+	xfrm_address_t *daddr;
 	int decaps = 0;
-	unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
+	int async = 0;
+
+	/* A negative encap_type indicates async resumption. */
+	if (encap_type < 0) {
+		async = 1;
+		x = skb->sp->xvec[skb->sp->len - 1];
+		seq = XFRM_SKB_CB(skb)->seq;
+		goto resume;
+	}
 
 	/* Allocate new secpath or COW existing one. */
 	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
@@ -116,6 +125,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		skb->sp = sp;
 	}
 
+	daddr = (xfrm_address_t *)(skb_network_header(skb) +
+				   XFRM_SPI_SKB_CB(skb)->daddroff);
+
 	seq = 0;
 	if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
 		goto drop;
@@ -124,9 +136,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		if (skb->sp->len == XFRM_MAX_DEPTH)
 			goto drop;
 
-		x = xfrm_state_lookup((xfrm_address_t *)
-				      (skb_network_header(skb) + daddroff),
-				      spi, nexthdr, AF_INET);
+		x = xfrm_state_lookup(daddr, spi, nexthdr, AF_INET);
 		if (x == NULL)
 			goto drop;
 
@@ -147,8 +157,14 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		spin_unlock(&x->lock);
 
+		XFRM_SKB_CB(skb)->seq = seq;
+
 		nexthdr = x->type->input(x, skb);
 
+		if (nexthdr == -EINPROGRESS)
+			return 0;
+
+resume:
 		spin_lock(&x->lock);
 		if (nexthdr <= 0) {
 			if (nexthdr == -EBADMSG)
@@ -177,6 +193,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			break;
 		}
 
+		/*
+		 * We need the inner address.  However, we only get here for
+		 * transport mode so the outer address is identical.
+		 */
+		daddr = &x->id.daddr;
+
 		err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
 		if (err < 0)
 			goto drop;
@@ -190,7 +212,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		netif_rx(skb);
 		return 0;
 	} else {
-		return x->inner_mode->afinfo->transport_finish(skb, 0);
+		return x->inner_mode->afinfo->transport_finish(skb, async);
 	}
 
 drop_unlock:
@@ -201,6 +223,12 @@ drop:
 }
 EXPORT_SYMBOL(xfrm_input);
 
+int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
+{
+	return xfrm_input(skb, nexthdr, 0, -1);
+}
+EXPORT_SYMBOL(xfrm_input_resume);
+
 void __init xfrm_input_init(void)
 {
 	secpath_cachep = kmem_cache_create("secpath_cache",
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input
  2007-11-14  6:27     ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input Herbert Xu
  2007-11-14  6:28       ` [PATCH 2/2] [IPSEC]: Add async resume support on input Herbert Xu
@ 2007-11-14  6:32       ` David Miller
  1 sibling, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  6:32 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 14 Nov 2007 14:27:58 +0800

> [IPSEC]: Remove nhoff from xfrm_input
> 
> The nhoff field isn't actually necessary in xfrm_input.  For tunnel mode
> transforms we now throw away the output IP header so it makes no sense to
> fill in the nexthdr field.  For transport mode we can now let the function
> transport_finish do the setting and it knows where the nexthdr field is.
> 
> The only other thing that needs the nexthdr field to be set is the header
> extraction code.  However, we can simply move the protocol extraction out
> of the generic header extraction.
> 
> We want to minimise the amount of info we have to carry around between
> transforms as this simplifies the resumption process for async crypto.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-2.6.25

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:28       ` [PATCH 2/2] [IPSEC]: Add async resume support on input Herbert Xu
@ 2007-11-14  6:33         ` David Miller
  2007-11-14  6:36           ` Herbert Xu
  2007-11-14  9:05           ` Patrick McHardy
  0 siblings, 2 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  6:33 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 14 Nov 2007 14:28:34 +0800

> [IPSEC]: Add async resume support on input
> 
> This patch adds support for async resumptions on input.  To do so, the
> transform would return -EINPROGRESS and subsequently invoke the function
> xfrm_input_resume to resume processing.
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Also applied to net-2.6.25, thanks.

I'll work on integrating Patrick's NF_INET_* patch next.

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:33         ` David Miller
@ 2007-11-14  6:36           ` Herbert Xu
  2007-11-14  6:38             ` David Miller
  2007-11-14  9:58             ` David Miller
  2007-11-14  9:05           ` Patrick McHardy
  1 sibling, 2 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-14  6:36 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Tue, Nov 13, 2007 at 10:33:56PM -0800, David Miller wrote:
>
> Also applied to net-2.6.25, thanks.
> 
> I'll work on integrating Patrick's NF_INET_* patch next.

Thanks! With that you would be able to remove the nf_post_routing
field from xfrm_state_afinfo.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:36           ` Herbert Xu
@ 2007-11-14  6:38             ` David Miller
  2007-11-14  6:41               ` Herbert Xu
  2007-11-14  9:58             ` David Miller
  1 sibling, 1 reply; 71+ messages in thread
From: David Miller @ 2007-11-14  6:38 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 14 Nov 2007 14:36:58 +0800

> On Tue, Nov 13, 2007 at 10:33:56PM -0800, David Miller wrote:
> >
> > Also applied to net-2.6.25, thanks.
> > 
> > I'll work on integrating Patrick's NF_INET_* patch next.
> 
> Thanks! With that you would be able to remove the nf_post_routing
> field from xfrm_state_afinfo.

We need to fix something else up first :-)

net/ipv4/xfrm4_input.c: In function 'xfrm4_transport_finish':
net/ipv4/xfrm4_input.c:65: error: implicit declaration of function 'xfrm4_rcv_encap_finish'
net/ipv4/xfrm4_input.c:67: error: 'nexthdr' undeclared (first use in this function)
net/ipv4/xfrm4_input.c:67: error: (Each undeclared identifier is reported only once
net/ipv4/xfrm4_input.c:67: error: for each function it appears in.)
make[2]: *** [net/ipv4/xfrm4_input.o] Error 1
make[1]: *** [net/ipv4] Error 2
make: *** [net] Error 2

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:38             ` David Miller
@ 2007-11-14  6:41               ` Herbert Xu
  2007-11-14  6:46                 ` David Miller
  0 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-14  6:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Tue, Nov 13, 2007 at 10:38:03PM -0800, David Miller wrote:
> 
> We need to fix something else up first :-)
> 
> net/ipv4/xfrm4_input.c: In function 'xfrm4_transport_finish':
> net/ipv4/xfrm4_input.c:65: error: implicit declaration of function 'xfrm4_rcv_encap_finish'
> net/ipv4/xfrm4_input.c:67: error: 'nexthdr' undeclared (first use in this function)
> net/ipv4/xfrm4_input.c:67: error: (Each undeclared identifier is reported only once
> net/ipv4/xfrm4_input.c:67: error: for each function it appears in.)
> make[2]: *** [net/ipv4/xfrm4_input.o] Error 1
> make[1]: *** [net/ipv4] Error 2
> make: *** [net] Error 2

No netfilter, surely not :)

Does this patch help?

[IPSEC]: Fix build problem with netfilter off

The function xfrm4_rcv_encap_finish is now used even with NETFILTER
off.  So we need to remove the ifdefs around i.t

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index cd25351..7795938 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -21,7 +21,6 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 	return xfrm4_extract_header(skb);
 }
 
-#ifdef CONFIG_NETFILTER
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
 	if (skb->dst == NULL) {
@@ -36,7 +35,6 @@ drop:
 	kfree_skb(skb);
 	return NET_RX_DROP;
 }
-#endif
 
 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 		    int encap_type)

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:41               ` Herbert Xu
@ 2007-11-14  6:46                 ` David Miller
  0 siblings, 0 replies; 71+ messages in thread
From: David Miller @ 2007-11-14  6:46 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 14 Nov 2007 14:41:54 +0800

> On Tue, Nov 13, 2007 at 10:38:03PM -0800, David Miller wrote:
> > 
> > We need to fix something else up first :-)
> > 
> > net/ipv4/xfrm4_input.c: In function 'xfrm4_transport_finish':
> > net/ipv4/xfrm4_input.c:65: error: implicit declaration of function 'xfrm4_rcv_encap_finish'
> > net/ipv4/xfrm4_input.c:67: error: 'nexthdr' undeclared (first use in this function)
> > net/ipv4/xfrm4_input.c:67: error: (Each undeclared identifier is reported only once
> > net/ipv4/xfrm4_input.c:67: error: for each function it appears in.)
> > make[2]: *** [net/ipv4/xfrm4_input.o] Error 1
> > make[1]: *** [net/ipv4] Error 2
> > make: *** [net] Error 2
> 
> No netfilter, surely not :)
> 
> Does this patch help?
> 
> [IPSEC]: Fix build problem with netfilter off
> 
> The function xfrm4_rcv_encap_finish is now used even with NETFILTER
> off.  So we need to remove the ifdefs around i.t
> 
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Nope, it needs a little more than that :-)  I just checked
in the following:

>From befb75b758f8a4d4de4c535db9f845726eae05eb Mon Sep 17 00:00:00 2001
From: David S. Miller <davem@sunset.davemloft.net>
Date: Tue, 13 Nov 2007 22:45:41 -0800
Subject: [PATCH] [IPV4] xfrm4_input.c: Fix build in non-NETFILTER case.

Based in part on a patch from Herbert Xu.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/ipv4/xfrm4_input.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index cd25351..d5890c8 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -21,7 +21,6 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 	return xfrm4_extract_header(skb);
 }
 
-#ifdef CONFIG_NETFILTER
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
 	if (skb->dst == NULL) {
@@ -36,7 +35,6 @@ drop:
 	kfree_skb(skb);
 	return NET_RX_DROP;
 }
-#endif
 
 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
 		    int encap_type)
@@ -64,7 +62,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
 	if (async)
 		return xfrm4_rcv_encap_finish(skb);
 
-	return -nexthdr;
+	return -iph->protocol;
 #endif
 }
 
-- 
1.5.3.5


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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:33         ` David Miller
  2007-11-14  6:36           ` Herbert Xu
@ 2007-11-14  9:05           ` Patrick McHardy
  1 sibling, 0 replies; 71+ messages in thread
From: Patrick McHardy @ 2007-11-14  9:05 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, netdev

David Miller wrote:
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Wed, 14 Nov 2007 14:28:34 +0800
> 
>> [IPSEC]: Add async resume support on input
>>
>> This patch adds support for async resumptions on input.  To do so, the
>> transform would return -EINPROGRESS and subsequently invoke the function
>> xfrm_input_resume to resume processing.
>>
>> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
> 
> Also applied to net-2.6.25, thanks.
> 
> I'll work on integrating Patrick's NF_INET_* patch next.


I'm rebasing my netfilter tree to net-2.6.25, so unless you're
already working on this, I can take care of that.

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-08 11:29     ` Herbert Xu
@ 2007-11-14  9:07       ` David Miller
  2007-11-14  9:14         ` Patrick McHardy
  0 siblings, 1 reply; 71+ messages in thread
From: David Miller @ 2007-11-14  9:07 UTC (permalink / raw)
  To: herbert; +Cc: kaber, netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 8 Nov 2007 19:29:21 +0800

> On Thu, Nov 08, 2007 at 12:23:29PM +0100, Patrick McHardy wrote:
> >
> > We have a few places that go though the trouble of selecting the
> > "correct" hook value for the address family, even though the numerical
> > values are identical. How about we just get rid of the different
> > naming and use NF_INET_... for both IPv4 and IPv6?
> 
> Nice work! Thanks Patrick.

Yeah I like it too, applied to net-2.6.25

I had to do some minor rediffing to make it go in cleanly after
Herbert's work, so I'm doing some build testing before I push this bit
onto kernel.org

Thanks again Patrick.

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-14  9:07       ` David Miller
@ 2007-11-14  9:14         ` Patrick McHardy
  2007-11-14  9:16           ` Herbert Xu
  0 siblings, 1 reply; 71+ messages in thread
From: Patrick McHardy @ 2007-11-14  9:14 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, netdev

David Miller wrote:
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Thu, 8 Nov 2007 19:29:21 +0800
> 
>> On Thu, Nov 08, 2007 at 12:23:29PM +0100, Patrick McHardy wrote:
>>> We have a few places that go though the trouble of selecting the
>>> "correct" hook value for the address family, even though the numerical
>>> values are identical. How about we just get rid of the different
>>> naming and use NF_INET_... for both IPv4 and IPv6?
>> Nice work! Thanks Patrick.
> 
> Yeah I like it too, applied to net-2.6.25
> 
> I had to do some minor rediffing to make it go in cleanly after
> Herbert's work, so I'm doing some build testing before I push this bit
> onto kernel.org


Thanks Dave. As luck would have it, my HIFN card should arrive
within the next few hours, so I'll try to convert esp over to
async crypto and give this all some good testing :)


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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-14  9:14         ` Patrick McHardy
@ 2007-11-14  9:16           ` Herbert Xu
  2007-11-14  9:19             ` Patrick McHardy
  0 siblings, 1 reply; 71+ messages in thread
From: Herbert Xu @ 2007-11-14  9:16 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David Miller, netdev

On Wed, Nov 14, 2007 at 10:14:27AM +0100, Patrick McHardy wrote:
>
> Thanks Dave. As luck would have it, my HIFN card should arrive
> within the next few hours, so I'll try to convert esp over to
> async crypto and give this all some good testing :)

Actually I'm already working on that :)

I'm not just converting ESP over to async, I'm also changing
it to use the AEAD interface which is needed for it to properly
support algorithms such as CCM.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH 19/24] [IPSEC]: Merge most of the output path
  2007-11-14  9:16           ` Herbert Xu
@ 2007-11-14  9:19             ` Patrick McHardy
  0 siblings, 0 replies; 71+ messages in thread
From: Patrick McHardy @ 2007-11-14  9:19 UTC (permalink / raw)
  To: Herbert Xu; +Cc: David Miller, netdev

Herbert Xu wrote:
> On Wed, Nov 14, 2007 at 10:14:27AM +0100, Patrick McHardy wrote:
>> Thanks Dave. As luck would have it, my HIFN card should arrive
>> within the next few hours, so I'll try to convert esp over to
>> async crypto and give this all some good testing :)
> 
> Actually I'm already working on that :)
> 
> I'm not just converting ESP over to async, I'm also changing
> it to use the AEAD interface which is needed for it to properly
> support algorithms such as CCM.


Great. If you're looking for testers, just send it over :)

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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  6:36           ` Herbert Xu
  2007-11-14  6:38             ` David Miller
@ 2007-11-14  9:58             ` David Miller
  2007-11-14 10:04               ` Herbert Xu
  1 sibling, 1 reply; 71+ messages in thread
From: David Miller @ 2007-11-14  9:58 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 14 Nov 2007 14:36:58 +0800

> On Tue, Nov 13, 2007 at 10:33:56PM -0800, David Miller wrote:
> >
> > Also applied to net-2.6.25, thanks.
> > 
> > I'll work on integrating Patrick's NF_INET_* patch next.
> 
> Thanks! With that you would be able to remove the nf_post_routing
> field from xfrm_state_afinfo.

Done, and checked into net-2.6.25:

>From d15f51674f6e9985c84f221a7fd1026eafbe42c8 Mon Sep 17 00:00:00 2001
From: David S. Miller <davem@sunset.davemloft.net>
Date: Wed, 14 Nov 2007 01:57:47 -0800
Subject: [PATCH] [IPSEC]: Kill afinfo->nf_post_routing

After changeset:

	[NETFILTER]: Introduce NF_INET_ hook values

It always evaluates to NF_INET_POST_ROUTING.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/xfrm.h     |    1 -
 net/ipv4/xfrm4_state.c |    1 -
 net/ipv6/xfrm6_state.c |    1 -
 net/xfrm/xfrm_output.c |    2 +-
 4 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index e184c11..99251b7 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -259,7 +259,6 @@ struct xfrm_state_afinfo {
 	unsigned int		family;
 	unsigned int		proto;
 	unsigned int		eth_proto;
-	unsigned int		nf_post_routing;
 	struct module		*owner;
 	struct xfrm_type	*type_map[IPPROTO_MAX];
 	struct xfrm_mode	*mode_map[XFRM_MODE_MAX];
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 2961135..fdeebe6 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -66,7 +66,6 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
 	.proto			= IPPROTO_IPIP,
 	.eth_proto		= htons(ETH_P_IP),
-	.nf_post_routing	= NF_INET_POST_ROUTING,
 	.owner			= THIS_MODULE,
 	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index 29e0d25..a7a7e8f 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -188,7 +188,6 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
 	.family			= AF_INET6,
 	.proto			= IPPROTO_IPV6,
 	.eth_proto		= htons(ETH_P_IPV6),
-	.nf_post_routing	= NF_INET_POST_ROUTING,
 	.owner			= THIS_MODULE,
 	.init_tempsel		= __xfrm6_init_tempsel,
 	.tmpl_sort		= __xfrm6_tmpl_sort,
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 048d240..3c277a4 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -113,7 +113,7 @@ int xfrm_output_resume(struct sk_buff *skb, int err)
 			return dst_output(skb);
 
 		err = nf_hook(x->inner_mode->afinfo->family,
-			      x->inner_mode->afinfo->nf_post_routing, skb,
+			      NF_INET_POST_ROUTING, skb,
 			      NULL, skb->dst->dev, xfrm_output2);
 		if (unlikely(err != 1))
 			goto out;
-- 
1.5.3.5


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

* Re: [PATCH 2/2] [IPSEC]: Add async resume support on input
  2007-11-14  9:58             ` David Miller
@ 2007-11-14 10:04               ` Herbert Xu
  0 siblings, 0 replies; 71+ messages in thread
From: Herbert Xu @ 2007-11-14 10:04 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Wed, Nov 14, 2007 at 01:58:12AM -0800, David Miller wrote:
>
> >From d15f51674f6e9985c84f221a7fd1026eafbe42c8 Mon Sep 17 00:00:00 2001
> From: David S. Miller <davem@sunset.davemloft.net>
> Date: Wed, 14 Nov 2007 01:57:47 -0800
> Subject: [PATCH] [IPSEC]: Kill afinfo->nf_post_routing
> 
> After changeset:
> 
> 	[NETFILTER]: Introduce NF_INET_ hook values
> 
> It always evaluates to NF_INET_POST_ROUTING.
> 
> Signed-off-by: David S. Miller <davem@davemloft.net>

Thank you!
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

end of thread, other threads:[~2007-11-14 10:15 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-07 14:07 [0/24] Merge IPv4/IPv6 IPsec bundle creation and input/ouput Herbert Xu
2007-11-07 14:08 ` [PATCH 1/24] [IPV6]: Only set nfheader_len for top xfrm dst Herbert Xu
2007-11-14  5:32   ` David Miller
2007-11-07 14:08 ` [PATCH 2/24] [IPSEC]: Use dst->header_len when resizing on output Herbert Xu
2007-11-14  5:33   ` David Miller
2007-11-07 14:08 ` [PATCH 3/24] [IPV6]: Move nfheader_len into rt6_info Herbert Xu
2007-11-14  5:33   ` David Miller
2007-11-07 14:08 ` [PATCH 4/24] [NET]: Eliminate duplicate copies of dst_discard Herbert Xu
2007-11-14  5:34   ` David Miller
2007-11-07 14:08 ` [PATCH 5/24] [NET]: Remove unnecessary inclusion of dst.h Herbert Xu
2007-11-14  5:34   ` David Miller
2007-11-07 14:08 ` [PATCH 6/24] [IPSEC]: Only set neighbour on top xfrm dst Herbert Xu
2007-11-14  5:35   ` David Miller
2007-11-07 14:08 ` [PATCH 7/24] [IPSEC]: Set dst->input to dst_discard Herbert Xu
2007-11-14  5:35   ` David Miller
2007-11-07 14:08 ` [PATCH 8/24] [IPSEC]: Make sure idev is consistent with dev in xfrm_dst Herbert Xu
2007-11-14  5:36   ` David Miller
2007-11-07 14:08 ` [PATCH 9/24] [IPSEC]: Replace x->type->{local,remote}_addr with flags Herbert Xu
2007-11-14  5:37   ` David Miller
2007-11-07 14:08 ` [PATCH 10/24] [IPSEC]: Move flow construction into xfrm_dst_lookup Herbert Xu
2007-11-14  5:37   ` David Miller
2007-11-07 14:08 ` [PATCH 11/24] [IPSEC]: Merge common code into xfrm_bundle_create Herbert Xu
2007-11-14  5:38   ` David Miller
2007-11-07 14:08 ` [PATCH 12/24] [IPSEC]: Forbid BEET + ipcomp for now Herbert Xu
2007-11-14  5:39   ` David Miller
2007-11-07 14:08 ` [PATCH 13/24] [IPSEC]: Move x->outer_mode->output out of locked section Herbert Xu
2007-11-07 16:17   ` Ingo Oeser
2007-11-08  0:39     ` Herbert Xu
2007-11-13 11:33       ` David Miller
2007-11-13 11:51         ` Herbert Xu
2007-11-14  5:47           ` David Miller
2007-11-14  5:39   ` David Miller
2007-11-07 14:08 ` [PATCH 14/24] [INET]: Give outer DSCP directly to ip*_copy_dscp Herbert Xu
2007-11-14  5:40   ` David Miller
2007-11-07 14:08 ` [PATCH 15/24] [IPSEC]: Separate inner/outer mode processing on output Herbert Xu
2007-11-14  5:41   ` David Miller
2007-11-07 14:08 ` [PATCH 16/24] [IPSEC]: Separate inner/outer mode processing on input Herbert Xu
2007-11-14  5:41   ` David Miller
2007-11-07 14:08 ` [PATCH 17/24] [IPV4]: Add ip_local_out Herbert Xu
2007-11-14  5:42   ` David Miller
2007-11-07 14:08 ` [PATCH 18/24] [IPV6]: Add ip6_local_out Herbert Xu
2007-11-14  5:42   ` David Miller
2007-11-07 14:08 ` [PATCH 19/24] [IPSEC]: Merge most of the output path Herbert Xu
2007-11-08 11:23   ` Patrick McHardy
2007-11-08 11:29     ` Herbert Xu
2007-11-14  9:07       ` David Miller
2007-11-14  9:14         ` Patrick McHardy
2007-11-14  9:16           ` Herbert Xu
2007-11-14  9:19             ` Patrick McHardy
2007-11-14  5:43   ` David Miller
2007-11-07 14:08 ` [PATCH 20/24] [IPSEC]: Add async resume support on output Herbert Xu
2007-11-14  5:44   ` David Miller
2007-11-07 14:08 ` [PATCH 21/24] [IPSEC]: Merge most of the input path Herbert Xu
2007-11-14  5:44   ` David Miller
2007-11-07 14:08 ` [PATCH 22/24] [IPSEC]: Store xfrm states in security path directly Herbert Xu
2007-11-14  5:45   ` David Miller
2007-11-07 14:08 ` [PATCH 23/24] [IPSEC]: Move integrity stat collection into xfrm_input Herbert Xu
2007-11-14  5:45   ` David Miller
2007-11-07 14:08 ` [PATCH 24/24] [IPSEC]: Move state lock into x->type->input Herbert Xu
2007-11-14  5:46   ` David Miller
2007-11-14  6:27     ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input Herbert Xu
2007-11-14  6:28       ` [PATCH 2/2] [IPSEC]: Add async resume support on input Herbert Xu
2007-11-14  6:33         ` David Miller
2007-11-14  6:36           ` Herbert Xu
2007-11-14  6:38             ` David Miller
2007-11-14  6:41               ` Herbert Xu
2007-11-14  6:46                 ` David Miller
2007-11-14  9:58             ` David Miller
2007-11-14 10:04               ` Herbert Xu
2007-11-14  9:05           ` Patrick McHardy
2007-11-14  6:32       ` [PATCH 1/2] [IPSEC]: Remove nhoff from xfrm_input David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).