[IPSEC 2/4] Policy Expiration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave:

This patch fixes the index recycling problem for expired policies.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.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
Index: kernel-source-2.5/include/net/xfrm.h
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/net/xfrm.h,v
retrieving revision 1.8
diff -u -r1.8 xfrm.h
--- kernel-source-2.5/include/net/xfrm.h	5 Jul 2003 04:44:34 -0000	1.8
+++ kernel-source-2.5/include/net/xfrm.h	5 Jul 2003 05:54:39 -0000
@@ -637,16 +637,16 @@
 	return 0;
 }
 
-extern void __xfrm_sk_free_policy(struct xfrm_policy *, int dir);
+extern void xfrm_policy_delete(struct xfrm_policy *pol, int dir);
 
 static inline void xfrm_sk_free_policy(struct sock *sk)
 {
 	if (unlikely(sk->sk_policy[0] != NULL)) {
-		__xfrm_sk_free_policy(sk->sk_policy[0], 0);
+		xfrm_policy_delete(sk->sk_policy[0], XFRM_POLICY_MAX);
 		sk->sk_policy[0] = NULL;
 	}
 	if (unlikely(sk->sk_policy[1] != NULL)) {
-		__xfrm_sk_free_policy(sk->sk_policy[1], 1);
+		xfrm_policy_delete(sk->sk_policy[1], XFRM_POLICY_MAX+1);
 		sk->sk_policy[1] = NULL;
 	}
 }
Index: kernel-source-2.5/net/xfrm/xfrm_policy.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_policy.c,v
retrieving revision 1.15
diff -u -r1.15 xfrm_policy.c
--- kernel-source-2.5/net/xfrm/xfrm_policy.c	5 Jul 2003 06:56:57 -0000	1.15
+++ kernel-source-2.5/net/xfrm/xfrm_policy.c	5 Jul 2003 07:33:36 -0000
@@ -141,7 +141,6 @@
 	struct xfrm_policy *xp = (struct xfrm_policy*)data;
 	unsigned long now = (unsigned long)xtime.tv_sec;
 	long next = LONG_MAX;
-	u32 index;
 
 	if (xp->dead)
 		goto out;
@@ -163,14 +162,8 @@
 	return;
 
 expired:
-	index = xp->index;
+	xfrm_policy_delete(xp, xp->index & 7);
 	xfrm_pol_put(xp);
-
-	/* Not 100% correct. id can be recycled in theory */
-	xp = xfrm_policy_byid(0, index, 1);
-	if (xp) {
-		xfrm_pol_put(xp);
-	}
 }
 
 
@@ -481,25 +474,36 @@
 	return pol;
 }
 
-void xfrm_sk_policy_link(struct xfrm_policy *pol, int dir)
+static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
 {
-	pol->next = xfrm_policy_list[XFRM_POLICY_MAX+dir];
-	xfrm_policy_list[XFRM_POLICY_MAX+dir] = pol;
+	pol->next = xfrm_policy_list[dir];
+	xfrm_policy_list[dir] = pol;
 	xfrm_pol_hold(pol);
 }
 
-void xfrm_sk_policy_unlink(struct xfrm_policy *pol, int dir)
+static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
+						int dir)
 {
 	struct xfrm_policy **polp;
 
-	for (polp = &xfrm_policy_list[XFRM_POLICY_MAX+dir];
+	for (polp = &xfrm_policy_list[dir];
 	     *polp != NULL; polp = &(*polp)->next) {
 		if (*polp == pol) {
 			*polp = pol->next;
 			atomic_dec(&pol->refcnt);
-			return;
+			return pol;
 		}
 	}
+	return NULL;
+}
+
+void xfrm_policy_delete(struct xfrm_policy *pol, int dir)
+{
+	write_lock_bh(&xfrm_policy_lock);
+	pol = __xfrm_policy_unlink(pol, dir);
+	write_unlock_bh(&xfrm_policy_lock);
+	if (pol)
+		xfrm_policy_kill(pol);
 }
 
 int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
@@ -512,10 +516,10 @@
 	if (pol) {
 		pol->curlft.add_time = (unsigned long)xtime.tv_sec;
 		pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir);
-		xfrm_sk_policy_link(pol, dir);
+		__xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
 	}
 	if (old_pol)
-		xfrm_sk_policy_unlink(old_pol, dir);
+		__xfrm_policy_unlink(old_pol, XFRM_POLICY_MAX+dir);
 	write_unlock_bh(&xfrm_policy_lock);
 
 	if (old_pol) {
@@ -540,7 +544,7 @@
 		memcpy(newp->xfrm_vec, old->xfrm_vec,
 		       newp->xfrm_nr*sizeof(struct xfrm_tmpl));
 		write_lock_bh(&xfrm_policy_lock);
-		xfrm_sk_policy_link(newp, dir);
+		__xfrm_policy_link(newp, XFRM_POLICY_MAX+dir);
 		write_unlock_bh(&xfrm_policy_lock);
 	}
 	return newp;
@@ -557,15 +561,6 @@
 	if (p1 && (sk->sk_policy[1] = clone_policy(p1, 1)) == NULL)
 		return -ENOMEM;
 	return 0;
-}
-
-void __xfrm_sk_free_policy(struct xfrm_policy *pol, int dir)
-{
-	write_lock_bh(&xfrm_policy_lock);
-	xfrm_sk_policy_unlink(pol, dir);
-	write_unlock_bh(&xfrm_policy_lock);
-
-	xfrm_policy_kill(pol);
 }
 
 /* Resolve list of templates for the flow, given policy. */

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux