]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
xfrm: force a garbage collection after deleting a policy
authorPaul Moore <pmoore@redhat.com>
Wed, 29 May 2013 07:36:25 +0000 (07:36 +0000)
committerGerrit Code Review <gerrit2@git.omapzoom.org>
Wed, 12 Mar 2014 01:14:43 +0000 (20:14 -0500)
In some cases after deleting a policy from the SPD the policy would
remain in the dst/flow/route cache for an extended period of time
which caused problems for SELinux as its dynamic network access
controls key off of the number of XFRM policy and state entries.
This patch corrects this problem by forcing a XFRM garbage collection
whenever a policy is sucessfully removed.

[ cileija@ti.com: backport ]
[ upstream commit e4c1721642bbd42d8142f4811cde0588c28db51d ]

Change-Id: I7f51b8b10f9f660698d7abe24f033a283fd28849
Reported-by: Ondrej Moris <omoris@redhat.com>
Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Carlos Leija <cileija@ti.com>
include/net/xfrm.h
net/key/af_key.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c

index 63445ede48bb7fd04b175c111935fb77464568b6..57de34d37e257ae05b397f640548afaa656c695e 100644 (file)
@@ -1156,6 +1156,8 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
        }
 }
 
+extern void xfrm_garbage_collect(struct net *net);
+
 #else
 
 static inline void xfrm_sk_free_policy(struct sock *sk) {}
@@ -1190,6 +1192,9 @@ static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
 {
        return 1;
 }
+static inline void xfrm_garbage_collect(struct net *net)
+{
+}
 #endif
 
 static __inline__
index 5b426a6465447f954a4b4728f72a6c00966c91ee..a302f65be7d9c77df5fde3bb0ffcbf4d07c79c68 100644 (file)
@@ -2361,6 +2361,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
 out:
        xfrm_pol_put(xp);
+       if (err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
@@ -2610,6 +2612,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }
 
index 07c585756d2a52530dc3fd1f5b14192b1a3c4cd6..22348964a2cebe76a79c80e90bc5ddd9a9732360 100644 (file)
@@ -2312,11 +2312,12 @@ static void __xfrm_garbage_collect(struct net *net)
        }
 }
 
-static void xfrm_garbage_collect(struct net *net)
+void xfrm_garbage_collect(struct net *net)
 {
        flow_cache_flush();
        __xfrm_garbage_collect(net);
 }
+EXPORT_SYMBOL(xfrm_garbage_collect);
 
 static void xfrm_garbage_collect_deferred(struct net *net)
 {
index eb872b2e366e1209993efe470bed7f614a299098..8b94ba7ba6dab4376a4b13f8ec74e719927b9e23 100644 (file)
@@ -1671,6 +1671,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 out:
        xfrm_pol_put(xp);
+       if (delete && err == 0)
+               xfrm_garbage_collect(net);
        return err;
 }