diff options
author | ume <ume@FreeBSD.org> | 2003-11-04 16:02:05 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-11-04 16:02:05 +0000 |
commit | 373abd94036be0e5643f5134aa9fb8bb694d1624 (patch) | |
tree | fdad404b77778d90d4bdccd4cb96415d0821c8d5 /sys/netkey/keydb.c | |
parent | b5882bdf826f86fe99c8ba32265622dcc6139367 (diff) | |
download | FreeBSD-src-373abd94036be0e5643f5134aa9fb8bb694d1624.zip FreeBSD-src-373abd94036be0e5643f5134aa9fb8bb694d1624.tar.gz |
- cleanup SP refcnt issue.
- share policy-on-socket for listening socket.
- don't copy policy-on-socket at all. secpolicy no longer contain
spidx, which saves a lot of memory.
- deep-copy pcb policy if it is an ipsec policy. assign ID field to
all SPD entries. make it possible for racoon to grab SPD entry on
pcb.
- fixed the order of searching SA table for packets.
- fixed to get a security association header. a mode is always needed
to compare them.
- fixed that the incorrect time was set to
sadb_comb_{hard|soft}_usetime.
- disallow port spec for tunnel mode policy (as we don't reassemble).
- an user can define a policy-id.
- clear enc/auth key before freeing.
- fixed that the kernel crashed when key_spdacquire() was called
because key_spdacquire() had been implemented imcopletely.
- preparation for 64bit sequence number.
- maintain ordered list of SA, based on SA id.
- cleanup secasvar management; refcnt is key.c responsibility;
alloc/free is keydb.c responsibility.
- cleanup, avoid double-loop.
- use hash for spi-based lookup.
- mark persistent SP "persistent".
XXX in theory refcnt should do the right thing, however, we have
"spdflush" which would touch all SPs. another solution would be to
de-register persistent SPs from sptree.
- u_short -> u_int16_t
- reduce kernel stack usage by auto variable secasindex.
- clarify function name confusion. ipsec_*_policy ->
ipsec_*_pcbpolicy.
- avoid variable name confusion.
(struct inpcbpolicy *)pcb_sp, spp (struct secpolicy **), sp (struct
secpolicy *)
- count number of ipsec encapsulations on ipsec4_output, so that we
can tell ip_output() how to handle the packet further.
- When the value of the ul_proto is ICMP or ICMPV6, the port field in
"src" of the spidx specifies ICMP type, and the port field in "dst"
of the spidx specifies ICMP code.
- avoid from applying IPsec transport mode to the packets when the
kernel forwards the packets.
Tested by: nork
Obtained from: KAME
Diffstat (limited to 'sys/netkey/keydb.c')
-rw-r--r-- | sys/netkey/keydb.c | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/sys/netkey/keydb.c b/sys/netkey/keydb.c index 309b512..697b6e5 100644 --- a/sys/netkey/keydb.c +++ b/sys/netkey/keydb.c @@ -1,4 +1,4 @@ -/* $KAME: keydb.c,v 1.64 2000/05/11 17:02:30 itojun Exp $ */ +/* $KAME: keydb.c,v 1.82 2003/09/07 07:47:33 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <net/pfkeyv2.h> #include <netkey/keydb.h> +#include <netkey/key.h> #include <netinet6/ipsec.h> #include <net/net_osdep.h> @@ -69,17 +70,63 @@ keydb_newsecpolicy() if (!p) return p; bzero(p, sizeof(*p)); + TAILQ_INSERT_TAIL(&sptailq, p, tailq); + return p; } +u_int32_t +keydb_newspid(void) +{ + u_int32_t newid = 0; + static u_int32_t lastalloc = IPSEC_MANUAL_POLICYID_MAX; + struct secpolicy *sp; + + newid = lastalloc + 1; + /* XXX possible infinite loop */ +again: + TAILQ_FOREACH(sp, &sptailq, tailq) { + if (sp->id == newid) + break; + } + if (sp != NULL) { + if (newid + 1 < newid) /* wraparound */ + newid = IPSEC_MANUAL_POLICYID_MAX + 1; + else + newid++; + goto again; + } + lastalloc = newid; + + return newid; +} + void keydb_delsecpolicy(p) struct secpolicy *p; { + TAILQ_REMOVE(&sptailq, p, tailq); + if (p->spidx) + free(p->spidx, M_SECA); free(p, M_SECA); } +int +keydb_setsecpolicyindex(p, idx) + struct secpolicy *p; + struct secpolicyindex *idx; +{ + + if (!p->spidx) + p->spidx = (struct secpolicyindex *)malloc(sizeof(*p->spidx), + M_SECA, M_NOWAIT); + if (!p->spidx) + return ENOMEM; + memcpy(p->spidx, idx, sizeof(*p->spidx)); + return 0; +} + /* * secashead management */ @@ -112,12 +159,36 @@ keydb_delsecashead(p) struct secasvar * keydb_newsecasvar() { - struct secasvar *p; + struct secasvar *p, *q; + static u_int32_t said = 0; p = (struct secasvar *)malloc(sizeof(*p), M_SECA, M_NOWAIT); if (!p) return p; + +again: + said++; + if (said == 0) + said++; + TAILQ_FOREACH(q, &satailq, tailq) { + if (q->id == said) + goto again; + if (TAILQ_NEXT(q, tailq)) { + if (q->id < said && said < TAILQ_NEXT(q, tailq)->id) + break; + if (q->id + 1 < TAILQ_NEXT(q, tailq)->id) { + said = q->id + 1; + break; + } + } + } + bzero(p, sizeof(*p)); + p->id = said; + if (q) + TAILQ_INSERT_AFTER(&satailq, q, p, tailq); + else + TAILQ_INSERT_TAIL(&satailq, p, tailq); return p; } @@ -126,6 +197,8 @@ keydb_delsecasvar(p) struct secasvar *p; { + TAILQ_REMOVE(&satailq, p, tailq); + free(p, M_SECA); } @@ -144,7 +217,7 @@ keydb_newsecreplay(wsize) bzero(p, sizeof(*p)); if (wsize != 0) { - p->bitmap = (caddr_t)malloc(wsize, M_SECA, M_NOWAIT); + p->bitmap = malloc(wsize, M_SECA, M_NOWAIT); if (!p->bitmap) { free(p, M_SECA); return NULL; |