diff --git a/include/net/xfrm.h b/include/net/xfrm.h index f3014e4f54fc..a1d5acd1f2ad 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -229,6 +229,7 @@ struct xfrm_state { int trailer_len; u32 extra_flags; struct xfrm_mark smark; + u8 alive; } props; struct xfrm_lifetime_cfg lft; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 78fcbb89cf32..d66adf7ee6a2 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -755,6 +755,7 @@ struct xfrm_state *xfrm_state_alloc(struct net *net) x->pcpu_num = UINT_MAX; spin_lock_init(&x->lock); x->mode_data = NULL; + x->props.alive = 1; } return x; } @@ -830,6 +831,7 @@ int __xfrm_state_delete(struct xfrm_state *x) hlist_del_rcu(&x->byspi); net->xfrm.state_num--; xfrm_nat_keepalive_state_updated(x); + x->props.alive = 0; spin_unlock(&net->xfrm.xfrm_state_lock); xfrm_dev_state_delete(x); @@ -932,7 +934,8 @@ int xfrm_state_flush(struct net *net, u8 proto, bool task_valid) restart: hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { if (!xfrm_state_kern(x) && - xfrm_id_proto_match(x->id.proto, proto)) { + xfrm_id_proto_match(x->id.proto, proto) && + x->props.alive) { xfrm_state_hold(x); spin_unlock_bh(&net->xfrm.xfrm_state_lock);