diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 3254143f3a6c..cf199eb452fb 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1157,6 +1157,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) {} @@ -1191,6 +1193,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__ diff --git a/net/key/af_key.c b/net/key/af_key.c index 85e0b2816e7e..0e59c091f271 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2367,6 +2367,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; } @@ -2616,6 +2618,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; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8e5850e29ee8..5cbf3c111f56 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2543,11 +2543,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) { diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5b11e701d763..d8a2e7a248d8 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1688,6 +1688,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; }