diff options
Diffstat (limited to 'net/xfrm/xfrm_state.c')
| -rw-r--r-- | net/xfrm/xfrm_state.c | 25 | 
1 files changed, 20 insertions, 5 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5b228f97d4b..210be48d8ae 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 + @@ -1981,8 +1994,10 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay)  		goto error;  	x->outer_mode = xfrm_get_mode(x->props.mode, family); -	if (x->outer_mode == NULL) +	if (x->outer_mode == NULL) { +		err = -EPROTONOSUPPORT;  		goto error; +	}  	if (init_replay) {  		err = xfrm_init_replay(x);  |