diff options
Diffstat (limited to 'net/xfrm/xfrm_state.c')
| -rw-r--r-- | net/xfrm/xfrm_state.c | 21 | 
1 files changed, 17 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5b228f97d4b3..87cd0e4d4282 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -415,8 +415,17 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)  	if (x->lft.hard_add_expires_seconds) {  		long tmo = x->lft.hard_add_expires_seconds +  			x->curlft.add_time - now; -		if (tmo <= 0) -			goto expired; +		if (tmo <= 0) { +			if (x->xflags & XFRM_SOFT_EXPIRE) { +				/* enter hard expire without soft expire first?! +				 * setting a new date could trigger this. +				 * workarbound: fix x->curflt.add_time by below: +				 */ +				x->curlft.add_time = now - x->saved_tmo - 1; +				tmo = x->lft.hard_add_expires_seconds - x->saved_tmo; +			} else +				goto expired; +		}  		if (tmo < next)  			next = tmo;  	} @@ -433,10 +442,14 @@ static enum hrtimer_restart xfrm_timer_handler(struct hrtimer * me)  	if (x->lft.soft_add_expires_seconds) {  		long tmo = x->lft.soft_add_expires_seconds +  			x->curlft.add_time - now; -		if (tmo <= 0) +		if (tmo <= 0) {  			warn = 1; -		else if (tmo < next) +			x->xflags &= ~XFRM_SOFT_EXPIRE; +		} else if (tmo < next) {  			next = tmo; +			x->xflags |= XFRM_SOFT_EXPIRE; +			x->saved_tmo = tmo; +		}  	}  	if (x->lft.soft_use_expires_seconds) {  		long tmo = x->lft.soft_use_expires_seconds +  |