Newer SA is prefered for a out-bound packet than old one

when net.key.prefered_oldsa is set to zero.

Obtained from:	KAME
MFC after:	1 week
This commit is contained in:
Hajimu UMEMOTO 2001-12-05 05:40:49 +00:00
parent 3d7f57bc69
commit 8d6337d059
2 changed files with 90 additions and 8 deletions

View File

@ -134,6 +134,7 @@ static u_int key_int_random = 60; /*interval to initialize randseed,1(m)*/
static u_int key_larval_lifetime = 30; /* interval to expire acquiring, 30(s)*/
static int key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/
static int key_blockacq_lifetime = 20; /* lifetime for blocking SADB_ACQUIRE.*/
static int key_prefered_oldsa = 1; /* prefered old sa rather than new sa.*/
static u_int32_t acq_seq = 0;
static int key_tick_init_random = 0;
@ -262,6 +263,10 @@ SYSCTL_INT(_net_key, KEYCTL_ESP_KEYMIN, esp_keymin, CTLFLAG_RW, \
SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW, \
&ipsec_ah_keymin, 0, "");
/* perfered old SA rather than new SA */
SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW,\
&key_prefered_oldsa, 0, "");
#ifndef LIST_FOREACH
#define LIST_FOREACH(elm, head, field) \
for (elm = LIST_FIRST(head); elm; elm = LIST_NEXT(elm, field))
@ -769,12 +774,16 @@ key_do_allocsa_policy(sah, state)
struct secashead *sah;
u_int state;
{
struct secasvar *sav, *candidate;
struct secasvar *sav, *nextsav, *candidate, *d;
/* initilize */
candidate = NULL;
LIST_FOREACH(sav, &sah->savtree[state], chain) {
for (sav = LIST_FIRST(&sah->savtree[state]);
sav != NULL;
sav = nextsav) {
nextsav = LIST_NEXT(sav, chain);
/* sanity check */
KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy");
@ -792,11 +801,82 @@ key_do_allocsa_policy(sah, state)
panic("key_do_allocsa_policy: "
"lifetime_current is NULL.\n");
/* XXX What the best method is to compare ? */
if (candidate->lft_c->sadb_lifetime_addtime >
sav->lft_c->sadb_lifetime_addtime) {
candidate = sav;
/* What the best method is to compare ? */
if (key_prefered_oldsa) {
if (candidate->lft_c->sadb_lifetime_addtime >
sav->lft_c->sadb_lifetime_addtime) {
candidate = sav;
}
continue;
/*NOTREACHED*/
}
/* prefered new sa rather than old sa */
if (candidate->lft_c->sadb_lifetime_addtime <
sav->lft_c->sadb_lifetime_addtime) {
d = candidate;
candidate = sav;
} else
d = sav;
/*
* prepared to delete the SA when there is more
* suitable candidate and the lifetime of the SA is not
* permanent.
*/
if (d->lft_c->sadb_lifetime_addtime != 0) {
struct mbuf *m, *result;
key_sa_chgstate(d, SADB_SASTATE_DEAD);
key_freesav(d);
m = key_setsadbmsg(SADB_DELETE, 0,
sav->sah->saidx.proto, 0, 0, d->refcnt);
if (!m)
return NULL;
result = m;
/* set sadb_address for saidx's. */
m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
(struct sockaddr *)&d->sah->saidx.src,
d->sah->saidx.src.ss_len << 3,
IPSEC_ULPROTO_ANY);
if (!m)
return NULL;
m_cat(result, m);
/* set sadb_address for saidx's. */
m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
(struct sockaddr *)&d->sah->saidx.src,
d->sah->saidx.src.ss_len << 3,
IPSEC_ULPROTO_ANY);
if (!m)
return NULL;
m_cat(result, m);
/* create SA extension */
m = key_setsadbsa(d);
if (!m)
return NULL;
m_cat(result, m);
if (result->m_len < sizeof(struct sadb_msg)) {
result = m_pullup(result,
sizeof(struct sadb_msg));
if (result == NULL)
return NULL;
}
result->m_pkthdr.len = 0;
for (m = result; m; m = m->m_next)
result->m_pkthdr.len += m->m_len;
mtod(result, struct sadb_msg *)->sadb_msg_len =
PFKEY_UNIT64(result->m_pkthdr.len);
if (key_sendup_mbuf(NULL, result,
KEY_SENDUP_REGISTERED))
return NULL;
}
}

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: key_var.h,v 1.10 2001/07/27 04:14:12 itojun Exp $ */
/* $KAME: key_var.h,v 1.11 2001/09/12 23:05:07 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -45,7 +45,8 @@
#define KEYCTL_ESP_KEYMIN 9
#define KEYCTL_ESP_AUTH 10
#define KEYCTL_AH_KEYMIN 11
#define KEYCTL_MAXID 12
#define KEYCTL_PREFERED_OLDSA 12
#define KEYCTL_MAXID 13
#define KEYCTL_NAMES { \
{ 0, 0 }, \
@ -60,6 +61,7 @@
{ "esp_keymin", CTLTYPE_INT }, \
{ "esp_auth", CTLTYPE_INT }, \
{ "ah_keymin", CTLTYPE_INT }, \
{ "prefered_oldsa", CTLTYPE_INT }, \
}
#ifdef _KERNEL