PERFORCE change 124120 for review
Ana Kukec
anchie at FreeBSD.org
Thu Jul 26 15:52:02 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=124120
Change 124120 by anchie at anchie_malimis on 2007/07/26 15:51:14
Fixed manipulation with IPSec databases for different vnets.
Affected files ...
.. //depot/projects/vimage/src/sys/netipsec/key.c#11 edit
.. //depot/projects/vimage/src/sys/netipsec/vipsec.h#8 edit
.. //depot/projects/vimage/src/sys/sys/vimage.h#25 edit
Differences ...
==== //depot/projects/vimage/src/sys/netipsec/key.c#11 (text+ko) ====
@@ -130,7 +130,22 @@
static u_int32_t acq_seq = 0;
#endif
+
+static int key_iattach(void *);
+static int key_idetach(void *);
+
+#ifdef VIMAGE
+static struct vnet_modinfo vnet_key_modinfo = {
+ .id = VNET_MOD_KEY,
+ .name = "key",
+ .i_attach = key_iattach,
+ .i_detach = key_idetach
+};
+#endif
+
+#ifndef VIMAGE
static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */
+#endif
static struct mtx sptree_lock;
#define SPTREE_LOCK_INIT() \
mtx_init(&sptree_lock, "sptree", \
@@ -140,7 +155,9 @@
#define SPTREE_UNLOCK() mtx_unlock(&sptree_lock)
#define SPTREE_LOCK_ASSERT() mtx_assert(&sptree_lock, MA_OWNED)
+#ifndef VIMAGE
static LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */
+#endif
static struct mtx sahtree_lock;
#define SAHTREE_LOCK_INIT() \
mtx_init(&sahtree_lock, "sahtree", \
@@ -150,7 +167,9 @@
#define SAHTREE_UNLOCK() mtx_unlock(&sahtree_lock)
#define SAHTREE_LOCK_ASSERT() mtx_assert(&sahtree_lock, MA_OWNED)
/* registed list */
+#ifndef VIMAGE
static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
+#endif
static struct mtx regtree_lock;
#define REGTREE_LOCK_INIT() \
mtx_init(®tree_lock, "regtree", "fast ipsec regtree", MTX_DEF)
@@ -159,7 +178,9 @@
#define REGTREE_UNLOCK() mtx_unlock(®tree_lock)
#define REGTREE_LOCK_ASSERT() mtx_assert(®tree_lock, MA_OWNED)
+#ifndef VIMAGE
static LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */
+#endif
static struct mtx acq_lock;
#define ACQ_LOCK_INIT() \
mtx_init(&acq_lock, "acqtree", "fast ipsec acquire list", MTX_DEF)
@@ -168,7 +189,9 @@
#define ACQ_UNLOCK() mtx_unlock(&acq_lock)
#define ACQ_LOCK_ASSERT() mtx_assert(&acq_lock, MA_OWNED)
+#ifndef VIMAGE
static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */
+#endif
static struct mtx spacq_lock;
#define SPACQ_LOCK_INIT() \
mtx_init(&spacq_lock, "spacqtree", \
@@ -558,8 +581,9 @@
int
key_havesp(u_int dir)
{
+ INIT_VNET_IPSEC(curvnet);
return (dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND ?
- LIST_FIRST(&sptree[dir]) != NULL : 1);
+ LIST_FIRST(&V_sptree[dir]) != NULL : 1);
}
/* %%% IPsec policy management */
@@ -588,7 +612,7 @@
kdebug_secpolicyindex(spidx));
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
kdebug_secpolicyindex(&sp->spidx));
@@ -646,7 +670,7 @@
kdebug_sockaddr(&dst->sa));
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
kdebug_secpolicyindex(&sp->spidx));
@@ -708,7 +732,7 @@
}
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
@@ -869,7 +893,7 @@
const u_int *state_valid;
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) {
@@ -1081,7 +1105,7 @@
saorder_state_valid = saorder_state_valid_prefer_new;
arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
}
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
/* search valid state */
for (stateidx = 0; stateidx < arraysize; stateidx++) {
state = saorder_state_valid[stateidx];
@@ -1280,12 +1304,13 @@
static struct secpolicy *
key_getsp(struct secpolicyindex *spidx)
{
+ INIT_VNET_IPSEC(curvnet);
struct secpolicy *sp;
IPSEC_ASSERT(spidx != NULL, ("null spidx"));
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[spidx->dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[spidx->dir], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
@@ -1306,10 +1331,11 @@
static struct secpolicy *
key_getspbyid(u_int32_t id)
{
+ INIT_VNET_IPSEC(curvnet);
struct secpolicy *sp;
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) {
+ LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
if (sp->id == id) {
@@ -1318,7 +1344,7 @@
}
}
- LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) {
+ LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) {
if (sp->state == IPSEC_SPSTATE_DEAD)
continue;
if (sp->id == id) {
@@ -1923,7 +1949,7 @@
newsp->refcnt = 1; /* do not reclaim until I say I do */
newsp->state = IPSEC_SPSTATE_ALIVE;
- LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain);
+ LIST_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, secpolicy, chain);
/* delete the entry in spacqtree */
if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
@@ -2355,7 +2381,7 @@
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[dir], chain)
+ LIST_FOREACH(sp, &V_sptree[dir], chain)
sp->state = IPSEC_SPSTATE_DEAD;
SPTREE_UNLOCK();
}
@@ -2393,6 +2419,7 @@
struct mbuf *m;
const struct sadb_msghdr *mhp;
{
+ INIT_VNET_IPSEC(curvnet);
struct secpolicy *sp;
int cnt;
u_int dir;
@@ -2406,7 +2433,7 @@
/* search SPD entry and get buffer size. */
cnt = 0;
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
cnt++;
}
}
@@ -2415,7 +2442,7 @@
return key_senderror(so, m, ENOENT);
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
--cnt;
n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt,
mhp->msg->sadb_msg_pid);
@@ -2638,6 +2665,7 @@
key_newsah(saidx)
struct secasindex *saidx;
{
+ INIT_VNET_IPSEC(curvnet);
struct secashead *newsah;
IPSEC_ASSERT(saidx != NULL, ("null saidx"));
@@ -2653,7 +2681,7 @@
newsah->state = SADB_SASTATE_MATURE;
SAHTREE_LOCK();
- LIST_INSERT_HEAD(&sahtree, newsah, chain);
+ LIST_INSERT_HEAD(&V_sahtree, newsah, chain);
SAHTREE_UNLOCK();
}
return(newsah);
@@ -2890,10 +2918,11 @@
key_getsah(saidx)
struct secasindex *saidx;
{
+ INIT_VNET_IPSEC(curvnet);
struct secashead *sah;
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID))
@@ -2930,7 +2959,7 @@
sav = NULL;
/* check all SAD */
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
continue;
sav = key_getsavbyspi(sah, spi);
@@ -4088,6 +4117,7 @@
static void
key_flush_spd(time_t now)
{
+ INIT_VNET_IPSEC(curvnet);
static u_int16_t sptree_scangen = 0;
u_int16_t gen = sptree_scangen++;
struct secpolicy *sp;
@@ -4097,7 +4127,7 @@
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
restart:
SPTREE_LOCK();
- LIST_FOREACH(sp, &sptree[dir], chain) {
+ LIST_FOREACH(sp, &V_sptree[dir], chain) {
if (sp->scangen == gen) /* previously handled */
continue;
sp->scangen = gen;
@@ -4131,7 +4161,7 @@
/* SAD */
SAHTREE_LOCK();
- LIST_FOREACH_SAFE(sah, &sahtree, chain, nextsah) {
+ LIST_FOREACH_SAFE(sah, &V_sahtree, chain, nextsah) {
/* if sah has been dead, then delete it and process next sah. */
if (sah->state == SADB_SASTATE_DEAD) {
key_delsah(sah);
@@ -4269,7 +4299,7 @@
/* ACQ tree */
ACQ_LOCK();
- for (acq = LIST_FIRST(&acqtree); acq != NULL; acq = nextacq) {
+ for (acq = LIST_FIRST(&V_acqtree); acq != NULL; acq = nextacq) {
nextacq = LIST_NEXT(acq, chain);
if (now - acq->created > V_key_blockacq_lifetime
&& __LIST_CHAINED(acq)) {
@@ -4288,7 +4318,7 @@
/* SP ACQ tree */
SPACQ_LOCK();
- for (acq = LIST_FIRST(&spacqtree); acq != NULL; acq = nextacq) {
+ for (acq = LIST_FIRST(&V_spacqtree); acq != NULL; acq = nextacq) {
nextacq = LIST_NEXT(acq, chain);
if (now - acq->created > V_key_blockacq_lifetime
&& __LIST_CHAINED(acq)) {
@@ -5208,7 +5238,7 @@
/* get a SA header */
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
@@ -5277,7 +5307,7 @@
KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
@@ -5393,7 +5423,7 @@
/* get a SA header */
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
@@ -5904,7 +5934,7 @@
/* add to acqtree */
ACQ_LOCK();
- LIST_INSERT_HEAD(&acqtree, newacq, chain);
+ LIST_INSERT_HEAD(&V_acqtree, newacq, chain);
ACQ_UNLOCK();
return newacq;
@@ -5913,10 +5943,11 @@
static struct secacq *
key_getacq(const struct secasindex *saidx)
{
+ INIT_VNET_IPSEC(curvnet);
struct secacq *acq;
ACQ_LOCK();
- LIST_FOREACH(acq, &acqtree, chain) {
+ LIST_FOREACH(acq, &V_acqtree, chain) {
if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
break;
}
@@ -5929,10 +5960,11 @@
key_getacqbyseq(seq)
u_int32_t seq;
{
+ INIT_VNET_IPSEC(curvnet);
struct secacq *acq;
ACQ_LOCK();
- LIST_FOREACH(acq, &acqtree, chain) {
+ LIST_FOREACH(acq, &V_acqtree, chain) {
if (acq->seq == seq)
break;
}
@@ -5962,7 +5994,7 @@
/* add to spacqtree */
SPACQ_LOCK();
- LIST_INSERT_HEAD(&spacqtree, acq, chain);
+ LIST_INSERT_HEAD(&V_spacqtree, acq, chain);
SPACQ_UNLOCK();
return acq;
@@ -5972,10 +6004,11 @@
key_getspacq(spidx)
struct secpolicyindex *spidx;
{
+ INIT_VNET_IPSEC(curvnet);
struct secspacq *acq;
SPACQ_LOCK();
- LIST_FOREACH(acq, &spacqtree, chain) {
+ LIST_FOREACH(acq, &V_spacqtree, chain) {
if (key_cmpspidx_exactly(spidx, &acq->spidx)) {
/* NB: return holding spacq_lock */
return acq;
@@ -6087,7 +6120,7 @@
/* get a SA index */
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (sah->state == SADB_SASTATE_DEAD)
continue;
if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID))
@@ -6137,7 +6170,7 @@
IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
/* check for invalid register message */
- if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0]))
+ if (mhp->msg->sadb_msg_satype >= sizeof(V_regtree)/sizeof(V_regtree[0]))
return key_senderror(so, m, EINVAL);
/* When SATYPE_UNSPEC is specified, only return sabd_supported. */
@@ -6146,7 +6179,7 @@
/* check whether existing or not */
REGTREE_LOCK();
- LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) {
+ LIST_FOREACH(reg, &V_regtree[mhp->msg->sadb_msg_satype], chain) {
if (reg->so == so) {
REGTREE_UNLOCK();
ipseclog((LOG_DEBUG, "%s: socket exists already.\n",
@@ -6167,7 +6200,7 @@
((struct keycb *)sotorawcb(so))->kp_registered++;
/* add regnode to regtree. */
- LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain);
+ LIST_INSERT_HEAD(&V_regtree[mhp->msg->sadb_msg_satype], newreg, chain);
REGTREE_UNLOCK();
setmsg:
@@ -6283,6 +6316,7 @@
void
key_freereg(struct socket *so)
{
+ INIT_VNET_IPSEC(curvnet);
struct secreg *reg;
int i;
@@ -6295,7 +6329,7 @@
*/
REGTREE_LOCK();
for (i = 0; i <= SADB_SATYPE_MAX; i++) {
- LIST_FOREACH(reg, ®tree[i], chain) {
+ LIST_FOREACH(reg, &V_regtree[i], chain) {
if (reg->so == so && __LIST_CHAINED(reg)) {
LIST_REMOVE(reg, chain);
free(reg, M_IPSEC_SAR);
@@ -6470,7 +6504,7 @@
/* no SATYPE specified, i.e. flushing all SA. */
SAHTREE_LOCK();
- for (sah = LIST_FIRST(&sahtree);
+ for (sah = LIST_FIRST(&V_sahtree);
sah != NULL;
sah = nextsah) {
nextsah = LIST_NEXT(sah, chain);
@@ -6559,7 +6593,7 @@
/* count sav entries to be sent to the userland. */
cnt = 0;
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
&& proto != sah->saidx.proto)
continue;
@@ -6581,7 +6615,7 @@
/* send this to the userland, one at a time. */
newmsg = NULL;
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC
&& proto != sah->saidx.proto)
continue;
@@ -7144,7 +7178,19 @@
}
void
-key_init()
+key_init(void)
+{
+#ifdef VIMAGE
+ if (IS_VNET_0(curvnet))
+ vnet_mod_register(&vnet_key_modinfo);
+#else
+ key_iattach(NULL);
+#endif
+
+ return;
+}
+
+static int key_iattach(unused) void *unused;
{
INIT_VNET_IPSEC(curvnet);
int i;
@@ -7184,15 +7230,15 @@
}
#endif
for (i = 0; i < IPSEC_DIR_MAX; i++)
- LIST_INIT(&sptree[i]);
+ LIST_INIT(&V_sptree[i]);
- LIST_INIT(&sahtree);
+ LIST_INIT(&V_sahtree);
for (i = 0; i <= SADB_SATYPE_MAX; i++)
- LIST_INIT(®tree[i]);
+ LIST_INIT(&V_regtree[i]);
- LIST_INIT(&acqtree);
- LIST_INIT(&spacqtree);
+ LIST_INIT(&V_acqtree);
+ LIST_INIT(&V_spacqtree);
/* system default */
V_ip4_def_policy.policy = IPSEC_POLICY_NONE;
@@ -7210,8 +7256,19 @@
printf("Fast IPsec: Initialized Security Association Processing.\n");
- return;
+ return 0;
+}
+
+#ifdef VIMAGE
+static int key_idetach(unused) void *unused;
+{
+ INIT_VNET_IPSEC(curvnet);
+ /*
+ * Flush: spdtree, sahtree, regtree, acqtree, sacqtree
+ */
+ return 0;
}
+#endif
/*
* XXX: maybe This function is called after INBOUND IPsec processing.
@@ -7283,11 +7340,12 @@
key_sa_routechange(dst)
struct sockaddr *dst;
{
+ INIT_VNET_IPSEC(curvnet);
struct secashead *sah;
struct route *ro;
SAHTREE_LOCK();
- LIST_FOREACH(sah, &sahtree, chain) {
+ LIST_FOREACH(sah, &V_sahtree, chain) {
ro = &sah->sa_route;
if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len
&& bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) {
==== //depot/projects/vimage/src/sys/netipsec/vipsec.h#8 (text+ko) ====
@@ -117,6 +117,9 @@
LIST_HEAD(, secpolicy) _sptree[IPSEC_DIR_MAX];
LIST_HEAD(, secashead) _sahtree;
+ LIST_HEAD(, secreg) _regtree[SADB_SATYPE_MAX + 1];
+ LIST_HEAD(, secacq) _acqtree;
+ LIST_HEAD(, secspacq) _spacqtree;
};
#endif
@@ -181,4 +184,7 @@
#define V_key_src VNET_IPSEC(key_src)
#define V_sptree VNET_IPSEC(sptree)
#define V_sahtree VNET_IPSEC(sahtree)
+#define V_regtree VNET_IPSEC(regtree)
+#define V_acqtree VNET_IPSEC(acqtree)
+#define V_spacqtree VNET_IPSEC(spacqtree)
#endif /* !_NETIPSEC_VIPSEC_H_ */
==== //depot/projects/vimage/src/sys/sys/vimage.h#25 (text+ko) ====
@@ -81,6 +81,7 @@
#define VNET_MOD_AH 15
#define VNET_MOD_GIF 16
#define VNET_MOD_IPCOMP 17
+#define VNET_MOD_KEY 18
#define VNET_MOD_ARP 28
#define VNET_MOD_RTABLE 29
#define VNET_MOD_LOIF 30
More information about the p4-projects
mailing list