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:
parent
3d7f57bc69
commit
8d6337d059
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user