Fix unexpected SA hard expiration after changing date
After SA is setup, one timer is armed to detect soft/hard expiration, however the timer handler uses xtime to do the math. This makes hard expiration occurs first before soft expiration after setting new date with big interval. As a result new child SA is deleted before rekeying the new one. Signed-off-by: Fan Du <fdu@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1485348d24
commit
e3c0d04750
@ -213,6 +213,9 @@ struct xfrm_state {
|
||||
struct xfrm_lifetime_cur curlft;
|
||||
struct tasklet_hrtimer mtimer;
|
||||
|
||||
/* used to fix curlft->add_time when changing date */
|
||||
long saved_tmo;
|
||||
|
||||
/* Last used time */
|
||||
unsigned long lastused;
|
||||
|
||||
@ -238,6 +241,7 @@ static inline struct net *xs_net(struct xfrm_state *x)
|
||||
|
||||
/* xflags - make enum if more show up */
|
||||
#define XFRM_TIME_DEFER 1
|
||||
#define XFRM_SOFT_EXPIRE 2
|
||||
|
||||
enum {
|
||||
XFRM_STATE_VOID,
|
||||
|
@ -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 +
|
||||
|
Loading…
Reference in New Issue
Block a user