diff options
author | ae <ae@FreeBSD.org> | 2015-06-02 03:51:33 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2015-06-02 03:51:33 +0000 |
commit | 3c9fd219636d39ff34d957bf7cb13945826529b8 (patch) | |
tree | 48da68d155f90e660ef443637448f98868106c2f /sys/netipsec | |
parent | bf9acc9587cc1734e0b30b1318463ab75428ba52 (diff) | |
download | FreeBSD-src-3c9fd219636d39ff34d957bf7cb13945826529b8.zip FreeBSD-src-3c9fd219636d39ff34d957bf7cb13945826529b8.tar.gz |
MFC r283101:
Teach key_expire() send SADB_EXPIRE message with the SADB_EXT_LIFETIME_HARD
extension header type. The key_flush_sad() now will send SADB_EXPIRE
message when HARD lifetime expires. This is required by RFC 2367 and some
keying daemons rely on these messages. HARD lifetime messages have
precedence over SOFT lifetime messages, so now they will be checked first.
Also now SADB_EXPIRE messages will be send even the SA has not been used,
because keying daemons might want to rekey such SA.
PR: 200282, 200283
MFC r283102:
Change SA's state before sending SADB_EXPIRE message. This state will
be reported to keying daemon.
Diffstat (limited to 'sys/netipsec')
-rw-r--r-- | sys/netipsec/key.c | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index d3bc81c..ba10fb4 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -529,7 +529,7 @@ static int key_acquire2(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_register(struct socket *, struct mbuf *, const struct sadb_msghdr *); -static int key_expire(struct secasvar *); +static int key_expire(struct secasvar *, int); static int key_flush(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_dump(struct socket *, struct mbuf *, @@ -4302,41 +4302,29 @@ key_flush_sad(time_t now) "time, why?\n", __func__)); continue; } - - /* check SOFT lifetime */ - if (sav->lft_s->addtime != 0 && - now - sav->created > sav->lft_s->addtime) { - key_sa_chgstate(sav, SADB_SASTATE_DYING); - /* - * Actually, only send expire message if - * SA has been used, as it was done before, - * but should we always send such message, - * and let IKE daemon decide if it should be - * renegotiated or not ? - * XXX expire message will actually NOT be - * sent if SA is only used after soft - * lifetime has been reached, see below - * (DYING state) - */ - if (sav->lft_c->usetime != 0) - key_expire(sav); - } - /* check SOFT lifetime by bytes */ /* - * XXX I don't know the way to delete this SA - * when new SA is installed. Caution when it's - * installed too big lifetime by time. + * RFC 2367: + * HARD lifetimes MUST take precedence over SOFT + * lifetimes, meaning if the HARD and SOFT lifetimes + * are the same, the HARD lifetime will appear on the + * EXPIRE message. */ - else if (sav->lft_s->bytes != 0 && - sav->lft_s->bytes < sav->lft_c->bytes) { - + /* check HARD lifetime */ + if ((sav->lft_h->addtime != 0 && + now - sav->created > sav->lft_h->addtime) || + (sav->lft_h->bytes != 0 && + sav->lft_h->bytes < sav->lft_c->bytes)) { + key_sa_chgstate(sav, SADB_SASTATE_DEAD); + key_expire(sav, 1); + KEY_FREESAV(&sav); + } + /* check SOFT lifetime */ + else if ((sav->lft_s->addtime != 0 && + now - sav->created > sav->lft_s->addtime) || + (sav->lft_s->bytes != 0 && + sav->lft_s->bytes < sav->lft_c->bytes)) { key_sa_chgstate(sav, SADB_SASTATE_DYING); - /* - * XXX If we keep to send expire - * message in the status of - * DYING. Do remove below code. - */ - key_expire(sav); + key_expire(sav, 0); } } @@ -4356,6 +4344,7 @@ key_flush_sad(time_t now) if (sav->lft_h->addtime != 0 && now - sav->created > sav->lft_h->addtime) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); + key_expire(sav, 1); KEY_FREESAV(&sav); } #if 0 /* XXX Should we keep to send expire message until HARD lifetime ? */ @@ -4371,13 +4360,14 @@ key_flush_sad(time_t now) * If there is no SA then sending * expire message. */ - key_expire(sav); + key_expire(sav, 0); } #endif /* check HARD lifetime by bytes */ else if (sav->lft_h->bytes != 0 && sav->lft_h->bytes < sav->lft_c->bytes) { key_sa_chgstate(sav, SADB_SASTATE_DEAD); + key_expire(sav, 1); KEY_FREESAV(&sav); } } @@ -6783,7 +6773,7 @@ key_freereg(struct socket *so) * others : error number */ static int -key_expire(struct secasvar *sav) +key_expire(struct secasvar *sav, int hard) { int satype; struct mbuf *result = NULL, *m; @@ -6841,11 +6831,19 @@ key_expire(struct secasvar *sav) lt->sadb_lifetime_usetime = sav->lft_c->usetime; lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2); lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime)); - lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; - lt->sadb_lifetime_allocations = sav->lft_s->allocations; - lt->sadb_lifetime_bytes = sav->lft_s->bytes; - lt->sadb_lifetime_addtime = sav->lft_s->addtime; - lt->sadb_lifetime_usetime = sav->lft_s->usetime; + if (hard) { + lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; + lt->sadb_lifetime_allocations = sav->lft_h->allocations; + lt->sadb_lifetime_bytes = sav->lft_h->bytes; + lt->sadb_lifetime_addtime = sav->lft_h->addtime; + lt->sadb_lifetime_usetime = sav->lft_h->usetime; + } else { + lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; + lt->sadb_lifetime_allocations = sav->lft_s->allocations; + lt->sadb_lifetime_bytes = sav->lft_s->bytes; + lt->sadb_lifetime_addtime = sav->lft_s->addtime; + lt->sadb_lifetime_usetime = sav->lft_s->usetime; + } m_cat(result, m); /* set sadb_address for source */ |