r1051 - in trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian: . patches
Simon Horman
horms@haydn.debian.org
Thu, 12 Aug 2004 19:31:44 -0600
Author: horms
Date: 2004-08-12 19:31:41 -0600 (Thu, 12 Aug 2004)
New Revision: 1051
Modified:
trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/changelog
trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/patches/patch-2.4.26-6
Log:
Updated xfrm from 2.6 bitkeeper
Modified: trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/changelog
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/changelog 2004-08-13 00:36:06 UTC (rev 1050)
+++ trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/changelog 2004-08-13 01:31:41 UTC (rev 1051)
@@ -103,8 +103,59 @@
. include/linux/fs.h
. kernel/ksyms.c
. mm/filemap.c
+ * Various updates to xfrm.
+ Brings 2.4.26 backport up to date with the 2.6 tree
+ - Lock in Policy Timer. Herbert Xu
+ . ChangeSet1.1722.10.22 (linux-2.5 tree)
+ . net/xfrm/xfrm_policy.c
+ - Fix memory leak in xfrm_state_find. Herbert Xu
+ . ChangeSet1.1722.15.5 (linux-2.5 tree)
+ . net/xfrm/xfrm_state.c
+ - Fix outdated comment in __xfrm_state_delete. Herbert Xu
+ ChangeSet1.1722.15.6 (linux-2.5 tree)
+ . net/xfrm/xfrm_state.c
+ - Use add_timer() in xfrm_state_find.. Herbert Xu
+ ChangeSet1.1722.15.7 (linux-2.5 tree)
+ . net/xfrm/xfrm_state.c
+ - Fix dependancy issues for CONFIG_IPV6=m. Hideaki Yoshifuji
+ . ChangeSet1.1722.172.4 (linux-2.5 tree)
+ . include/net/xfrm.h
+ . net/xfrm/Makefile
+ . net/xfrm/xfrm_export.c
+ . net/xfrm/xfrm_output.c
+ . net/xfrm/xfrm_state.c
+ - Fix counting in __xfrmN_bundle_create(). Herbert Xu
+ . ChangeSet1.1722.2.41 (linux-2.5 tree)
+ . net/ipv4/xfrm4_policy.c
+ . net/ipv6/xfrm6_policy.c
+ . net/xfrm/xfrm_policy.c
+ - Fix state modifications in xfrm_state_update(). Herbert Xu
+ . ChangeSet1.1722.6.4 (linux-2.5 tree)
+ . net/xfrm/xfrm_state.c
+ - Fix xfrm_tunnel leak. Herbert Xu
+ ChangeSet1.1722.74.3 (linux-2.5 tree)
+ . net/ipv4/ipcomp.c
+ . net/xfrm/xfrm_state.c
+ - Add FLUSHSA and FLUSHPOLICY. Herbert Xu
+ . ChangeSet1.1784.11.13 (linux-2.5 tree)
+ . include/linux/xfrm.h
+ . net/xfrm/xfrm_user.c
+ - Missing unlock in policy timer. Herbert Xu
+ ChangeSet1.1807.2.27 (linux-2.5 tree)
+ . net/xfrm/xfrm_policy.c
+ - Wake up km_waitq once per gc-run instead of once per state.
+ Patrick McHardy, David Miller
+ . ChangeSet1.1807.13.20 (linux-2.5 tree)
+ . net/xfrm/xfrm_state.c
+ - Add missing unlock in policy timer
+ . ChangeSet1.1807.13.3
+ . net/xfrm/xfrm_policy.c
+ - Fix adding SA through netlink. Masahide Nakamura
+ . ChangeSet1.1807.19.12
+ . algo-detect.patch
+ . linux26/net/xfrm/xfrm_user.c
- -- Simon Horman <horms@debian.org> Thu, 12 Aug 2004 14:49:38 +0900
+ -- Simon Horman <horms@debian.org> Thu, 12 Aug 2004 15:38:33 +0900
kernel-source-2.4.26 (2.4.26-5) unstable; urgency=high
Modified: trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/patches/patch-2.4.26-6
===================================================================
--- trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/patches/patch-2.4.26-6 2004-08-13 00:36:06 UTC (rev 1050)
+++ trunk/kernel-2.4/source/kernel-source-2.4.26-2.4.26/debian/patches/patch-2.4.26-6 2004-08-13 01:31:41 UTC (rev 1051)
@@ -5519,3 +5519,814 @@
do {
unsigned long index, offset;
+#ChangeSet1.1722.10.22
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/22 13:35:20-07:00 herbet@gondor.apana.org.au
+# [IPSEC]: Lock policy in policy timer.
+#
+# net/xfrm/xfrm_policy.c
+# 2004/05/22 13:35:06-07:00 herbet@gondor.apana.org.au +3 -0
+# [IPSEC]: Lock policy in policy timer.
+#
+diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+--- a/net/xfrm/xfrm_policy.c 2004-07-28 22:26:39 -07:00
++++ b/net/xfrm/xfrm_policy.c 2004-07-28 22:26:39 -07:00
+@@ -148,6 +148,8 @@
+ int warn = 0;
+ int dir;
+
++ read_lock(&xp->lock);
++
+ if (xp->dead)
+ goto out;
+
+@@ -197,6 +199,7 @@
+ xfrm_pol_hold(xp);
+
+ out:
++ read_unlock(&xp->lock);
+ xfrm_pol_put(xp);
+ return;
+
+#ChangeSet1.1722.15.5
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/25 11:01:22-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Do not leak entries in xfrm_state_find.
+#
+# In xfrm_state_find, the larval state never actually matures with
+# Openswan so it only ever gets deleted by the timer which means
+# that the time crash can't happen :) It becomes a (possible) memory
+# leak instead.
+#
+# net/xfrm/xfrm_state.c
+# 2004/05/25 11:01:09-07:00 herbert@gondor.apana.org.au +6 -10
+# [IPSEC]: Do not leak entries in xfrm_state_find.
+#
+# In xfrm_state_find, the larval state never actually matures with
+# Openswan so it only ever gets deleted by the timer which means
+# that the time crash can't happen :) It becomes a (possible) memory
+# leak instead.
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:51:45 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:51:45 -07:00
+@@ -331,14 +331,8 @@
+ }
+ }
+
+- if (best) {
+- xfrm_state_hold(best);
+- spin_unlock_bh(&xfrm_state_lock);
+- return best;
+- }
+-
+- x = NULL;
+- if (!error && !acquire_in_progress &&
++ x = best;
++ if (!x && !error && !acquire_in_progress &&
+ ((x = xfrm_state_alloc()) != NULL)) {
+ /* Initialize temporary selector matching only
+ * to current session. */
+@@ -363,10 +357,12 @@
+ error = 1;
+ }
+ }
+- spin_unlock_bh(&xfrm_state_lock);
+- if (!x)
++ if (x)
++ xfrm_state_hold(x);
++ else
+ *err = acquire_in_progress ? -EAGAIN :
+ (error ? -ESRCH : -ENOMEM);
++ spin_unlock_bh(&xfrm_state_lock);
+ return x;
+ }
+
+#ChangeSet1.1722.15.6
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/25 11:02:07-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Fix outdated comment in __xfrm_state_delete.
+#
+# net/xfrm/xfrm_state.c
+# 2004/05/25 11:01:54-07:00 herbert@gondor.apana.org.au +3 -7
+# [IPSEC]: Fix outdated comment in __xfrm_state_delete.
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:50:36 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:50:36 -07:00
+@@ -221,13 +221,9 @@
+ if (atomic_read(&x->refcnt) > 2)
+ xfrm_flush_bundles();
+
+- /* All xfrm_state objects are created by one of two possible
+- * paths:
+- *
+- * 2) xfrm_state_lookup --> xfrm_state_insert
+- *
+- * The xfrm_state_lookup or xfrm_state_alloc call gives a
+- * reference, and that is what we are dropping here.
++ /* All xfrm_state objects are created by xfrm_state_alloc.
++ * The xfrm_state_alloc call gives a reference, and that
++ * is what we are dropping here.
+ */
+ atomic_dec(&x->refcnt);
+ }
+#ChangeSet1.1722.15.7
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/25 11:02:48-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Use add_timer() in xfrm_state_find.
+#
+# net/xfrm/xfrm_state.c
+# 2004/05/25 11:02:35-07:00 herbert@gondor.apana.org.au +2 -1
+# [IPSEC]: Use add_timer() in xfrm_state_find.
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:45:32 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:45:32 -07:00
+@@ -345,7 +345,8 @@
+ }
+ x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES;
+ xfrm_state_hold(x);
+- mod_timer(&x->timer, XFRM_ACQ_EXPIRES*HZ);
++ x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ;
++ add_timer(&x->timer);
+ } else {
+ x->km.state = XFRM_STATE_DEAD;
+ xfrm_state_put(x);
+#ChangeSet1.1722.172.4
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/06/18 15:21:08+09:00 yoshfuji@linux-ipv6.org
+# [XFRM] fix dependency issues for CONFIG_IPV6=m.
+#
+# include/net/xfrm.h
+# 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1
+# [XFRM] split up xfrm_check_output() into two functions to solve dependency issues.
+#
+# net/xfrm/Makefile
+# 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1
+# [XFRM] split up xfrm_check_output() into two functions to solve dependency issues.
+#
+# net/xfrm/xfrm_export.c
+# 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +1 -1
+# [XFRM] split up xfrm_check_output() into two functions to solve dependency issues.
+#
+# net/xfrm/xfrm_state.c
+# 2004/06/18 15:20:58+09:00 yoshfuji@linux-ipv6.org +10 -0
+# [XFRM] split up xfrm_check_output() into two functions to solve dependency issues.
+#
+diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h
+--- a/include/net/xfrm.h 2004-07-28 21:35:50 -07:00
++++ b/include/net/xfrm.h 2004-07-28 21:35:50 -07:00
+@@ -816,7 +816,7 @@
+ extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
+ extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+ extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
+-extern int xfrm_check_output(struct xfrm_state *x, struct sk_buff *skb, unsigned short family);
++extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
+ extern int xfrm4_rcv(struct sk_buff *skb);
+ extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
+ extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
+diff -Nru a/net/xfrm/Makefile b/net/xfrm/Makefile
+--- a/net/xfrm/Makefile 2004-07-28 21:35:50 -07:00
++++ b/net/xfrm/Makefile 2004-07-28 21:35:50 -07:00
+@@ -2,7 +2,7 @@
+ # Makefile for the XFRM subsystem.
+ #
+
+-obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o \
++obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o \
+ xfrm_export.o
+ obj-$(CONFIG_XFRM_USER) += xfrm_user.o
+
+diff -Nru a/net/xfrm/xfrm_export.c b/net/xfrm/xfrm_export.c
+--- a/net/xfrm/xfrm_export.c 2004-07-28 21:35:50 -07:00
++++ b/net/xfrm/xfrm_export.c 2004-07-28 21:35:50 -07:00
+@@ -18,6 +18,7 @@
+ EXPORT_SYMBOL(xfrm_state_update);
+ EXPORT_SYMBOL(xfrm_state_check_expire);
+ EXPORT_SYMBOL(xfrm_state_check_space);
++EXPORT_SYMBOL(xfrm_state_check);
+ EXPORT_SYMBOL(xfrm_state_lookup);
+ EXPORT_SYMBOL(xfrm_state_register_afinfo);
+ EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
+@@ -27,7 +28,6 @@
+ EXPORT_SYMBOL(xfrm_replay_check);
+ EXPORT_SYMBOL(xfrm_replay_advance);
+ EXPORT_SYMBOL(xfrm_check_selectors);
+-EXPORT_SYMBOL(xfrm_check_output);
+ EXPORT_SYMBOL(__secpath_destroy);
+ EXPORT_SYMBOL(secpath_dup);
+ EXPORT_SYMBOL(xfrm_get_acqseq);
+diff -Nru a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
+--- a/net/xfrm/xfrm_output.c 2004-07-28 21:35:50 -07:00
++++ /dev/null Wed Dec 31 16:00:00 196900
+@@ -1,46 +0,0 @@
+-/*
+- * generic xfrm output routines
+- *
+- * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License as published by the Free
+- * Software Foundation; either version 2 of the License, or (at your option)
+- * any later version.
+- */
+-#include <linux/config.h>
+-#include <linux/kernel.h>
+-#include <linux/skbuff.h>
+-#include <net/xfrm.h>
+-
+-int xfrm_check_output(struct xfrm_state *x,
+- struct sk_buff *skb, unsigned short family)
+-{
+- int err;
+-
+- err = xfrm_state_check_expire(x);
+- if (err)
+- goto out;
+-
+- if (x->props.mode) {
+- switch (family) {
+- case AF_INET:
+- err = xfrm4_tunnel_check_size(skb);
+- break;
+-
+- case AF_INET6:
+- err = xfrm6_tunnel_check_size(skb);
+- break;
+-
+- default:
+- err = -EINVAL;
+- }
+-
+- if (err)
+- goto out;
+- }
+-
+- err = xfrm_state_check_space(x, skb);
+-out:
+- return err;
+-}
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:35:50 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:35:50 -07:00
+@@ -531,6 +531,16 @@
+ return 0;
+ }
+
++int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
++{
++ int err = xfrm_state_check_expire(x);
++ if (err < 0)
++ goto err;
++ err = xfrm_state_check_space(x, skb);
++err:
++ return err;
++}
++
+ struct xfrm_state *
+ xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
+ unsigned short family)
+#ChangeSet1.1722.2.41
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/29 12:46:04-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Fix ref counting in __xfrmN_bundle_create().
+#
+# net/ipv4/xfrm4_policy.c
+# 2004/05/29 12:45:43-07:00 herbert@gondor.apana.org.au +2 -1
+# [IPSEC]: Fix ref counting in __xfrmN_bundle_create().
+#
+# net/ipv6/xfrm6_policy.c
+# 2004/05/29 12:45:43-07:00 herbert@gondor.apana.org.au +2 -1
+# [IPSEC]: Fix ref counting in __xfrmN_bundle_create().
+#
+# net/xfrm/xfrm_policy.c
+# 2004/05/29 12:45:43-07:00 herbert@gondor.apana.org.au +2 -0
+# [IPSEC]: Fix ref counting in __xfrmN_bundle_create().
+#
+diff -Nru a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
+--- a/net/ipv4/xfrm4_policy.c 2004-07-28 23:04:01 -07:00
++++ b/net/ipv4/xfrm4_policy.c 2004-07-28 23:04:01 -07:00
+@@ -90,7 +90,6 @@
+ goto error;
+ }
+
+- dst1->xfrm = xfrm[i];
+ if (!dst)
+ dst = dst1;
+ else {
+@@ -120,10 +119,12 @@
+ dst_hold(&rt->u.dst);
+ }
+ dst_prev->child = &rt->u.dst;
++ i = 0;
+ for (dst_prev = dst; 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);
+diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+--- a/net/ipv6/xfrm6_policy.c 2004-07-28 23:04:01 -07:00
++++ b/net/ipv6/xfrm6_policy.c 2004-07-28 23:04:01 -07:00
+@@ -107,7 +107,6 @@
+ goto error;
+ }
+
+- dst1->xfrm = xfrm[i];
+ if (!dst)
+ dst = dst1;
+ else {
+@@ -139,9 +138,11 @@
+ dst_hold(&rt->u.dst);
+ }
+ dst_prev->child = &rt->u.dst;
++ i = 0;
+ for (dst_prev = dst; 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);
+diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+--- a/net/xfrm/xfrm_policy.c 2004-07-28 23:04:01 -07:00
++++ b/net/xfrm/xfrm_policy.c 2004-07-28 23:04:01 -07:00
+@@ -1017,6 +1017,8 @@
+
+ static void xfrm_dst_destroy(struct dst_entry *dst)
+ {
++ if (!dst->xfrm)
++ return;
+ xfrm_state_put(dst->xfrm);
+ dst->xfrm = NULL;
+ }
+#ChangeSet1.1722.6.4
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/05/21 14:43:13-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Fix state modifications in xfrm_state_update().
+#
+# doing a mod_timer on a live state without holding a lock or for that
+# matter not even checking whether the state is dead is definitely a bad
+# idea
+#
+# net/xfrm/xfrm_state.c
+# 2004/05/21 14:42:59-07:00 herbert@gondor.apana.org.au +6 -5
+# [IPSEC]: Fix state modifications in xfrm_state_update().
+#
+# doing a mod_timer on a live state without holding a lock or for that
+# matter not even checking whether the state is dead is definitely a bad
+# idea
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:52:49 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:52:49 -07:00
+@@ -489,14 +489,15 @@
+ memcpy(x1->encap, x->encap, sizeof(*x1->encap));
+ memcpy(&x1->lft, &x->lft, sizeof(x1->lft));
+ x1->km.dying = 0;
++
++ if (!mod_timer(&x1->timer, jiffies + HZ))
++ xfrm_state_hold(x1);
++ if (x1->curlft.use_time)
++ xfrm_state_check_expire(x1);
++
+ err = 0;
+ }
+ spin_unlock_bh(&x1->lock);
+-
+- if (!mod_timer(&x1->timer, jiffies + HZ))
+- xfrm_state_hold(x1);
+- if (x1->curlft.use_time)
+- xfrm_state_check_expire(x1);
+
+ xfrm_state_put(x1);
+
+#ChangeSet1.1722.74.3
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/06/01 12:35:39-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Fix xfrm_tunnel leak.
+#
+# Turns out that the IPIP tunnel used by IPCOMP states are only freed
+# if the IPCOMP state is deleted by xfrm_state_delete.
+#
+# This is not the case for all states. For example, an immature IPCOMP
+# state that dies in add_sa will not go through xfrm_state_delete.
+#
+# The following patch moves the delete_tunnel call into IPCOMP's
+# destructor. I think it makes more sense there as IPCOMP is the
+# only user of the tunnel anyway.
+#
+# net/ipv4/ipcomp.c
+# 2004/06/01 12:35:15-07:00 herbert@gondor.apana.org.au +1 -0
+# [IPSEC]: Fix xfrm_tunnel leak.
+#
+# Turns out that the IPIP tunnel used by IPCOMP states are only freed
+# if the IPCOMP state is deleted by xfrm_state_delete.
+#
+# This is not the case for all states. For example, an immature IPCOMP
+# state that dies in add_sa will not go through xfrm_state_delete.
+#
+# The following patch moves the delete_tunnel call into IPCOMP's
+# destructor. I think it makes more sense there as IPCOMP is the
+# only user of the tunnel anyway.
+#
+# net/xfrm/xfrm_state.c
+# 2004/06/01 12:35:15-07:00 herbert@gondor.apana.org.au +0 -1
+# [IPSEC]: Fix xfrm_tunnel leak.
+#
+# Turns out that the IPIP tunnel used by IPCOMP states are only freed
+# if the IPCOMP state is deleted by xfrm_state_delete.
+#
+# This is not the case for all states. For example, an immature IPCOMP
+# state that dies in add_sa will not go through xfrm_state_delete.
+#
+# The following patch moves the delete_tunnel call into IPCOMP's
+# destructor. I think it makes more sense there as IPCOMP is the
+# only user of the tunnel anyway.
+#
+diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
+--- a/net/ipv4/ipcomp.c 2004-07-28 21:37:23 -07:00
++++ b/net/ipv4/ipcomp.c 2004-07-28 21:37:23 -07:00
+@@ -339,6 +339,7 @@
+ struct ipcomp_data *ipcd = x->data;
+ if (!ipcd)
+ return;
++ xfrm_state_delete_tunnel(x);
+ ipcomp_free_data(ipcd);
+ kfree(ipcd);
+ }
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-07-28 21:37:23 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-07-28 21:37:23 -07:00
+@@ -231,7 +231,6 @@
+
+ void xfrm_state_delete(struct xfrm_state *x)
+ {
+- xfrm_state_delete_tunnel(x);
+ spin_lock_bh(&x->lock);
+ __xfrm_state_delete(x);
+ spin_unlock_bh(&x->lock);
+#ChangeSet1.1784.11.13
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/09 16:51:35-07:00 herbert@gondor.apana.org.au
+# [XFRM]: Add FLUSHSA and FLUSHPOLICY.
+#
+# This patch adds FLUSHSA and FLUSHPOLICY to xfrm_user which are
+# analagous to SADB_FLUSH and SADB_X_SPDFLUSH in af_key.
+#
+# This is useful in KMs on startup/shutdown so that the system is
+# reset to a known state.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# include/linux/xfrm.h
+# 2004/07/09 16:51:20-07:00 herbert@gondor.apana.org.au +9 -0
+# [XFRM]: Add FLUSHSA and FLUSHPOLICY.
+#
+# This patch adds FLUSHSA and FLUSHPOLICY to xfrm_user which are
+# analagous to SADB_FLUSH and SADB_X_SPDFLUSH in af_key.
+#
+# This is useful in KMs on startup/shutdown so that the system is
+# reset to a known state.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_user.c
+# 2004/07/09 16:51:20-07:00 herbert@gondor.apana.org.au +20 -0
+# [XFRM]: Add FLUSHSA and FLUSHPOLICY.
+#
+# This patch adds FLUSHSA and FLUSHPOLICY to xfrm_user which are
+# analagous to SADB_FLUSH and SADB_X_SPDFLUSH in af_key.
+#
+# This is useful in KMs on startup/shutdown so that the system is
+# reset to a known state.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# *** xfrm.h patch updated for 2.4 backport ***
+# *** Joshua Kwan & Horms 2004/08/12 ***
+--- a/include/linux/xfrm.h.orig 2004-08-12 16:32:18.000000000 +0900
++++ b/include/linux/xfrm.h 2004-08-12 16:37:17.000000000 +0900
+@@ -122,7 +122,10 @@
+
+ #define XFRM_MSG_POLEXPIRE (XFRM_MSG_BASE + 11)
+
+-#define XFRM_MSG_MAX (XFRM_MSG_POLEXPIRE+1)
++#define XFRM_MSG_FLUSHSA (XFRM_MSG_BASE + 12)
++#define XFRM_MSG_FLUSHPOLICY (XFRM_MSG_BASE + 13)
++
++#define XFRM_MSG_MAX (XFRM_MSG_FLUSHPOLICY+1)
+
+ struct xfrm_user_tmpl {
+ struct xfrm_id id;
+@@ -227,6 +230,10 @@
+ __u8 hard;
+ };
+
++struct xfrm_usersa_flush {
++ __u8 proto;
++};
++
+ #define XFRMGRP_ACQUIRE 1
+ #define XFRMGRP_EXPIRE 2
+
+diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+--- a/net/xfrm/xfrm_user.c 2004-07-28 22:44:21 -07:00
++++ b/net/xfrm/xfrm_user.c 2004-07-28 22:44:21 -07:00
+@@ -814,6 +814,20 @@
+ return err;
+ }
+
++static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
++{
++ struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
++
++ xfrm_state_flush(p->proto);
++ return 0;
++}
++
++static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
++{
++ xfrm_policy_flush();
++ return 0;
++}
++
+ static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = {
+ NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* NEW SA */
+ NLMSG_LENGTH(sizeof(struct xfrm_usersa_id)), /* DEL SA */
+@@ -826,6 +840,9 @@
+ NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */
+ NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */
+ NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */
++ NLMSG_LENGTH(sizeof(struct xfrm_user_polexpire)), /* POLEXPIRE */
++ NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush)), /* FLUSH SA */
++ NLMSG_LENGTH(0), /* FLUSH POLICY */
+ };
+
+ static struct xfrm_link {
+@@ -849,6 +866,9 @@
+ {},
+ { .doit = xfrm_add_policy },
+ { .doit = xfrm_add_sa, },
++ {},
++ { .doit = xfrm_flush_sa },
++ { .doit = xfrm_flush_policy },
+ };
+
+ static int xfrm_done(struct netlink_callback *cb)
+#ChangeSet1.1807.13.20
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/25 16:54:54-07:00 kaber@trash.net
+# [XFRM]: Wake up km_waitq once per gc-run instead of once per state.
+#
+# Signed-off-by: Patrick McHardy <kaber@trash.net>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_state.c
+# 2004/07/25 16:54:39-07:00 kaber@trash.net +1 -1
+# [XFRM]: Wake up km_waitq once per gc-run instead of once per state.
+#
+# Signed-off-by: Patrick McHardy <kaber@trash.net>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-08-11 23:21:30 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-08-11 23:21:30 -07:00
+@@ -65,7 +65,6 @@
+ xfrm_put_type(x->type);
+ }
+ kfree(x);
+- wake_up(&km_waitq);
+ }
+
+ static void xfrm_state_gc_task(void *data)
+@@ -82,6 +81,7 @@
+ x = list_entry(entry, struct xfrm_state, bydst);
+ xfrm_state_gc_destroy(x);
+ }
++ wake_up(&km_waitq);
+ }
+
+ static inline unsigned long make_jiffies(long secs)
+#ChangeSet1.1807.13.3
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/23 13:23:48-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Missing unlock in policy timer.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_policy.c
+# 2004/07/23 13:23:33-07:00 herbert@gondor.apana.org.au +1 -0
+# [IPSEC]: Missing unlock in policy timer.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+diff -Nru a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+--- a/net/xfrm/xfrm_policy.c 2004-08-11 23:25:52 -07:00
++++ b/net/xfrm/xfrm_policy.c 2004-08-11 23:25:52 -07:00
+@@ -204,6 +204,7 @@
+ return;
+
+ expired:
++ read_unlock(&xp->lock);
+ km_policy_expired(xp, dir, 1);
+ xfrm_policy_delete(xp, dir);
+ xfrm_pol_put(xp);
+#ChangeSet1.1807.19.12
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/28 18:56:51-07:00 nakam@linux-ipv6.org
+# [IPSEC]: xfrm_user code forgets to call xfrm_probe_algs()
+#
+# Signed-off-by: Masahide Nakmura <nakam@linux-ipv6.org>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_user.c
+# 2004/07/28 18:56:37-07:00 nakam@linux-ipv6.org +2 -0
+# [IPSEC]: xfrm_user code forgets to call xfrm_probe_algs()
+#
+# Signed-off-by: Masahide Nakmura <nakam@linux-ipv6.org>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+--- a/net/xfrm/xfrm_user.c 2004-08-11 23:01:30 -07:00
++++ b/net/xfrm/xfrm_user.c 2004-08-11 23:01:30 -07:00
+@@ -267,6 +267,8 @@
+ if (err)
+ return err;
+
++ xfrm_probe_algs();
++
+ x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
+ if (!x)
+ return err;
+#ChangeSet1.1836
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/31 23:30:00-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: Remove redundant check in xfrm_state_add()
+#
+# This is the patch referred to in the netlink_get_spi thread.
+#
+# I was actually wrong about the reason for this patch though. Firstly
+# it's the SPI check that is redundant and not the find_acq() call.
+# And it's redundant because of the find_acq() patch, not because
+# of the fact that this is in xfrm_state_add().
+#
+# Now that find_acq() only returns SAs with SPIs, we don't need to
+# check this in xfrm_state_add() anymore.
+#
+# We do still need the call though to clean up leftover larval states.
+#
+# Another side-effect of the change is that we can move the existence
+# check above find_acq() since find_acq() will never return any SAs
+# matching the SPI we're trying to add (It doesn't need to because if
+# an SA with a matching SPI existed, it would've been returned by
+# state_lookup() already).
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_state.c
+# 2004/07/31 23:29:46-07:00 herbert@gondor.apana.org.au +5 -11
+# [IPSEC]: Remove redundant check in xfrm_state_add()
+#
+# This is the patch referred to in the netlink_get_spi thread.
+#
+# I was actually wrong about the reason for this patch though. Firstly
+# it's the SPI check that is redundant and not the find_acq() call.
+# And it's redundant because of the find_acq() patch, not because
+# of the fact that this is in xfrm_state_add().
+#
+# Now that find_acq() only returns SAs with SPIs, we don't need to
+# check this in xfrm_state_add() anymore.
+#
+# We do still need the call though to clean up leftover larval states.
+#
+# Another side-effect of the change is that we can move the existence
+# check above find_acq() since find_acq() will never return any SAs
+# matching the SPI we're trying to add (It doesn't need to because if
+# an SA with a matching SPI existed, it would've been returned by
+# state_lookup() already).
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-08-11 23:14:58 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-08-11 23:14:58 -07:00
+@@ -400,22 +400,16 @@
+ spin_lock_bh(&xfrm_state_lock);
+
+ x1 = afinfo->state_lookup(&x->id.daddr, x->id.spi, x->id.proto);
+- if (!x1) {
+- x1 = afinfo->find_acq(
+- x->props.mode, x->props.reqid, x->id.proto,
+- &x->id.daddr, &x->props.saddr, 0);
+- if (x1 && x1->id.spi != x->id.spi && x1->id.spi) {
+- xfrm_state_put(x1);
+- x1 = NULL;
+- }
+- }
+-
+- if (x1 && x1->id.spi) {
++ if (x1) {
+ xfrm_state_put(x1);
+ x1 = NULL;
+ err = -EEXIST;
+ goto out;
+ }
++
++ x1 = afinfo->find_acq(
++ x->props.mode, x->props.reqid, x->id.proto,
++ &x->id.daddr, &x->props.saddr, 0);
+
+ __xfrm_state_insert(x);
+ err = 0;
+#ChangeSet1.1837
+# This is a BitKeeper generated diff -Nru style patch.
+#
+# ChangeSet
+# 2004/07/31 23:33:16-07:00 herbert@gondor.apana.org.au
+# [IPSEC]: xfrm_alloc_spi always succeeds on non-trivial range
+#
+# xfrm_alloc_spi will always succeed if minspi < maxspi, even if
+# minspi + 1 == maxspi. If the range is already occupied this
+# will obviously lead to breakage.
+#
+# Of course this is very unlikely to occur in reality due to the
+# size of the range. Although with IPCOMP it might actually happen
+# on a very large server.
+#
+# The fix is obivous.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+# net/xfrm/xfrm_state.c
+# 2004/07/31 23:33:00-07:00 herbert@gondor.apana.org.au +3 -2
+# [IPSEC]: xfrm_alloc_spi always succeeds on non-trivial range
+#
+# xfrm_alloc_spi will always succeed if minspi < maxspi, even if
+# minspi + 1 == maxspi. If the range is already occupied this
+# will obviously lead to breakage.
+#
+# Of course this is very unlikely to occur in reality due to the
+# size of the range. Although with IPCOMP it might actually happen
+# on a very large server.
+#
+# The fix is obivous.
+#
+# Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+# Signed-off-by: David S. Miller <davem@redhat.com>
+#
+diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+--- a/net/xfrm/xfrm_state.c 2004-08-11 23:21:50 -07:00
++++ b/net/xfrm/xfrm_state.c 2004-08-11 23:21:50 -07:00
+@@ -624,11 +624,12 @@
+ for (h=0; h<maxspi-minspi+1; h++) {
+ spi = minspi + net_random()%(maxspi-minspi+1);
+ x0 = xfrm_state_lookup(&x->id.daddr, htonl(spi), x->id.proto, x->props.family);
+- if (x0 == NULL)
++ if (x0 == NULL) {
++ x->id.spi = htonl(spi);
+ break;
++ }
+ xfrm_state_put(x0);
+ }
+- x->id.spi = htonl(spi);
+ }
+ if (x->id.spi) {
+ spin_lock_bh(&xfrm_state_lock);