MFp4: portability work, general cleanup, locking fixes
change 38496 o add ipsec_osdep.h that holds os-specific definitions for portability o s/KASSERT/IPSEC_ASSERT/ for portability o s/SPLASSERT/IPSEC_SPLASSERT/ for portability o remove function names from ASSERT strings since line#+file pinpints the location o use __func__ uniformly to reduce string storage o convert some random #ifdef DIAGNOSTIC code to assertions o remove some debuggging assertions no longer needed change 38498 o replace numerous bogus panic's with equally bogus assertions that at least go away on a production system change 38502 + 38530 o change explicit mtx operations to #defines to simplify future changes to a different lock type change 38531 o hookup ipv4 ctlinput paths to a noop routine; we should be handling path mtu changes at least o correct potential null pointer deref in ipsec4_common_input_cb chnage 38685 o fix locking for bundled SA's and for when key exchange is required change 38770 o eliminate recursion on the SAHTREE lock change 38804 o cleanup some types: long -> time_t o remove refrence to dead #define change 38805 o correct some types: long -> time_t o add scan generation # to secpolicy to deal with locking issues change 38806 o use LIST_FOREACH_SAFE instead of handrolled code o change key_flush_spd to drop the sptree lock before purging an entry to avoid lock recursion and to avoid holding the lock over a long-running operation o misc cleanups of tangled and twisty code There is still much to do here but for now things look to be working again. Supported by: FreeBSD Foundation
This commit is contained in:
parent
1a920b1142
commit
9ffa96777e
@ -92,8 +92,6 @@
|
|||||||
|
|
||||||
#include <machine/in_cksum.h>
|
#include <machine/in_cksum.h>
|
||||||
|
|
||||||
#include <net/net_osdep.h>
|
|
||||||
|
|
||||||
#ifdef IPSEC_DEBUG
|
#ifdef IPSEC_DEBUG
|
||||||
int ipsec_debug = 1;
|
int ipsec_debug = 1;
|
||||||
#else
|
#else
|
||||||
@ -249,14 +247,14 @@ ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
|
|||||||
{
|
{
|
||||||
struct secpolicy *sp;
|
struct secpolicy *sp;
|
||||||
|
|
||||||
KASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
|
IPSEC_ASSERT(tdbi != NULL, ("null tdbi"));
|
||||||
KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
||||||
("ipsec_getpolicy: invalid direction %u", dir));
|
("invalid direction %u", dir));
|
||||||
|
|
||||||
sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
|
sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
|
||||||
if (sp == NULL) /*XXX????*/
|
if (sp == NULL) /*XXX????*/
|
||||||
sp = KEY_ALLOCSP_DEFAULT();
|
sp = KEY_ALLOCSP_DEFAULT();
|
||||||
KASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
|
IPSEC_ASSERT(sp != NULL, ("null SP"));
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,11 +281,11 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
struct secpolicy *currsp = NULL; /* policy on socket */
|
struct secpolicy *currsp = NULL; /* policy on socket */
|
||||||
struct secpolicy *sp;
|
struct secpolicy *sp;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
|
IPSEC_ASSERT(inp != NULL, ("null inpcb"));
|
||||||
KASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
|
IPSEC_ASSERT(error != NULL, ("null error"));
|
||||||
KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
||||||
("ipsec_getpolicybysock: invalid direction %u", dir));
|
("invalid direction %u", dir));
|
||||||
|
|
||||||
/* set spidx in pcb */
|
/* set spidx in pcb */
|
||||||
if (inp->inp_vflag & INP_IPV6PROTO) {
|
if (inp->inp_vflag & INP_IPV6PROTO) {
|
||||||
@ -304,7 +302,7 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
if (*error)
|
if (*error)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
KASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
|
IPSEC_ASSERT(pcbsp != NULL, ("null pcbsp"));
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case IPSEC_DIR_INBOUND:
|
case IPSEC_DIR_INBOUND:
|
||||||
currsp = pcbsp->sp_in;
|
currsp = pcbsp->sp_in;
|
||||||
@ -313,7 +311,7 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
currsp = pcbsp->sp_out;
|
currsp = pcbsp->sp_out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
KASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
|
IPSEC_ASSERT(currsp != NULL, ("null currsp"));
|
||||||
|
|
||||||
if (pcbsp->priv) { /* when privilieged socket */
|
if (pcbsp->priv) { /* when privilieged socket */
|
||||||
switch (currsp->policy) {
|
switch (currsp->policy) {
|
||||||
@ -331,8 +329,8 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
|
ipseclog((LOG_ERR, "%s: Invalid policy for PCB %d\n",
|
||||||
"Invalid policy for PCB %d\n", currsp->policy));
|
__func__, currsp->policy));
|
||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -341,9 +339,9 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
if (sp == NULL) { /* no SP found */
|
if (sp == NULL) { /* no SP found */
|
||||||
switch (currsp->policy) {
|
switch (currsp->policy) {
|
||||||
case IPSEC_POLICY_BYPASS:
|
case IPSEC_POLICY_BYPASS:
|
||||||
ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
|
ipseclog((LOG_ERR, "%s: Illegal policy for "
|
||||||
"Illegal policy for non-priviliged defined %d\n",
|
"non-priviliged defined %d\n",
|
||||||
currsp->policy));
|
__func__, currsp->policy));
|
||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -357,20 +355,18 @@ ipsec_getpolicybysock(m, dir, inp, error)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
|
ipseclog((LOG_ERR, "%s: Invalid policy for "
|
||||||
"Invalid policy for PCB %d\n", currsp->policy));
|
"PCB %d\n", __func__, currsp->policy));
|
||||||
*error = EINVAL;
|
*error = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KASSERT(sp != NULL,
|
IPSEC_ASSERT(sp != NULL,
|
||||||
("ipsec_getpolicybysock: null SP (priv %u policy %u",
|
("null SP (priv %u policy %u", pcbsp->priv, currsp->policy));
|
||||||
pcbsp->priv, currsp->policy));
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||||
printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
|
printf("DP %s (priv %u policy %u) allocate SP:%p (refcnt %u)\n",
|
||||||
"SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
|
__func__, pcbsp->priv, currsp->policy, sp, sp->refcnt));
|
||||||
sp, sp->refcnt));
|
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,10 +390,10 @@ ipsec_getpolicybyaddr(m, dir, flag, error)
|
|||||||
struct secpolicyindex spidx;
|
struct secpolicyindex spidx;
|
||||||
struct secpolicy *sp;
|
struct secpolicy *sp;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
|
IPSEC_ASSERT(error != NULL, ("null error"));
|
||||||
KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
|
||||||
("ipsec4_getpolicybaddr: invalid direction %u", dir));
|
("invalid direction %u", dir));
|
||||||
|
|
||||||
sp = NULL;
|
sp = NULL;
|
||||||
if (key_havesp(dir)) {
|
if (key_havesp(dir)) {
|
||||||
@ -405,8 +401,8 @@ ipsec_getpolicybyaddr(m, dir, flag, error)
|
|||||||
*error = ipsec_setspidx(m, &spidx,
|
*error = ipsec_setspidx(m, &spidx,
|
||||||
(flag & IP_FORWARDING) ? 0 : 1);
|
(flag & IP_FORWARDING) ? 0 : 1);
|
||||||
if (*error != 0) {
|
if (*error != 0) {
|
||||||
DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
|
DPRINTF(("%s: setpidx failed, dir %u flag %u\n",
|
||||||
" dir %u flag %u\n", dir, flag));
|
__func__, dir, flag));
|
||||||
bzero(&spidx, sizeof (spidx));
|
bzero(&spidx, sizeof (spidx));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -416,7 +412,7 @@ ipsec_getpolicybyaddr(m, dir, flag, error)
|
|||||||
}
|
}
|
||||||
if (sp == NULL) /* no SP found, use system default */
|
if (sp == NULL) /* no SP found, use system default */
|
||||||
sp = KEY_ALLOCSP_DEFAULT();
|
sp = KEY_ALLOCSP_DEFAULT();
|
||||||
KASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
|
IPSEC_ASSERT(sp != NULL, ("null SP"));
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,17 +431,15 @@ ipsec4_checkpolicy(m, dir, flag, error, inp)
|
|||||||
else
|
else
|
||||||
sp = ipsec_getpolicybysock(m, dir, inp, error);
|
sp = ipsec_getpolicybysock(m, dir, inp, error);
|
||||||
if (sp == NULL) {
|
if (sp == NULL) {
|
||||||
KASSERT(*error != 0,
|
IPSEC_ASSERT(*error != 0, ("getpolicy failed w/o error"));
|
||||||
("ipsec4_checkpolicy: getpolicy failed w/o error"));
|
|
||||||
newipsecstat.ips_out_inval++;
|
newipsecstat.ips_out_inval++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
KASSERT(*error == 0,
|
IPSEC_ASSERT(*error == 0, ("sp w/ error set to %u", *error));
|
||||||
("ipsec4_checkpolicy: sp w/ error set to %u", *error));
|
|
||||||
switch (sp->policy) {
|
switch (sp->policy) {
|
||||||
case IPSEC_POLICY_ENTRUST:
|
case IPSEC_POLICY_ENTRUST:
|
||||||
default:
|
default:
|
||||||
printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
|
printf("%s: invalid policy %u\n", __func__, sp->policy);
|
||||||
/* fall thru... */
|
/* fall thru... */
|
||||||
case IPSEC_POLICY_DISCARD:
|
case IPSEC_POLICY_DISCARD:
|
||||||
newipsecstat.ips_out_polvio++;
|
newipsecstat.ips_out_polvio++;
|
||||||
@ -475,10 +469,10 @@ ipsec4_setspidx_inpcb(m, pcb)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
KASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
|
IPSEC_ASSERT(pcb != NULL, ("null pcb"));
|
||||||
KASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
|
IPSEC_ASSERT(pcb->inp_sp != NULL, ("null inp_sp"));
|
||||||
KASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
|
IPSEC_ASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
|
||||||
("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
|
("null sp_in || sp_out"));
|
||||||
|
|
||||||
error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
|
error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
@ -503,10 +497,10 @@ ipsec6_setspidx_in6pcb(m, pcb)
|
|||||||
struct secpolicyindex *spidx;
|
struct secpolicyindex *spidx;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
KASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
|
IPSEC_ASSERT(pcb != NULL, ("null pcb"));
|
||||||
KASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
|
IPSEC_ASSERT(pcb->in6p_sp != NULL, ("null inp_sp"));
|
||||||
KASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
|
IPSEC_ASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
|
||||||
("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
|
("null sp_in || sp_out"));
|
||||||
|
|
||||||
bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
|
bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
|
||||||
bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
|
bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
|
||||||
@ -550,7 +544,7 @@ ipsec_setspidx(m, spidx, needport)
|
|||||||
int len;
|
int len;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* validate m->m_pkthdr.len. we see incorrect length if we
|
* validate m->m_pkthdr.len. we see incorrect length if we
|
||||||
@ -562,18 +556,15 @@ ipsec_setspidx(m, spidx, needport)
|
|||||||
len += n->m_len;
|
len += n->m_len;
|
||||||
if (m->m_pkthdr.len != len) {
|
if (m->m_pkthdr.len != len) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_setspidx: "
|
printf("%s: pkthdr len(%d) mismatch (%d), ignored.\n",
|
||||||
"total of m_len(%d) != pkthdr.len(%d), "
|
__func__, len, m->m_pkthdr.len));
|
||||||
"ignored.\n",
|
|
||||||
len, m->m_pkthdr.len));
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->m_pkthdr.len < sizeof(struct ip)) {
|
if (m->m_pkthdr.len < sizeof(struct ip)) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_setspidx: "
|
printf("%s: pkthdr len(%d) too small (v4), ignored.\n",
|
||||||
"pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
|
__func__, m->m_pkthdr.len));
|
||||||
m->m_pkthdr.len));
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,9 +590,8 @@ ipsec_setspidx(m, spidx, needport)
|
|||||||
case 6:
|
case 6:
|
||||||
if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
|
if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_setspidx: "
|
printf("%s: pkthdr len(%d) too small (v6), "
|
||||||
"pkthdr.len(%d) < sizeof(struct ip6_hdr), "
|
"ignored\n", __func__, m->m_pkthdr.len));
|
||||||
"ignored.\n", m->m_pkthdr.len));
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
error = ipsec6_setspidx_ipaddr(m, spidx);
|
error = ipsec6_setspidx_ipaddr(m, spidx);
|
||||||
@ -612,8 +602,8 @@ ipsec_setspidx(m, spidx, needport)
|
|||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_setspidx: "
|
printf("%s: " "unknown IP version %u, ignored.\n",
|
||||||
"unknown IP version %u, ignored.\n", v));
|
__func__, v));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -625,9 +615,8 @@ ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
|
|||||||
int off;
|
int off;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
KASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(m->m_pkthdr.len >= sizeof(struct ip),
|
IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
|
||||||
("ipsec4_get_ulp: packet too short"));
|
|
||||||
|
|
||||||
/* NB: ip_input() flips it into host endian XXX need more checking */
|
/* NB: ip_input() flips it into host endian XXX need more checking */
|
||||||
if (m->m_len < sizeof (struct ip)) {
|
if (m->m_len < sizeof (struct ip)) {
|
||||||
@ -747,10 +736,10 @@ ipsec6_get_ulp(m, spidx, needport)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
panic("ipsec6_get_ulp: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
|
printf("%s:\n", __func__); kdebug_mbuf(m));
|
||||||
|
|
||||||
/* set default */
|
/* set default */
|
||||||
spidx->ul_proto = IPSEC_ULPROTO_ANY;
|
spidx->ul_proto = IPSEC_ULPROTO_ANY;
|
||||||
@ -851,19 +840,16 @@ ipsec_init_policy(so, pcb_sp)
|
|||||||
|
|
||||||
/* sanity check. */
|
/* sanity check. */
|
||||||
if (so == NULL || pcb_sp == NULL)
|
if (so == NULL || pcb_sp == NULL)
|
||||||
panic("ipsec_init_policy: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
|
new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
|
||||||
M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
|
M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
|
ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so->so_cred != 0 && so->so_cred->cr_uid == 0)
|
new->priv = IPSEC_IS_PRIVILEGED_SO(so);
|
||||||
new->priv = 1;
|
|
||||||
else
|
|
||||||
new->priv = 0;
|
|
||||||
|
|
||||||
if ((new->sp_in = KEY_NEWSP()) == NULL) {
|
if ((new->sp_in = KEY_NEWSP()) == NULL) {
|
||||||
ipsec_delpcbpolicy(new);
|
ipsec_delpcbpolicy(new);
|
||||||
@ -918,14 +904,14 @@ ipsec_newisr(void)
|
|||||||
|
|
||||||
p = malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, M_NOWAIT|M_ZERO);
|
p = malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, M_NOWAIT|M_ZERO);
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
mtx_init(&p->lock, "ipsec request", NULL, MTX_DEF);
|
IPSECREQUEST_LOCK_INIT(p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ipsec_delisr(struct ipsecrequest *p)
|
ipsec_delisr(struct ipsecrequest *p)
|
||||||
{
|
{
|
||||||
mtx_destroy(&p->lock);
|
IPSECREQUEST_LOCK_DESTROY(p);
|
||||||
free(p, M_IPSEC_SR);
|
free(p, M_IPSEC_SR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1005,7 +991,7 @@ ipsec_set_policy(pcb_sp, optname, request, len, priv)
|
|||||||
xpl = (struct sadb_x_policy *)request;
|
xpl = (struct sadb_x_policy *)request;
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_set_policy: passed policy\n");
|
printf("%s: passed policy\n", __func__);
|
||||||
kdebug_sadb_x_policy((struct sadb_ext *)xpl));
|
kdebug_sadb_x_policy((struct sadb_ext *)xpl));
|
||||||
|
|
||||||
/* check policy type */
|
/* check policy type */
|
||||||
@ -1028,7 +1014,7 @@ ipsec_set_policy(pcb_sp, optname, request, len, priv)
|
|||||||
KEY_FREESP(pcb_sp);
|
KEY_FREESP(pcb_sp);
|
||||||
*pcb_sp = newsp;
|
*pcb_sp = newsp;
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_set_policy: new policy\n");
|
printf("%s: new policy\n", __func__);
|
||||||
kdebug_secpolicy(newsp));
|
kdebug_secpolicy(newsp));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1046,14 +1032,13 @@ ipsec_get_policy(pcb_sp, mp)
|
|||||||
|
|
||||||
*mp = key_sp2msg(pcb_sp);
|
*mp = key_sp2msg(pcb_sp);
|
||||||
if (!*mp) {
|
if (!*mp) {
|
||||||
ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
|
ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*mp)->m_type = MT_DATA;
|
(*mp)->m_type = MT_DATA;
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_get_policy:\n");
|
printf("%s:\n", __func__); kdebug_mbuf(*mp));
|
||||||
kdebug_mbuf(*mp));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1085,7 +1070,7 @@ ipsec4_set_policy(inp, optname, request, len, priv)
|
|||||||
pcb_sp = &inp->inp_sp->sp_out;
|
pcb_sp = &inp->inp_sp->sp_out;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
|
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
|
||||||
xpl->sadb_x_policy_dir));
|
xpl->sadb_x_policy_dir));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -1106,7 +1091,7 @@ ipsec4_get_policy(inp, request, len, mp)
|
|||||||
/* sanity check. */
|
/* sanity check. */
|
||||||
if (inp == NULL || request == NULL || mp == NULL)
|
if (inp == NULL || request == NULL || mp == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
KASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
|
IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
|
||||||
if (len < sizeof(*xpl))
|
if (len < sizeof(*xpl))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
xpl = (struct sadb_x_policy *)request;
|
xpl = (struct sadb_x_policy *)request;
|
||||||
@ -1120,7 +1105,7 @@ ipsec4_get_policy(inp, request, len, mp)
|
|||||||
pcb_sp = inp->inp_sp->sp_out;
|
pcb_sp = inp->inp_sp->sp_out;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
|
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
|
||||||
xpl->sadb_x_policy_dir));
|
xpl->sadb_x_policy_dir));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -1133,7 +1118,7 @@ int
|
|||||||
ipsec4_delete_pcbpolicy(inp)
|
ipsec4_delete_pcbpolicy(inp)
|
||||||
struct inpcb *inp;
|
struct inpcb *inp;
|
||||||
{
|
{
|
||||||
KASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
|
IPSEC_ASSERT(inp != NULL, ("null inp"));
|
||||||
|
|
||||||
if (inp->inp_sp == NULL)
|
if (inp->inp_sp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1178,7 +1163,7 @@ ipsec6_set_policy(in6p, optname, request, len, priv)
|
|||||||
pcb_sp = &in6p->in6p_sp->sp_out;
|
pcb_sp = &in6p->in6p_sp->sp_out;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
|
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
|
||||||
xpl->sadb_x_policy_dir));
|
xpl->sadb_x_policy_dir));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -1199,7 +1184,7 @@ ipsec6_get_policy(in6p, request, len, mp)
|
|||||||
/* sanity check. */
|
/* sanity check. */
|
||||||
if (in6p == NULL || request == NULL || mp == NULL)
|
if (in6p == NULL || request == NULL || mp == NULL)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
KASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
|
IPSEC_ASSERT(in6p->in6p_sp != NULL, ("null in6p_sp"));
|
||||||
if (len < sizeof(*xpl))
|
if (len < sizeof(*xpl))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
xpl = (struct sadb_x_policy *)request;
|
xpl = (struct sadb_x_policy *)request;
|
||||||
@ -1213,7 +1198,7 @@ ipsec6_get_policy(in6p, request, len, mp)
|
|||||||
pcb_sp = in6p->in6p_sp->sp_out;
|
pcb_sp = in6p->in6p_sp->sp_out;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
|
ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
|
||||||
xpl->sadb_x_policy_dir));
|
xpl->sadb_x_policy_dir));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -1225,7 +1210,7 @@ int
|
|||||||
ipsec6_delete_pcbpolicy(in6p)
|
ipsec6_delete_pcbpolicy(in6p)
|
||||||
struct in6pcb *in6p;
|
struct in6pcb *in6p;
|
||||||
{
|
{
|
||||||
KASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
|
IPSEC_ASSERT(in6p != NULL, ("null in6p"));
|
||||||
|
|
||||||
if (in6p->in6p_sp == NULL)
|
if (in6p->in6p_sp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
@ -1255,10 +1240,9 @@ ipsec_get_reqlevel(isr)
|
|||||||
u_int esp_trans_deflev, esp_net_deflev;
|
u_int esp_trans_deflev, esp_net_deflev;
|
||||||
u_int ah_trans_deflev, ah_net_deflev;
|
u_int ah_trans_deflev, ah_net_deflev;
|
||||||
|
|
||||||
KASSERT(isr != NULL && isr->sp != NULL,
|
IPSEC_ASSERT(isr != NULL && isr->sp != NULL, ("null argument"));
|
||||||
("ipsec_get_reqlevel: null argument"));
|
IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
|
||||||
KASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
|
("af family mismatch, src %u, dst %u",
|
||||||
("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
|
|
||||||
isr->sp->spidx.src.sa.sa_family,
|
isr->sp->spidx.src.sa.sa_family,
|
||||||
isr->sp->spidx.dst.sa.sa_family));
|
isr->sp->spidx.dst.sa.sa_family));
|
||||||
|
|
||||||
@ -1293,8 +1277,8 @@ ipsec_get_reqlevel(isr)
|
|||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
panic("key_get_reqlevel: unknown af %u",
|
panic("%s: unknown af %u",
|
||||||
isr->sp->spidx.src.sa.sa_family);
|
__func__, isr->sp->spidx.src.sa.sa_family);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef IPSEC_CHECK_DEFAULT
|
#undef IPSEC_CHECK_DEFAULT
|
||||||
@ -1322,8 +1306,7 @@ ipsec_get_reqlevel(isr)
|
|||||||
level = IPSEC_LEVEL_USE;
|
level = IPSEC_LEVEL_USE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("ipsec_get_reqlevel: "
|
panic("%s: Illegal protocol defined %u\n", __func__,
|
||||||
"Illegal protocol defined %u\n",
|
|
||||||
isr->saidx.proto);
|
isr->saidx.proto);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1337,8 +1320,7 @@ ipsec_get_reqlevel(isr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
|
panic("%s: Illegal IPsec level %u\n", __func__, isr->level);
|
||||||
isr->level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return level;
|
return level;
|
||||||
@ -1361,8 +1343,7 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
|
|||||||
int need_auth;
|
int need_auth;
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec_in_reject: using SP\n");
|
printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
|
||||||
kdebug_secpolicy(sp));
|
|
||||||
|
|
||||||
/* check policy */
|
/* check policy */
|
||||||
switch (sp->policy) {
|
switch (sp->policy) {
|
||||||
@ -1373,8 +1354,8 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
|
IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
|
||||||
("ipsec_in_reject: invalid policy %u", sp->policy));
|
("invalid policy %u", sp->policy));
|
||||||
|
|
||||||
/* XXX should compare policy against ipsec header history */
|
/* XXX should compare policy against ipsec header history */
|
||||||
|
|
||||||
@ -1386,7 +1367,7 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
|
|||||||
case IPPROTO_ESP:
|
case IPPROTO_ESP:
|
||||||
if ((m->m_flags & M_DECRYPTED) == 0) {
|
if ((m->m_flags & M_DECRYPTED) == 0) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_in_reject: ESP m_flags:%x\n",
|
printf("%s: ESP m_flags:%x\n", __func__,
|
||||||
m->m_flags));
|
m->m_flags));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1396,7 +1377,7 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
|
|||||||
isr->sav->tdb_authalgxform != NULL &&
|
isr->sav->tdb_authalgxform != NULL &&
|
||||||
(m->m_flags & M_AUTHIPDGM) == 0) {
|
(m->m_flags & M_AUTHIPDGM) == 0) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
|
printf("%s: ESP/AH m_flags:%x\n", __func__,
|
||||||
m->m_flags));
|
m->m_flags));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1405,7 +1386,7 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
|
|||||||
need_auth = 1;
|
need_auth = 1;
|
||||||
if ((m->m_flags & M_AUTHIPHDR) == 0) {
|
if ((m->m_flags & M_AUTHIPHDR) == 0) {
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
|
||||||
printf("ipsec_in_reject: AH m_flags:%x\n",
|
printf("%s: AH m_flags:%x\n", __func__,
|
||||||
m->m_flags));
|
m->m_flags));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1437,7 +1418,7 @@ ipsec4_in_reject(m, inp)
|
|||||||
int error;
|
int error;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
|
|
||||||
/* get SP for this packet.
|
/* get SP for this packet.
|
||||||
* When we are called from ip_forward(), we call
|
* When we are called from ip_forward(), we call
|
||||||
@ -1512,8 +1493,7 @@ ipsec_hdrsiz(struct secpolicy *sp)
|
|||||||
size_t siz;
|
size_t siz;
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec_hdrsiz: using SP\n");
|
printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
|
||||||
kdebug_secpolicy(sp));
|
|
||||||
|
|
||||||
switch (sp->policy) {
|
switch (sp->policy) {
|
||||||
case IPSEC_POLICY_DISCARD:
|
case IPSEC_POLICY_DISCARD:
|
||||||
@ -1522,8 +1502,8 @@ ipsec_hdrsiz(struct secpolicy *sp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
|
IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
|
||||||
("ipsec_hdrsiz: invalid policy %u", sp->policy));
|
("invalid policy %u", sp->policy));
|
||||||
|
|
||||||
siz = 0;
|
siz = 0;
|
||||||
for (isr = sp->req; isr != NULL; isr = isr->next) {
|
for (isr = sp->req; isr != NULL; isr = isr->next) {
|
||||||
@ -1552,8 +1532,8 @@ ipsec_hdrsiz(struct secpolicy *sp)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ipseclog((LOG_ERR, "ipsec_hdrsiz: "
|
ipseclog((LOG_ERR, "%s: unknown AF %d in "
|
||||||
"unknown AF %d in IPsec tunnel SA\n",
|
"IPsec tunnel SA\n", __func__,
|
||||||
((struct sockaddr *)&isr->saidx.dst)->sa_family));
|
((struct sockaddr *)&isr->saidx.dst)->sa_family));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1575,7 +1555,7 @@ ipsec4_hdrsiz(m, dir, inp)
|
|||||||
int error;
|
int error;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
|
|
||||||
/* get SP for this packet.
|
/* get SP for this packet.
|
||||||
* When we are called from ip_forward(), we call
|
* When we are called from ip_forward(), we call
|
||||||
@ -1589,7 +1569,7 @@ ipsec4_hdrsiz(m, dir, inp)
|
|||||||
if (sp != NULL) {
|
if (sp != NULL) {
|
||||||
size = ipsec_hdrsiz(sp);
|
size = ipsec_hdrsiz(sp);
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec4_hdrsiz: size:%lu.\n",
|
printf("%s: size:%lu.\n", __func__,
|
||||||
(unsigned long)size));
|
(unsigned long)size));
|
||||||
|
|
||||||
KEY_FREESP(&sp);
|
KEY_FREESP(&sp);
|
||||||
@ -1613,9 +1593,9 @@ ipsec6_hdrsiz(m, dir, in6p)
|
|||||||
int error;
|
int error;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(in6p == NULL || in6p->in6p_socket != NULL,
|
IPSEC_ASSERT(in6p == NULL || in6p->in6p_socket != NULL,
|
||||||
("ipsec6_hdrsize: socket w/o inpcb"));
|
("socket w/o inpcb"));
|
||||||
|
|
||||||
/* get SP for this packet */
|
/* get SP for this packet */
|
||||||
/* XXX Is it right to call with IP_FORWARDING. */
|
/* XXX Is it right to call with IP_FORWARDING. */
|
||||||
@ -1628,7 +1608,7 @@ ipsec6_hdrsiz(m, dir, in6p)
|
|||||||
return 0;
|
return 0;
|
||||||
size = ipsec_hdrsiz(sp);
|
size = ipsec_hdrsiz(sp);
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
|
printf("%s: size:%lu.\n", __func__, (unsigned long)size));
|
||||||
KEY_FREESP(&sp);
|
KEY_FREESP(&sp);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -1656,12 +1636,10 @@ ipsec_chkreplay(seq, sav)
|
|||||||
u_int32_t wsizeb; /* constant: bits of window size */
|
u_int32_t wsizeb; /* constant: bits of window size */
|
||||||
int frlast; /* constant: last frame */
|
int frlast; /* constant: last frame */
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipsec_chkreplay");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
|
IPSEC_ASSERT(sav != NULL, ("Null SA"));
|
||||||
KASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
|
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
|
||||||
|
|
||||||
replay = sav->replay;
|
replay = sav->replay;
|
||||||
|
|
||||||
@ -1718,12 +1696,10 @@ ipsec_updatereplay(seq, sav)
|
|||||||
u_int32_t wsizeb; /* constant: bits of window size */
|
u_int32_t wsizeb; /* constant: bits of window size */
|
||||||
int frlast; /* constant: last frame */
|
int frlast; /* constant: last frame */
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipsec_updatereplay");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
|
IPSEC_ASSERT(sav != NULL, ("Null SA"));
|
||||||
KASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
|
IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
|
||||||
|
|
||||||
replay = sav->replay;
|
replay = sav->replay;
|
||||||
|
|
||||||
@ -1794,8 +1770,8 @@ ok:
|
|||||||
if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
|
if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
|
ipseclog((LOG_WARNING, "%s: replay counter made %d cycle. %s\n",
|
||||||
replay->overflow, ipsec_logsastr(sav)));
|
__func__, replay->overflow, ipsec_logsastr(sav)));
|
||||||
}
|
}
|
||||||
|
|
||||||
replay->count++;
|
replay->count++;
|
||||||
@ -1872,8 +1848,8 @@ ipsec_logsastr(sav)
|
|||||||
char *p;
|
char *p;
|
||||||
struct secasindex *saidx = &sav->sah->saidx;
|
struct secasindex *saidx = &sav->sah->saidx;
|
||||||
|
|
||||||
KASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
|
IPSEC_ASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
|
||||||
("ipsec_logsastr: address family mismatch"));
|
("address family mismatch"));
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
|
snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <net/pfkeyv2.h>
|
#include <net/pfkeyv2.h>
|
||||||
#include <netipsec/keydb.h>
|
#include <netipsec/keydb.h>
|
||||||
|
#include <netipsec/ipsec_osdep.h>
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
|
|
||||||
@ -79,8 +80,8 @@ struct secpolicy {
|
|||||||
u_int state; /* 0: dead, others: alive */
|
u_int state; /* 0: dead, others: alive */
|
||||||
#define IPSEC_SPSTATE_DEAD 0
|
#define IPSEC_SPSTATE_DEAD 0
|
||||||
#define IPSEC_SPSTATE_ALIVE 1
|
#define IPSEC_SPSTATE_ALIVE 1
|
||||||
|
u_int16_t policy; /* policy_type per pfkeyv2.h */
|
||||||
u_int policy; /* DISCARD, NONE or IPSEC, see keyv2.h */
|
u_int16_t scangen; /* scan generation # */
|
||||||
struct ipsecrequest *req;
|
struct ipsecrequest *req;
|
||||||
/* pointer to the ipsec request tree, */
|
/* pointer to the ipsec request tree, */
|
||||||
/* if policy == IPSEC else this value == NULL.*/
|
/* if policy == IPSEC else this value == NULL.*/
|
||||||
@ -92,12 +93,19 @@ struct secpolicy {
|
|||||||
* "lifetime" is passed by sadb_lifetime.sadb_lifetime_addtime.
|
* "lifetime" is passed by sadb_lifetime.sadb_lifetime_addtime.
|
||||||
* "validtime" is passed by sadb_lifetime.sadb_lifetime_usetime.
|
* "validtime" is passed by sadb_lifetime.sadb_lifetime_usetime.
|
||||||
*/
|
*/
|
||||||
long created; /* time created the policy */
|
time_t created; /* time created the policy */
|
||||||
long lastused; /* updated every when kernel sends a packet */
|
time_t lastused; /* updated every when kernel sends a packet */
|
||||||
long lifetime; /* duration of the lifetime of this policy */
|
long lifetime; /* duration of the lifetime of this policy */
|
||||||
long validtime; /* duration this policy is valid without use */
|
long validtime; /* duration this policy is valid without use */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SECPOLICY_LOCK_INIT(_sp) \
|
||||||
|
mtx_init(&(_sp)->lock, "ipsec policy", NULL, MTX_DEF)
|
||||||
|
#define SECPOLICY_LOCK(_sp) mtx_lock(&(_sp)->lock)
|
||||||
|
#define SECPOLICY_UNLOCK(_sp) mtx_unlock(&(_sp)->lock)
|
||||||
|
#define SECPOLICY_LOCK_DESTROY(_sp) mtx_destroy(&(_sp)->lock)
|
||||||
|
#define SECPOLICY_LOCK_ASSERT(_sp) mtx_assert(&(_sp)->lock, MA_OWNED)
|
||||||
|
|
||||||
/* Request for IPsec */
|
/* Request for IPsec */
|
||||||
struct ipsecrequest {
|
struct ipsecrequest {
|
||||||
struct ipsecrequest *next;
|
struct ipsecrequest *next;
|
||||||
@ -112,6 +120,18 @@ struct ipsecrequest {
|
|||||||
struct mtx lock; /* to interlock updates */
|
struct mtx lock; /* to interlock updates */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need recursion for when crypto callbacks happen directly,
|
||||||
|
* as in the case of software crypto. Need to look at how
|
||||||
|
* hard it is to remove this...
|
||||||
|
*/
|
||||||
|
#define IPSECREQUEST_LOCK_INIT(_isr) \
|
||||||
|
mtx_init(&(_isr)->lock, "ipsec request", NULL, MTX_DEF | MTX_RECURSE)
|
||||||
|
#define IPSECREQUEST_LOCK(_isr) mtx_lock(&(_isr)->lock)
|
||||||
|
#define IPSECREQUEST_UNLOCK(_isr) mtx_unlock(&(_isr)->lock)
|
||||||
|
#define IPSECREQUEST_LOCK_DESTROY(_isr) mtx_destroy(&(_isr)->lock)
|
||||||
|
#define IPSECREQUEST_LOCK_ASSERT(_isr) mtx_assert(&(_isr)->lock, MA_OWNED)
|
||||||
|
|
||||||
/* security policy in PCB */
|
/* security policy in PCB */
|
||||||
struct inpcbpolicy {
|
struct inpcbpolicy {
|
||||||
struct secpolicy *sp_in;
|
struct secpolicy *sp_in;
|
||||||
@ -125,7 +145,7 @@ struct secspacq {
|
|||||||
|
|
||||||
struct secpolicyindex spidx;
|
struct secpolicyindex spidx;
|
||||||
|
|
||||||
long created; /* for lifetime */
|
time_t created; /* for lifetime */
|
||||||
int count; /* for lifetime */
|
int count; /* for lifetime */
|
||||||
/* XXX: here is mbuf place holder to be sent ? */
|
/* XXX: here is mbuf place holder to be sent ? */
|
||||||
};
|
};
|
||||||
@ -367,7 +387,9 @@ extern void ipsec_dumpmbuf __P((struct mbuf *));
|
|||||||
|
|
||||||
struct m_tag;
|
struct m_tag;
|
||||||
extern void ah4_input(struct mbuf *m, int off);
|
extern void ah4_input(struct mbuf *m, int off);
|
||||||
|
extern void ah4_ctlinput(int cmd, struct sockaddr *sa, void *);
|
||||||
extern void esp4_input(struct mbuf *m, int off);
|
extern void esp4_input(struct mbuf *m, int off);
|
||||||
|
extern void esp4_ctlinput(int cmd, struct sockaddr *sa, void *);
|
||||||
extern void ipcomp4_input(struct mbuf *m, int off);
|
extern void ipcomp4_input(struct mbuf *m, int off);
|
||||||
extern int ipsec4_common_input(struct mbuf *m, ...);
|
extern int ipsec4_common_input(struct mbuf *m, ...);
|
||||||
extern int ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
extern int ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
||||||
|
@ -91,11 +91,11 @@
|
|||||||
#include <machine/in_cksum.h>
|
#include <machine/in_cksum.h>
|
||||||
#include <machine/stdarg.h>
|
#include <machine/stdarg.h>
|
||||||
|
|
||||||
#include <net/net_osdep.h>
|
|
||||||
|
|
||||||
#define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \
|
#define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \
|
||||||
(p) == IPPROTO_AH ? (y)++ : (z)++)
|
(p) == IPPROTO_AH ? (y)++ : (z)++)
|
||||||
|
|
||||||
|
static void ipsec4_common_ctlinput(int, struct sockaddr *, void *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ipsec_common_input gets called when an IPsec-protected packet
|
* ipsec_common_input gets called when an IPsec-protected packet
|
||||||
* is received by IPv4 or IPv6. It's job is to find the right SA
|
* is received by IPv4 or IPv6. It's job is to find the right SA
|
||||||
@ -113,7 +113,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
|||||||
IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input,
|
IPSEC_ISTAT(sproto, espstat.esps_input, ahstat.ahs_input,
|
||||||
ipcompstat.ipcomps_input);
|
ipcompstat.ipcomps_input);
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec_common_input: null packet"));
|
IPSEC_ASSERT(m != NULL, ("null packet"));
|
||||||
|
|
||||||
if ((sproto == IPPROTO_ESP && !esp_enable) ||
|
if ((sproto == IPPROTO_ESP && !esp_enable) ||
|
||||||
(sproto == IPPROTO_AH && !ah_enable) ||
|
(sproto == IPPROTO_AH && !ah_enable) ||
|
||||||
@ -128,7 +128,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
|||||||
m_freem(m);
|
m_freem(m);
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
||||||
ipcompstat.ipcomps_hdrops);
|
ipcompstat.ipcomps_hdrops);
|
||||||
DPRINTF(("ipsec_common_input: packet too small\n"));
|
DPRINTF(("%s: packet too small\n", __func__));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +170,7 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
|||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
DPRINTF(("ipsec_common_input: unsupported protocol "
|
DPRINTF(("%s: unsupported protocol family %u\n", __func__, af));
|
||||||
"family %u\n", af));
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_nopf, ahstat.ahs_nopf,
|
IPSEC_ISTAT(sproto, espstat.esps_nopf, ahstat.ahs_nopf,
|
||||||
ipcompstat.ipcomps_nopf);
|
ipcompstat.ipcomps_nopf);
|
||||||
@ -181,9 +180,8 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
|||||||
/* NB: only pass dst since key_allocsa follows RFC2401 */
|
/* NB: only pass dst since key_allocsa follows RFC2401 */
|
||||||
sav = KEY_ALLOCSA(&dst_address, sproto, spi);
|
sav = KEY_ALLOCSA(&dst_address, sproto, spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
DPRINTF(("ipsec_common_input: no key association found for"
|
DPRINTF(("%s: no key association found for SA %s/%08lx/%u\n",
|
||||||
" SA %s/%08lx/%u\n",
|
__func__, ipsec_address(&dst_address),
|
||||||
ipsec_address(&dst_address),
|
|
||||||
(u_long) ntohl(spi), sproto));
|
(u_long) ntohl(spi), sproto));
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb,
|
IPSEC_ISTAT(sproto, espstat.esps_notdb, ahstat.ahs_notdb,
|
||||||
ipcompstat.ipcomps_notdb);
|
ipcompstat.ipcomps_notdb);
|
||||||
@ -192,9 +190,8 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sav->tdb_xform == NULL) {
|
if (sav->tdb_xform == NULL) {
|
||||||
DPRINTF(("ipsec_common_input: attempted to use uninitialized"
|
DPRINTF(("%s: attempted to use uninitialized SA %s/%08lx/%u\n",
|
||||||
" SA %s/%08lx/%u\n",
|
__func__, ipsec_address(&dst_address),
|
||||||
ipsec_address(&dst_address),
|
|
||||||
(u_long) ntohl(spi), sproto));
|
(u_long) ntohl(spi), sproto));
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_noxform, ahstat.ahs_noxform,
|
IPSEC_ISTAT(sproto, espstat.esps_noxform, ahstat.ahs_noxform,
|
||||||
ipcompstat.ipcomps_noxform);
|
ipcompstat.ipcomps_noxform);
|
||||||
@ -236,12 +233,26 @@ ah4_input(struct mbuf *m, int off)
|
|||||||
{
|
{
|
||||||
ipsec4_common_input(m, off, IPPROTO_AH);
|
ipsec4_common_input(m, off, IPPROTO_AH);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
ah4_ctlinput(int cmd, struct sockaddr *sa, void *v)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET &&
|
||||||
|
sa->sa_len == sizeof(struct sockaddr_in))
|
||||||
|
ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_AH);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
esp4_input(struct mbuf *m, int off)
|
esp4_input(struct mbuf *m, int off)
|
||||||
{
|
{
|
||||||
ipsec4_common_input(m, off, IPPROTO_ESP);
|
ipsec4_common_input(m, off, IPPROTO_ESP);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
esp4_ctlinput(int cmd, struct sockaddr *sa, void *v)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET &&
|
||||||
|
sa->sa_len == sizeof(struct sockaddr_in))
|
||||||
|
ipsec4_common_ctlinput(cmd, sa, v, IPPROTO_ESP);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ipcomp4_input(struct mbuf *m, int off)
|
ipcomp4_input(struct mbuf *m, int off)
|
||||||
@ -266,25 +277,22 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
struct secasindex *saidx;
|
struct secasindex *saidx;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipsec4_common_input_cb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec4_common_input_cb: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(sav != NULL, ("ipsec4_common_input_cb: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
KASSERT(sav->sah != NULL, ("ipsec4_common_input_cb: null SAH"));
|
IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
|
||||||
saidx = &sav->sah->saidx;
|
saidx = &sav->sah->saidx;
|
||||||
af = saidx->dst.sa.sa_family;
|
af = saidx->dst.sa.sa_family;
|
||||||
KASSERT(af == AF_INET, ("ipsec4_common_input_cb: unexpected af %u",af));
|
IPSEC_ASSERT(af == AF_INET, ("unexpected af %u", af));
|
||||||
sproto = saidx->proto;
|
sproto = saidx->proto;
|
||||||
KASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
|
IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
|
||||||
sproto == IPPROTO_IPCOMP,
|
sproto == IPPROTO_IPCOMP,
|
||||||
("ipsec4_common_input_cb: unexpected security protocol %u",
|
("unexpected security protocol %u", sproto));
|
||||||
sproto));
|
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
DPRINTF(("ipsec4_common_input_cb: null mbuf"));
|
DPRINTF(("%s: null mbuf", __func__));
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
|
IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
|
||||||
ipcompstat.ipcomps_badkcr);
|
ipcompstat.ipcomps_badkcr);
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
@ -294,9 +302,8 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
if (skip != 0) {
|
if (skip != 0) {
|
||||||
/* Fix IPv4 header */
|
/* Fix IPv4 header */
|
||||||
if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
|
if (m->m_len < skip && (m = m_pullup(m, skip)) == NULL) {
|
||||||
DPRINTF(("ipsec4_common_input_cb: processing failed "
|
DPRINTF(("%s: processing failed for SA %s/%08lx\n",
|
||||||
"for SA %s/%08lx\n",
|
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
||||||
ipcompstat.ipcomps_hdrops);
|
ipcompstat.ipcomps_hdrops);
|
||||||
@ -343,9 +350,9 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
(saidx->proxy.sa.sa_family != AF_INET &&
|
(saidx->proxy.sa.sa_family != AF_INET &&
|
||||||
saidx->proxy.sa.sa_family != 0)) {
|
saidx->proxy.sa.sa_family != 0)) {
|
||||||
|
|
||||||
DPRINTF(("ipsec4_common_input_cb: inner "
|
DPRINTF(("%s: inner source address %s doesn't "
|
||||||
"source address %s doesn't correspond to "
|
"correspond to expected proxy source %s, "
|
||||||
"expected proxy source %s, SA %s/%08lx\n",
|
"SA %s/%08lx\n", __func__,
|
||||||
inet_ntoa4(ipn.ip_src),
|
inet_ntoa4(ipn.ip_src),
|
||||||
ipsp_address(saidx->proxy),
|
ipsp_address(saidx->proxy),
|
||||||
ipsp_address(saidx->dst),
|
ipsp_address(saidx->dst),
|
||||||
@ -387,9 +394,9 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
||||||
saidx->proxy.sa.sa_family != 0)) {
|
saidx->proxy.sa.sa_family != 0)) {
|
||||||
|
|
||||||
DPRINTF(("ipsec4_common_input_cb: inner "
|
DPRINTF(("%s: inner source address %s doesn't "
|
||||||
"source address %s doesn't correspond to "
|
"correspond to expected proxy source %s, "
|
||||||
"expected proxy source %s, SA %s/%08lx\n",
|
"SA %s/%08lx\n", __func__,
|
||||||
ip6_sprintf(&ip6n.ip6_src),
|
ip6_sprintf(&ip6n.ip6_src),
|
||||||
ipsec_address(&saidx->proxy),
|
ipsec_address(&saidx->proxy),
|
||||||
ipsec_address(&saidx->dst),
|
ipsec_address(&saidx->dst),
|
||||||
@ -417,7 +424,7 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
|
mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
|
||||||
sizeof(struct tdb_ident), M_NOWAIT);
|
sizeof(struct tdb_ident), M_NOWAIT);
|
||||||
if (mtag == NULL) {
|
if (mtag == NULL) {
|
||||||
DPRINTF(("ipsec4_common_input_cb: failed to get tag\n"));
|
DPRINTF(("%s: failed to get tag\n", __func__));
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
||||||
ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
|
ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
@ -444,8 +451,8 @@ ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav,
|
|||||||
IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
|
IPSEC_ISTAT(sproto, espstat.esps_qfull, ahstat.ahs_qfull,
|
||||||
ipcompstat.ipcomps_qfull);
|
ipcompstat.ipcomps_qfull);
|
||||||
|
|
||||||
DPRINTF(("ipsec4_common_input_cb: queue full; "
|
DPRINTF(("%s: queue full; proto %u packet dropped\n",
|
||||||
"proto %u packet dropped\n", sproto));
|
__func__, sproto));
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -453,6 +460,12 @@ bad:
|
|||||||
m_freem(m);
|
m_freem(m);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ipsec4_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto)
|
||||||
|
{
|
||||||
|
/* XXX nothing just yet */
|
||||||
|
}
|
||||||
#endif /* INET */
|
#endif /* INET */
|
||||||
|
|
||||||
#ifdef INET6
|
#ifdef INET6
|
||||||
@ -465,7 +478,7 @@ ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
struct ip6_ext ip6e;
|
struct ip6_ext ip6e;
|
||||||
|
|
||||||
if (*offp < sizeof(struct ip6_hdr)) {
|
if (*offp < sizeof(struct ip6_hdr)) {
|
||||||
DPRINTF(("ipsec6_common_input: bad offset %u\n", *offp));
|
DPRINTF(("%s: bad offset %u\n", __func__, *offp));
|
||||||
return IPPROTO_DONE;
|
return IPPROTO_DONE;
|
||||||
} else if (*offp == sizeof(struct ip6_hdr)) {
|
} else if (*offp == sizeof(struct ip6_hdr)) {
|
||||||
protoff = offsetof(struct ip6_hdr, ip6_nxt);
|
protoff = offsetof(struct ip6_hdr, ip6_nxt);
|
||||||
@ -482,13 +495,13 @@ ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
l = (ip6e.ip6e_len + 2) << 2;
|
l = (ip6e.ip6e_len + 2) << 2;
|
||||||
else
|
else
|
||||||
l = (ip6e.ip6e_len + 1) << 3;
|
l = (ip6e.ip6e_len + 1) << 3;
|
||||||
KASSERT(l > 0, ("ah6_input: l went zero or negative"));
|
IPSEC_ASSERT(l > 0, ("l went zero or negative"));
|
||||||
} while (protoff + l < *offp);
|
} while (protoff + l < *offp);
|
||||||
|
|
||||||
/* Malformed packet check */
|
/* Malformed packet check */
|
||||||
if (protoff + l != *offp) {
|
if (protoff + l != *offp) {
|
||||||
DPRINTF(("ipsec6_common_input: bad packet header chain, "
|
DPRINTF(("%s: bad packet header chain, protoff %u, "
|
||||||
"protoff %u, l %u, off %u\n", protoff, l, *offp));
|
"l %u, off %u\n", __func__, protoff, l, *offp));
|
||||||
IPSEC_ISTAT(proto, espstat.esps_hdrops,
|
IPSEC_ISTAT(proto, espstat.esps_hdrops,
|
||||||
ahstat.ahs_hdrops,
|
ahstat.ahs_hdrops,
|
||||||
ipcompstat.ipcomps_hdrops);
|
ipcompstat.ipcomps_hdrops);
|
||||||
@ -502,6 +515,227 @@ ipsec6_common_input(struct mbuf **mp, int *offp, int proto)
|
|||||||
return IPPROTO_DONE;
|
return IPPROTO_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPsec input callback, called by the transform callback. Takes care of
|
||||||
|
* filtering and other sanity checks on the processed packet.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff,
|
||||||
|
struct m_tag *mt)
|
||||||
|
{
|
||||||
|
int prot, af, sproto;
|
||||||
|
struct ip6_hdr *ip6;
|
||||||
|
struct m_tag *mtag;
|
||||||
|
struct tdb_ident *tdbi;
|
||||||
|
struct secasindex *saidx;
|
||||||
|
int nxt;
|
||||||
|
u_int8_t nxt8;
|
||||||
|
int error, nest;
|
||||||
|
|
||||||
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
|
IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
|
||||||
|
saidx = &sav->sah->saidx;
|
||||||
|
af = saidx->dst.sa.sa_family;
|
||||||
|
IPSEC_ASSERT(af == AF_INET6, ("unexpected af %u", af));
|
||||||
|
sproto = saidx->proto;
|
||||||
|
IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
|
||||||
|
sproto == IPPROTO_IPCOMP,
|
||||||
|
("unexpected security protocol %u", sproto));
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (m == NULL) {
|
||||||
|
DPRINTF(("%s: null mbuf", __func__));
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
|
||||||
|
ipcompstat.ipcomps_badkcr);
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix IPv6 header */
|
||||||
|
if (m->m_len < sizeof(struct ip6_hdr) &&
|
||||||
|
(m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
|
||||||
|
|
||||||
|
DPRINTF(("%s: processing failed for SA %s/%08lx\n",
|
||||||
|
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||||
|
(u_long) ntohl(sav->spi)));
|
||||||
|
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
||||||
|
ipcompstat.ipcomps_hdrops);
|
||||||
|
error = EACCES;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip6 = mtod(m, struct ip6_hdr *);
|
||||||
|
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
|
||||||
|
|
||||||
|
/* Save protocol */
|
||||||
|
m_copydata(m, protoff, 1, (unsigned char *) &prot);
|
||||||
|
|
||||||
|
#ifdef INET
|
||||||
|
/* IP-in-IP encapsulation */
|
||||||
|
if (prot == IPPROTO_IPIP) {
|
||||||
|
struct ip ipn;
|
||||||
|
|
||||||
|
if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
||||||
|
ahstat.ahs_hdrops,
|
||||||
|
ipcompstat.ipcomps_hdrops);
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
/* ipn will now contain the inner IPv4 header */
|
||||||
|
m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
|
||||||
|
|
||||||
|
#ifdef notyet
|
||||||
|
/*
|
||||||
|
* Check that the inner source address is the same as
|
||||||
|
* the proxy address, if available.
|
||||||
|
*/
|
||||||
|
if ((saidx->proxy.sa.sa_family == AF_INET &&
|
||||||
|
saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
|
||||||
|
ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
|
||||||
|
(saidx->proxy.sa.sa_family != AF_INET &&
|
||||||
|
saidx->proxy.sa.sa_family != 0)) {
|
||||||
|
|
||||||
|
DPRINTF(("%s: inner source address %s doesn't "
|
||||||
|
"correspond to expected proxy source %s, "
|
||||||
|
"SA %s/%08lx\n", __func__,
|
||||||
|
inet_ntoa4(ipn.ip_src),
|
||||||
|
ipsec_address(&saidx->proxy),
|
||||||
|
ipsec_address(&saidx->dst),
|
||||||
|
(u_long) ntohl(sav->spi)));
|
||||||
|
|
||||||
|
IPSEC_ISTATsproto, (espstat.esps_pdrops,
|
||||||
|
ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
|
||||||
|
error = EACCES;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#endif /*XXX*/
|
||||||
|
}
|
||||||
|
#endif /* INET */
|
||||||
|
|
||||||
|
/* IPv6-in-IP encapsulation */
|
||||||
|
if (prot == IPPROTO_IPV6) {
|
||||||
|
struct ip6_hdr ip6n;
|
||||||
|
|
||||||
|
if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
||||||
|
ahstat.ahs_hdrops,
|
||||||
|
ipcompstat.ipcomps_hdrops);
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
/* ip6n will now contain the inner IPv6 header. */
|
||||||
|
m_copydata(m, skip, sizeof(struct ip6_hdr),
|
||||||
|
(caddr_t) &ip6n);
|
||||||
|
|
||||||
|
#ifdef notyet
|
||||||
|
/*
|
||||||
|
* Check that the inner source address is the same as
|
||||||
|
* the proxy address, if available.
|
||||||
|
*/
|
||||||
|
if ((saidx->proxy.sa.sa_family == AF_INET6 &&
|
||||||
|
!IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
|
||||||
|
!IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
|
||||||
|
&saidx->proxy.sin6.sin6_addr)) ||
|
||||||
|
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
||||||
|
saidx->proxy.sa.sa_family != 0)) {
|
||||||
|
|
||||||
|
DPRINTF(("%s: inner source address %s doesn't "
|
||||||
|
"correspond to expected proxy source %s, "
|
||||||
|
"SA %s/%08lx\n", __func__,
|
||||||
|
ip6_sprintf(&ip6n.ip6_src),
|
||||||
|
ipsec_address(&saidx->proxy),
|
||||||
|
ipsec_address(&saidx->dst),
|
||||||
|
(u_long) ntohl(sav->spi)));
|
||||||
|
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_pdrops,
|
||||||
|
ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
|
||||||
|
error = EACCES;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#endif /*XXX*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record what we've done to the packet (under what SA it was
|
||||||
|
* processed). If we've been passed an mtag, it means the packet
|
||||||
|
* was already processed by an ethernet/crypto combo card and
|
||||||
|
* thus has a tag attached with all the right information, but
|
||||||
|
* with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
|
||||||
|
* PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
|
||||||
|
*/
|
||||||
|
if (mt == NULL && sproto != IPPROTO_IPCOMP) {
|
||||||
|
mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
|
||||||
|
sizeof(struct tdb_ident), M_NOWAIT);
|
||||||
|
if (mtag == NULL) {
|
||||||
|
DPRINTF(("%s: failed to get tag\n", __func__));
|
||||||
|
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
||||||
|
ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
|
||||||
|
error = ENOMEM;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
tdbi = (struct tdb_ident *)(mtag + 1);
|
||||||
|
bcopy(&saidx->dst, &tdbi->dst, sizeof(union sockaddr_union));
|
||||||
|
tdbi->proto = sproto;
|
||||||
|
tdbi->spi = sav->spi;
|
||||||
|
|
||||||
|
m_tag_prepend(m, mtag);
|
||||||
|
} else {
|
||||||
|
if (mt != NULL)
|
||||||
|
mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
|
||||||
|
/* XXX do we need to mark m_flags??? */
|
||||||
|
}
|
||||||
|
|
||||||
|
key_sa_recordxfer(sav, m);
|
||||||
|
|
||||||
|
/* Retrieve new protocol */
|
||||||
|
m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See the end of ip6_input for this logic.
|
||||||
|
* IPPROTO_IPV[46] case will be processed just like other ones
|
||||||
|
*/
|
||||||
|
nest = 0;
|
||||||
|
nxt = nxt8;
|
||||||
|
while (nxt != IPPROTO_DONE) {
|
||||||
|
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
|
||||||
|
ip6stat.ip6s_toomanyhdr++;
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Protection against faulty packet - there should be
|
||||||
|
* more sanity checks in header chain processing.
|
||||||
|
*/
|
||||||
|
if (m->m_pkthdr.len < skip) {
|
||||||
|
ip6stat.ip6s_tooshort++;
|
||||||
|
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Enforce IPsec policy checking if we are seeing last header.
|
||||||
|
* note that we do not visit this with protocols with pcb layer
|
||||||
|
* code - like udp/tcp/raw ip.
|
||||||
|
*/
|
||||||
|
if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
|
||||||
|
ipsec6_in_reject(m, NULL)) {
|
||||||
|
error = EINVAL;
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
bad:
|
||||||
|
if (m)
|
||||||
|
m_freem(m);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
||||||
{
|
{
|
||||||
@ -577,227 +811,4 @@ esp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
|
|||||||
/* we normally notify any pcb here */
|
/* we normally notify any pcb here */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* IPsec input callback, called by the transform callback. Takes care of
|
|
||||||
* filtering and other sanity checks on the processed packet.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int protoff,
|
|
||||||
struct m_tag *mt)
|
|
||||||
{
|
|
||||||
int prot, af, sproto;
|
|
||||||
struct ip6_hdr *ip6;
|
|
||||||
struct m_tag *mtag;
|
|
||||||
struct tdb_ident *tdbi;
|
|
||||||
struct secasindex *saidx;
|
|
||||||
int nxt;
|
|
||||||
u_int8_t nxt8;
|
|
||||||
int error, nest;
|
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec6_common_input_cb: null mbuf"));
|
|
||||||
KASSERT(sav != NULL, ("ipsec6_common_input_cb: null SA"));
|
|
||||||
KASSERT(sav->sah != NULL, ("ipsec6_common_input_cb: null SAH"));
|
|
||||||
saidx = &sav->sah->saidx;
|
|
||||||
af = saidx->dst.sa.sa_family;
|
|
||||||
KASSERT(af == AF_INET6,
|
|
||||||
("ipsec6_common_input_cb: unexpected af %u", af));
|
|
||||||
sproto = saidx->proto;
|
|
||||||
KASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH ||
|
|
||||||
sproto == IPPROTO_IPCOMP,
|
|
||||||
("ipsec6_common_input_cb: unexpected security protocol %u",
|
|
||||||
sproto));
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
if (m == NULL) {
|
|
||||||
DPRINTF(("ipsec4_common_input_cb: null mbuf"));
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_badkcr, ahstat.ahs_badkcr,
|
|
||||||
ipcompstat.ipcomps_badkcr);
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix IPv6 header */
|
|
||||||
if (m->m_len < sizeof(struct ip6_hdr) &&
|
|
||||||
(m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
|
|
||||||
|
|
||||||
DPRINTF(("ipsec_common_input_cb: processing failed "
|
|
||||||
"for SA %s/%08lx\n", ipsec_address(&sav->sah->saidx.dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
|
||||||
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops, ahstat.ahs_hdrops,
|
|
||||||
ipcompstat.ipcomps_hdrops);
|
|
||||||
error = EACCES;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
ip6 = mtod(m, struct ip6_hdr *);
|
|
||||||
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
|
|
||||||
|
|
||||||
/* Save protocol */
|
|
||||||
m_copydata(m, protoff, 1, (unsigned char *) &prot);
|
|
||||||
|
|
||||||
#ifdef INET
|
|
||||||
/* IP-in-IP encapsulation */
|
|
||||||
if (prot == IPPROTO_IPIP) {
|
|
||||||
struct ip ipn;
|
|
||||||
|
|
||||||
if (m->m_pkthdr.len - skip < sizeof(struct ip)) {
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
|
||||||
ahstat.ahs_hdrops,
|
|
||||||
ipcompstat.ipcomps_hdrops);
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
/* ipn will now contain the inner IPv4 header */
|
|
||||||
m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn);
|
|
||||||
|
|
||||||
#ifdef notyet
|
|
||||||
/*
|
|
||||||
* Check that the inner source address is the same as
|
|
||||||
* the proxy address, if available.
|
|
||||||
*/
|
|
||||||
if ((saidx->proxy.sa.sa_family == AF_INET &&
|
|
||||||
saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY &&
|
|
||||||
ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) ||
|
|
||||||
(saidx->proxy.sa.sa_family != AF_INET &&
|
|
||||||
saidx->proxy.sa.sa_family != 0)) {
|
|
||||||
|
|
||||||
DPRINTF(("ipsec_common_input_cb: inner "
|
|
||||||
"source address %s doesn't correspond to "
|
|
||||||
"expected proxy source %s, SA %s/%08lx\n",
|
|
||||||
inet_ntoa4(ipn.ip_src),
|
|
||||||
ipsec_address(&saidx->proxy),
|
|
||||||
ipsec_address(&saidx->dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
|
||||||
|
|
||||||
IPSEC_ISTATsproto, (espstat.esps_pdrops,
|
|
||||||
ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
|
|
||||||
error = EACCES;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#endif /*XXX*/
|
|
||||||
}
|
|
||||||
#endif /* INET */
|
|
||||||
|
|
||||||
/* IPv6-in-IP encapsulation */
|
|
||||||
if (prot == IPPROTO_IPV6) {
|
|
||||||
struct ip6_hdr ip6n;
|
|
||||||
|
|
||||||
if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
|
||||||
ahstat.ahs_hdrops,
|
|
||||||
ipcompstat.ipcomps_hdrops);
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
/* ip6n will now contain the inner IPv6 header. */
|
|
||||||
m_copydata(m, skip, sizeof(struct ip6_hdr),
|
|
||||||
(caddr_t) &ip6n);
|
|
||||||
|
|
||||||
#ifdef notyet
|
|
||||||
/*
|
|
||||||
* Check that the inner source address is the same as
|
|
||||||
* the proxy address, if available.
|
|
||||||
*/
|
|
||||||
if ((saidx->proxy.sa.sa_family == AF_INET6 &&
|
|
||||||
!IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) &&
|
|
||||||
!IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src,
|
|
||||||
&saidx->proxy.sin6.sin6_addr)) ||
|
|
||||||
(saidx->proxy.sa.sa_family != AF_INET6 &&
|
|
||||||
saidx->proxy.sa.sa_family != 0)) {
|
|
||||||
|
|
||||||
DPRINTF(("ipsec_common_input_cb: inner "
|
|
||||||
"source address %s doesn't correspond to "
|
|
||||||
"expected proxy source %s, SA %s/%08lx\n",
|
|
||||||
ip6_sprintf(&ip6n.ip6_src),
|
|
||||||
ipsec_address(&saidx->proxy),
|
|
||||||
ipsec_address(&saidx->dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
|
||||||
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_pdrops,
|
|
||||||
ahstat.ahs_pdrops, ipcompstat.ipcomps_pdrops);
|
|
||||||
error = EACCES;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
#endif /*XXX*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Record what we've done to the packet (under what SA it was
|
|
||||||
* processed). If we've been passed an mtag, it means the packet
|
|
||||||
* was already processed by an ethernet/crypto combo card and
|
|
||||||
* thus has a tag attached with all the right information, but
|
|
||||||
* with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
|
|
||||||
* PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
|
|
||||||
*/
|
|
||||||
if (mt == NULL && sproto != IPPROTO_IPCOMP) {
|
|
||||||
mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
|
|
||||||
sizeof(struct tdb_ident), M_NOWAIT);
|
|
||||||
if (mtag == NULL) {
|
|
||||||
DPRINTF(("ipsec_common_input_cb: failed to "
|
|
||||||
"get tag\n"));
|
|
||||||
IPSEC_ISTAT(sproto, espstat.esps_hdrops,
|
|
||||||
ahstat.ahs_hdrops, ipcompstat.ipcomps_hdrops);
|
|
||||||
error = ENOMEM;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
tdbi = (struct tdb_ident *)(mtag + 1);
|
|
||||||
bcopy(&saidx->dst, &tdbi->dst, sizeof(union sockaddr_union));
|
|
||||||
tdbi->proto = sproto;
|
|
||||||
tdbi->spi = sav->spi;
|
|
||||||
|
|
||||||
m_tag_prepend(m, mtag);
|
|
||||||
} else {
|
|
||||||
mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE;
|
|
||||||
/* XXX do we need to mark m_flags??? */
|
|
||||||
}
|
|
||||||
|
|
||||||
key_sa_recordxfer(sav, m);
|
|
||||||
|
|
||||||
/* Retrieve new protocol */
|
|
||||||
m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See the end of ip6_input for this logic.
|
|
||||||
* IPPROTO_IPV[46] case will be processed just like other ones
|
|
||||||
*/
|
|
||||||
nest = 0;
|
|
||||||
nxt = nxt8;
|
|
||||||
while (nxt != IPPROTO_DONE) {
|
|
||||||
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
|
|
||||||
ip6stat.ip6s_toomanyhdr++;
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Protection against faulty packet - there should be
|
|
||||||
* more sanity checks in header chain processing.
|
|
||||||
*/
|
|
||||||
if (m->m_pkthdr.len < skip) {
|
|
||||||
ip6stat.ip6s_tooshort++;
|
|
||||||
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Enforce IPsec policy checking if we are seeing last header.
|
|
||||||
* note that we do not visit this with protocols with pcb layer
|
|
||||||
* code - like udp/tcp/raw ip.
|
|
||||||
*/
|
|
||||||
if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
|
|
||||||
ipsec6_in_reject(m, NULL)) {
|
|
||||||
error = EINVAL;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &skip, nxt);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
bad:
|
|
||||||
if (m)
|
|
||||||
m_freem(m);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
|
@ -60,7 +60,7 @@ m_clone(struct mbuf *m0)
|
|||||||
struct mbuf *n, *mfirst, *mlast;
|
struct mbuf *n, *mfirst, *mlast;
|
||||||
int len, off;
|
int len, off;
|
||||||
|
|
||||||
KASSERT(m0 != NULL, ("m_clone: null mbuf"));
|
IPSEC_ASSERT(m0 != NULL, ("null mbuf"));
|
||||||
|
|
||||||
mprev = NULL;
|
mprev = NULL;
|
||||||
for (m = m0; m != NULL; m = mprev->m_next) {
|
for (m = m0; m != NULL; m = mprev->m_next) {
|
||||||
@ -105,8 +105,7 @@ m_clone(struct mbuf *m0)
|
|||||||
* it anyway, we try to reduce the number of mbufs and
|
* it anyway, we try to reduce the number of mbufs and
|
||||||
* clusters so that future work is easier).
|
* clusters so that future work is easier).
|
||||||
*/
|
*/
|
||||||
KASSERT(m->m_flags & M_EXT,
|
IPSEC_ASSERT(m->m_flags & M_EXT, ("m_flags 0x%x", m->m_flags));
|
||||||
("m_clone: m_flags 0x%x", m->m_flags));
|
|
||||||
/* NB: we only coalesce into a cluster or larger */
|
/* NB: we only coalesce into a cluster or larger */
|
||||||
if (mprev != NULL && (mprev->m_flags & M_EXT) &&
|
if (mprev != NULL && (mprev->m_flags & M_EXT) &&
|
||||||
m->m_len <= M_TRAILINGSPACE(mprev)) {
|
m->m_len <= M_TRAILINGSPACE(mprev)) {
|
||||||
@ -208,8 +207,8 @@ m_makespace(struct mbuf *m0, int skip, int hlen, int *off)
|
|||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
unsigned remain;
|
unsigned remain;
|
||||||
|
|
||||||
KASSERT(m0 != NULL, ("m_dmakespace: null mbuf"));
|
IPSEC_ASSERT(m0 != NULL, ("null mbuf"));
|
||||||
KASSERT(hlen < MHLEN, ("m_makespace: hlen too big: %u", hlen));
|
IPSEC_ASSERT(hlen < MHLEN, ("hlen too big: %u", hlen));
|
||||||
|
|
||||||
for (m = m0; m && skip > m->m_len; m = m->m_next)
|
for (m = m0; m && skip > m->m_len; m = m->m_next)
|
||||||
skip -= m->m_len;
|
skip -= m->m_len;
|
||||||
@ -228,8 +227,7 @@ m_makespace(struct mbuf *m0, int skip, int hlen, int *off)
|
|||||||
struct mbuf *n;
|
struct mbuf *n;
|
||||||
|
|
||||||
/* XXX code doesn't handle clusters XXX */
|
/* XXX code doesn't handle clusters XXX */
|
||||||
KASSERT(remain < MLEN,
|
IPSEC_ASSERT(remain < MLEN, ("remainder too big: %u", remain));
|
||||||
("m_makespace: remainder too big: %u", remain));
|
|
||||||
/*
|
/*
|
||||||
* Not enough space in m, split the contents
|
* Not enough space in m, split the contents
|
||||||
* of m, inserting new mbufs as required.
|
* of m, inserting new mbufs as required.
|
||||||
@ -313,7 +311,7 @@ m_pad(struct mbuf *m, int n)
|
|||||||
caddr_t retval;
|
caddr_t retval;
|
||||||
|
|
||||||
if (n <= 0) { /* No stupid arguments. */
|
if (n <= 0) { /* No stupid arguments. */
|
||||||
DPRINTF(("m_pad: pad length invalid (%d)\n", n));
|
DPRINTF(("%s: pad length invalid (%d)\n", __func__, n));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -323,14 +321,14 @@ m_pad(struct mbuf *m, int n)
|
|||||||
m0 = m;
|
m0 = m;
|
||||||
|
|
||||||
while (m0->m_len < len) {
|
while (m0->m_len < len) {
|
||||||
KASSERT(m0->m_next != NULL, ("m_pad: m0 null, len %u m_len %u", len, m0->m_len));/*XXX*/
|
|
||||||
len -= m0->m_len;
|
len -= m0->m_len;
|
||||||
m0 = m0->m_next;
|
m0 = m0->m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m0->m_len != len) {
|
if (m0->m_len != len) {
|
||||||
DPRINTF(("m_pad: length mismatch (should be %d instead of %d)\n",
|
DPRINTF(("%s: length mismatch (should be %d instead of %d)\n",
|
||||||
m->m_pkthdr.len, m->m_pkthdr.len + m0->m_len - len));
|
__func__, m->m_pkthdr.len,
|
||||||
|
m->m_pkthdr.len + m0->m_len - len));
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -339,10 +337,10 @@ KASSERT(m0->m_next != NULL, ("m_pad: m0 null, len %u m_len %u", len, m0->m_len))
|
|||||||
/* Check for zero-length trailing mbufs, and find the last one. */
|
/* Check for zero-length trailing mbufs, and find the last one. */
|
||||||
for (m1 = m0; m1->m_next; m1 = m1->m_next) {
|
for (m1 = m0; m1->m_next; m1 = m1->m_next) {
|
||||||
if (m1->m_next->m_len != 0) {
|
if (m1->m_next->m_len != 0) {
|
||||||
DPRINTF(("m_pad: length mismatch (should be %d "
|
DPRINTF(("%s: length mismatch (should be %d instead "
|
||||||
"instead of %d)\n",
|
"of %d)\n", __func__,
|
||||||
m->m_pkthdr.len,
|
m->m_pkthdr.len,
|
||||||
m->m_pkthdr.len + m1->m_next->m_len));
|
m->m_pkthdr.len + m1->m_next->m_len));
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -356,7 +354,7 @@ KASSERT(m0->m_next != NULL, ("m_pad: m0 null, len %u m_len %u", len, m0->m_len))
|
|||||||
MGET(m1, M_DONTWAIT, MT_DATA);
|
MGET(m1, M_DONTWAIT, MT_DATA);
|
||||||
if (m1 == 0) {
|
if (m1 == 0) {
|
||||||
m_freem(m0);
|
m_freem(m0);
|
||||||
DPRINTF(("m_pad: unable to get extra mbuf\n"));
|
DPRINTF(("%s: unable to get extra mbuf\n", __func__));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,15 +89,13 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
|||||||
struct secasindex *saidx;
|
struct secasindex *saidx;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipsec_process_done");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec_process_done: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(isr != NULL, ("ipsec_process_done: null ISR"));
|
IPSEC_ASSERT(isr != NULL, ("null ISR"));
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
KASSERT(sav != NULL, ("ipsec_process_done: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
KASSERT(sav->sah != NULL, ("ipsec_process_done: null SAH"));
|
IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
|
||||||
|
|
||||||
saidx = &sav->sah->saidx;
|
saidx = &sav->sah->saidx;
|
||||||
switch (saidx->dst.sa.sa_family) {
|
switch (saidx->dst.sa.sa_family) {
|
||||||
@ -124,7 +122,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
|||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
DPRINTF(("ipsec_process_done: unknown protocol family %u\n",
|
DPRINTF(("%s: unknown protocol family %u\n", __func__,
|
||||||
saidx->dst.sa.sa_family));
|
saidx->dst.sa.sa_family));
|
||||||
error = ENXIO;
|
error = ENXIO;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -137,7 +135,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr)
|
|||||||
mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE,
|
mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE,
|
||||||
sizeof(struct tdb_ident), M_NOWAIT);
|
sizeof(struct tdb_ident), M_NOWAIT);
|
||||||
if (mtag == NULL) {
|
if (mtag == NULL) {
|
||||||
DPRINTF(("ipsec_process_done: could not get packet tag\n"));
|
DPRINTF(("%s: could not get packet tag\n", __func__));
|
||||||
error = ENOMEM;
|
error = ENOMEM;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -205,11 +203,11 @@ ipsec_nextisr(
|
|||||||
isr->saidx.proto == IPPROTO_AH ? (y)++ : (z)++)
|
isr->saidx.proto == IPPROTO_AH ? (y)++ : (z)++)
|
||||||
struct secasvar *sav;
|
struct secasvar *sav;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipsec_nextisr");
|
IPSECREQUEST_LOCK_ASSERT(isr);
|
||||||
#endif
|
|
||||||
KASSERT(af == AF_INET || af == AF_INET6,
|
IPSEC_ASSERT(af == AF_INET || af == AF_INET6,
|
||||||
("ipsec_nextisr: invalid address family %u", af));
|
("invalid address family %u", af));
|
||||||
again:
|
again:
|
||||||
/*
|
/*
|
||||||
* Craft SA index to search for proper SA. Note that
|
* Craft SA index to search for proper SA. Note that
|
||||||
@ -287,15 +285,17 @@ again:
|
|||||||
}
|
}
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
if (sav == NULL) { /* XXX valid return */
|
if (sav == NULL) { /* XXX valid return */
|
||||||
KASSERT(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE,
|
IPSEC_ASSERT(ipsec_get_reqlevel(isr) == IPSEC_LEVEL_USE,
|
||||||
("ipsec_nextisr: no SA found, but required; level %u",
|
("no SA found, but required; level %u",
|
||||||
ipsec_get_reqlevel(isr)));
|
ipsec_get_reqlevel(isr)));
|
||||||
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
isr = isr->next;
|
isr = isr->next;
|
||||||
if (isr == NULL) {
|
if (isr == NULL) {
|
||||||
/*XXXstatistic??*/
|
/*XXXstatistic??*/
|
||||||
*error = EINVAL; /*XXX*/
|
*error = EINVAL; /*XXX*/
|
||||||
return isr;
|
return isr;
|
||||||
}
|
}
|
||||||
|
IPSECREQUEST_LOCK(isr);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,8 +305,8 @@ again:
|
|||||||
if ((isr->saidx.proto == IPPROTO_ESP && !esp_enable) ||
|
if ((isr->saidx.proto == IPPROTO_ESP && !esp_enable) ||
|
||||||
(isr->saidx.proto == IPPROTO_AH && !ah_enable) ||
|
(isr->saidx.proto == IPPROTO_AH && !ah_enable) ||
|
||||||
(isr->saidx.proto == IPPROTO_IPCOMP && !ipcomp_enable)) {
|
(isr->saidx.proto == IPPROTO_IPCOMP && !ipcomp_enable)) {
|
||||||
DPRINTF(("ipsec_nextisr: IPsec outbound packet dropped due"
|
DPRINTF(("%s: IPsec outbound packet dropped due"
|
||||||
" to policy (check your sysctls)\n"));
|
" to policy (check your sysctls)\n", __func__));
|
||||||
IPSEC_OSTAT(espstat.esps_pdrops, ahstat.ahs_pdrops,
|
IPSEC_OSTAT(espstat.esps_pdrops, ahstat.ahs_pdrops,
|
||||||
ipcompstat.ipcomps_pdrops);
|
ipcompstat.ipcomps_pdrops);
|
||||||
*error = EHOSTUNREACH;
|
*error = EHOSTUNREACH;
|
||||||
@ -318,7 +318,7 @@ again:
|
|||||||
* before they invoke the xform output method.
|
* before they invoke the xform output method.
|
||||||
*/
|
*/
|
||||||
if (sav->tdb_xform == NULL) {
|
if (sav->tdb_xform == NULL) {
|
||||||
DPRINTF(("ipsec_nextisr: no transform for SA\n"));
|
DPRINTF(("%s: no transform for SA\n", __func__));
|
||||||
IPSEC_OSTAT(espstat.esps_noxform, ahstat.ahs_noxform,
|
IPSEC_OSTAT(espstat.esps_noxform, ahstat.ahs_noxform,
|
||||||
ipcompstat.ipcomps_noxform);
|
ipcompstat.ipcomps_noxform);
|
||||||
*error = EHOSTUNREACH;
|
*error = EHOSTUNREACH;
|
||||||
@ -326,7 +326,8 @@ again:
|
|||||||
}
|
}
|
||||||
return isr;
|
return isr;
|
||||||
bad:
|
bad:
|
||||||
KASSERT(*error != 0, ("ipsec_nextisr: error return w/ no error code"));
|
IPSEC_ASSERT(*error != 0, ("error return w/ no error code"));
|
||||||
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
return NULL;
|
return NULL;
|
||||||
#undef IPSEC_OSTAT
|
#undef IPSEC_OSTAT
|
||||||
}
|
}
|
||||||
@ -347,10 +348,10 @@ ipsec4_process_packet(
|
|||||||
struct ip *ip;
|
struct ip *ip;
|
||||||
int error, i, off;
|
int error, i, off;
|
||||||
|
|
||||||
KASSERT(m != NULL, ("ipsec4_process_packet: null mbuf"));
|
IPSEC_ASSERT(m != NULL, ("null mbuf"));
|
||||||
KASSERT(isr != NULL, ("ipsec4_process_packet: null isr"));
|
IPSEC_ASSERT(isr != NULL, ("null isr"));
|
||||||
|
|
||||||
mtx_lock(&isr->lock); /* insure SA contents don't change */
|
IPSECREQUEST_LOCK(isr); /* insure SA contents don't change */
|
||||||
|
|
||||||
isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error);
|
isr = ipsec_nextisr(m, isr, AF_INET, &saidx, &error);
|
||||||
if (isr == NULL)
|
if (isr == NULL)
|
||||||
@ -420,8 +421,8 @@ ipsec4_process_packet(
|
|||||||
error = ipip_output(m, isr, &mp, 0, 0);
|
error = ipip_output(m, isr, &mp, 0, 0);
|
||||||
if (mp == NULL && !error) {
|
if (mp == NULL && !error) {
|
||||||
/* Should never happen. */
|
/* Should never happen. */
|
||||||
DPRINTF(("ipsec4_process_packet: ipip_output "
|
DPRINTF(("%s: ipip_output returns no mbuf and "
|
||||||
"returns no mbuf and no error!"));
|
"no error!", __func__));
|
||||||
error = EFAULT;
|
error = EFAULT;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -469,10 +470,11 @@ ipsec4_process_packet(
|
|||||||
} else {
|
} else {
|
||||||
error = ipsec_process_done(m, isr);
|
error = ipsec_process_done(m, isr);
|
||||||
}
|
}
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
return error;
|
return error;
|
||||||
bad:
|
bad:
|
||||||
mtx_unlock(&isr->lock);
|
if (isr)
|
||||||
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
if (m)
|
if (m)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return error;
|
return error;
|
||||||
@ -490,8 +492,8 @@ ipsec6_splithdr(struct mbuf *m)
|
|||||||
struct ip6_hdr *ip6;
|
struct ip6_hdr *ip6;
|
||||||
int hlen;
|
int hlen;
|
||||||
|
|
||||||
KASSERT(m->m_len >= sizeof (struct ip6_hdr),
|
IPSEC_ASSERT(m->m_len >= sizeof (struct ip6_hdr),
|
||||||
("ipsec6_splithdr: first mbuf too short, len %u", m->m_len));
|
("first mbuf too short, len %u", m->m_len));
|
||||||
ip6 = mtod(m, struct ip6_hdr *);
|
ip6 = mtod(m, struct ip6_hdr *);
|
||||||
hlen = sizeof(struct ip6_hdr);
|
hlen = sizeof(struct ip6_hdr);
|
||||||
if (m->m_len > hlen) {
|
if (m->m_len > hlen) {
|
||||||
@ -533,15 +535,15 @@ ipsec6_output_trans(
|
|||||||
int error = 0;
|
int error = 0;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
KASSERT(state != NULL, ("ipsec6_output: null state"));
|
IPSEC_ASSERT(state != NULL, ("null state"));
|
||||||
KASSERT(state->m != NULL, ("ipsec6_output: null m"));
|
IPSEC_ASSERT(state->m != NULL, ("null m"));
|
||||||
KASSERT(nexthdrp != NULL, ("ipsec6_output: null nexthdrp"));
|
IPSEC_ASSERT(nexthdrp != NULL, ("null nexthdrp"));
|
||||||
KASSERT(mprev != NULL, ("ipsec6_output: null mprev"));
|
IPSEC_ASSERT(mprev != NULL, ("null mprev"));
|
||||||
KASSERT(sp != NULL, ("ipsec6_output: null sp"));
|
IPSEC_ASSERT(sp != NULL, ("null sp"));
|
||||||
KASSERT(tun != NULL, ("ipsec6_output: null tun"));
|
IPSEC_ASSERT(tun != NULL, ("null tun"));
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec6_output_trans: applyed SP\n");
|
printf("%s: applyed SP\n", __func__);
|
||||||
kdebug_secpolicy(sp));
|
kdebug_secpolicy(sp));
|
||||||
|
|
||||||
isr = sp->req;
|
isr = sp->req;
|
||||||
@ -596,8 +598,8 @@ ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
|
|||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
KASSERT(m->m_len != sizeof (struct ip6_hdr),
|
IPSEC_ASSERT(m->m_len != sizeof (struct ip6_hdr),
|
||||||
("ipsec6_encapsulate: mbuf wrong size; len %u", m->m_len));
|
("mbuf wrong size; len %u", m->m_len));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -662,12 +664,12 @@ ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int
|
|||||||
struct sockaddr_in6* dst6;
|
struct sockaddr_in6* dst6;
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
|
|
||||||
KASSERT(state != NULL, ("ipsec6_output: null state"));
|
IPSEC_ASSERT(state != NULL, ("null state"));
|
||||||
KASSERT(state->m != NULL, ("ipsec6_output: null m"));
|
IPSEC_ASSERT(state->m != NULL, ("null m"));
|
||||||
KASSERT(sp != NULL, ("ipsec6_output: null sp"));
|
IPSEC_ASSERT(sp != NULL, ("null sp"));
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
|
||||||
printf("ipsec6_output_tunnel: applyed SP\n");
|
printf("%s: applyed SP\n", __func__);
|
||||||
kdebug_secpolicy(sp));
|
kdebug_secpolicy(sp));
|
||||||
|
|
||||||
m = state->m;
|
m = state->m;
|
||||||
@ -693,8 +695,8 @@ ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp, int
|
|||||||
*/
|
*/
|
||||||
/* XXX should be processed with other familiy */
|
/* XXX should be processed with other familiy */
|
||||||
if (isr->sav->sah->saidx.src.sa.sa_family != AF_INET6) {
|
if (isr->sav->sah->saidx.src.sa.sa_family != AF_INET6) {
|
||||||
ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
|
ipseclog((LOG_ERR, "%s: family mismatched between "
|
||||||
"family mismatched between inner and outer, spi=%u\n",
|
"inner and outer, spi=%u\n", __func__,
|
||||||
ntohl(isr->sav->spi)));
|
ntohl(isr->sav->spi)));
|
||||||
newipsecstat.ips_out_inval++;
|
newipsecstat.ips_out_inval++;
|
||||||
error = EAFNOSUPPORT;
|
error = EAFNOSUPPORT;
|
||||||
|
1138
sys/netipsec/key.c
1138
sys/netipsec/key.c
File diff suppressed because it is too large
Load Diff
@ -88,7 +88,7 @@ kdebug_sadb(base)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (base == NULL)
|
if (base == NULL)
|
||||||
panic("kdebug_sadb: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_msg{ version=%u type=%u errno=%u satype=%u\n",
|
printf("sadb_msg{ version=%u type=%u errno=%u satype=%u\n",
|
||||||
base->sadb_msg_version, base->sadb_msg_type,
|
base->sadb_msg_version, base->sadb_msg_type,
|
||||||
@ -105,11 +105,12 @@ kdebug_sadb(base)
|
|||||||
ext->sadb_ext_len, ext->sadb_ext_type);
|
ext->sadb_ext_len, ext->sadb_ext_type);
|
||||||
|
|
||||||
if (ext->sadb_ext_len == 0) {
|
if (ext->sadb_ext_len == 0) {
|
||||||
printf("kdebug_sadb: invalid ext_len=0 was passed.\n");
|
printf("%s: invalid ext_len=0 was passed.\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ext->sadb_ext_len > tlen) {
|
if (ext->sadb_ext_len > tlen) {
|
||||||
printf("kdebug_sadb: ext_len exceeds end of buffer.\n");
|
printf("%s: ext_len too big (%u > %u).\n",
|
||||||
|
__func__, ext->sadb_ext_len, tlen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ kdebug_sadb(base)
|
|||||||
kdebug_sadb_x_sa2(ext);
|
kdebug_sadb_x_sa2(ext);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("kdebug_sadb: invalid ext_type %u was passed.\n",
|
printf("%s: invalid ext_type %u\n", __func__,
|
||||||
ext->sadb_ext_type);
|
ext->sadb_ext_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -177,7 +178,7 @@ kdebug_sadb_prop(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_prop: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop))
|
len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop))
|
||||||
/ sizeof(*comb);
|
/ sizeof(*comb);
|
||||||
@ -226,7 +227,7 @@ kdebug_sadb_identity(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_identity: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id);
|
len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id);
|
||||||
printf("sadb_ident_%s{",
|
printf("sadb_ident_%s{",
|
||||||
@ -270,7 +271,7 @@ kdebug_sadb_supported(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_supported: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup))
|
len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup))
|
||||||
/ sizeof(*alg);
|
/ sizeof(*alg);
|
||||||
@ -295,7 +296,7 @@ kdebug_sadb_lifetime(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
printf("kdebug_sadb_lifetime: NULL pointer was passed.\n");
|
printf("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_lifetime{ alloc=%u, bytes=%u\n",
|
printf("sadb_lifetime{ alloc=%u, bytes=%u\n",
|
||||||
lft->sadb_lifetime_allocations,
|
lft->sadb_lifetime_allocations,
|
||||||
@ -315,7 +316,7 @@ kdebug_sadb_sa(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_sa: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_sa{ spi=%u replay=%u state=%u\n",
|
printf("sadb_sa{ spi=%u replay=%u state=%u\n",
|
||||||
(u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay,
|
(u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay,
|
||||||
@ -334,7 +335,7 @@ kdebug_sadb_address(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_address: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_address{ proto=%u prefixlen=%u reserved=0x%02x%02x }\n",
|
printf("sadb_address{ proto=%u prefixlen=%u reserved=0x%02x%02x }\n",
|
||||||
addr->sadb_address_proto, addr->sadb_address_prefixlen,
|
addr->sadb_address_proto, addr->sadb_address_prefixlen,
|
||||||
@ -354,7 +355,7 @@ kdebug_sadb_key(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_key: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_key{ bits=%u reserved=%u\n",
|
printf("sadb_key{ bits=%u reserved=%u\n",
|
||||||
key->sadb_key_bits, key->sadb_key_reserved);
|
key->sadb_key_bits, key->sadb_key_reserved);
|
||||||
@ -363,7 +364,8 @@ kdebug_sadb_key(ext)
|
|||||||
/* sanity check 2 */
|
/* sanity check 2 */
|
||||||
if ((key->sadb_key_bits >> 3) >
|
if ((key->sadb_key_bits >> 3) >
|
||||||
(PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) {
|
(PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) {
|
||||||
printf("kdebug_sadb_key: key length mismatch, bit:%d len:%ld.\n",
|
printf("%s: key length mismatch, bit:%d len:%ld.\n",
|
||||||
|
__func__,
|
||||||
key->sadb_key_bits >> 3,
|
key->sadb_key_bits >> 3,
|
||||||
(long)PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key));
|
(long)PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key));
|
||||||
}
|
}
|
||||||
@ -382,7 +384,7 @@ kdebug_sadb_x_sa2(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_x_sa2: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_x_sa2{ mode=%u reqid=%u\n",
|
printf("sadb_x_sa2{ mode=%u reqid=%u\n",
|
||||||
sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid);
|
sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid);
|
||||||
@ -402,7 +404,7 @@ kdebug_sadb_x_policy(ext)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ext == NULL)
|
if (ext == NULL)
|
||||||
panic("kdebug_sadb_x_policy: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("sadb_x_policy{ type=%u dir=%u id=%x }\n",
|
printf("sadb_x_policy{ type=%u dir=%u id=%x }\n",
|
||||||
xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
|
xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
|
||||||
@ -435,12 +437,14 @@ kdebug_sadb_x_policy(ext)
|
|||||||
|
|
||||||
/* prevent infinite loop */
|
/* prevent infinite loop */
|
||||||
if (xisr->sadb_x_ipsecrequest_len <= 0) {
|
if (xisr->sadb_x_ipsecrequest_len <= 0) {
|
||||||
printf("kdebug_sadb_x_policy: wrong policy struct.\n");
|
printf("%s: wrong policy struct.\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* prevent overflow */
|
/* prevent overflow */
|
||||||
if (xisr->sadb_x_ipsecrequest_len > tlen) {
|
if (xisr->sadb_x_ipsecrequest_len > tlen) {
|
||||||
printf("invalid ipsec policy length\n");
|
printf("%s: invalid ipsec policy length "
|
||||||
|
"(%u > %u)\n", __func__,
|
||||||
|
xisr->sadb_x_ipsecrequest_len, tlen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +455,7 @@ kdebug_sadb_x_policy(ext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tlen != 0)
|
if (tlen != 0)
|
||||||
panic("kdebug_sadb_x_policy: wrong policy struct.\n");
|
panic("%s: wrong policy struct.\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -465,7 +469,7 @@ kdebug_secpolicy(sp)
|
|||||||
{
|
{
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
panic("kdebug_secpolicy: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("secpolicy{ refcnt=%u state=%u policy=%u\n",
|
printf("secpolicy{ refcnt=%u state=%u policy=%u\n",
|
||||||
sp->refcnt, sp->state, sp->policy);
|
sp->refcnt, sp->state, sp->policy);
|
||||||
@ -500,8 +504,7 @@ kdebug_secpolicy(sp)
|
|||||||
printf(" type=entrust }\n");
|
printf(" type=entrust }\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("kdebug_secpolicy: Invalid policy found. %d\n",
|
printf("%s: Invalid policy found. %d\n", __func__, sp->policy);
|
||||||
sp->policy);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +517,7 @@ kdebug_secpolicyindex(spidx)
|
|||||||
{
|
{
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (spidx == NULL)
|
if (spidx == NULL)
|
||||||
panic("kdebug_secpolicyindex: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("secpolicyindex{ dir=%u prefs=%u prefd=%u ul_proto=%u\n",
|
printf("secpolicyindex{ dir=%u prefs=%u prefd=%u ul_proto=%u\n",
|
||||||
spidx->dir, spidx->prefs, spidx->prefd, spidx->ul_proto);
|
spidx->dir, spidx->prefs, spidx->prefd, spidx->ul_proto);
|
||||||
@ -535,7 +538,7 @@ kdebug_secasindex(saidx)
|
|||||||
{
|
{
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (saidx == NULL)
|
if (saidx == NULL)
|
||||||
panic("kdebug_secpolicyindex: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("secasindex{ mode=%u proto=%u\n",
|
printf("secasindex{ mode=%u proto=%u\n",
|
||||||
saidx->mode, saidx->proto);
|
saidx->mode, saidx->proto);
|
||||||
@ -556,7 +559,7 @@ kdebug_secasv(sav)
|
|||||||
{
|
{
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (sav == NULL)
|
if (sav == NULL)
|
||||||
panic("kdebug_secasv: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf("secas{");
|
printf("secas{");
|
||||||
kdebug_secasindex(&sav->sah->saidx);
|
kdebug_secasindex(&sav->sah->saidx);
|
||||||
@ -600,7 +603,7 @@ kdebug_secreplay(rpl)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (rpl == NULL)
|
if (rpl == NULL)
|
||||||
panic("kdebug_secreplay: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u",
|
printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u",
|
||||||
rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
|
rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
|
||||||
@ -685,7 +688,7 @@ kdebug_sockaddr(addr)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (addr == NULL)
|
if (addr == NULL)
|
||||||
panic("kdebug_sockaddr: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
/* NOTE: We deal with port number as host byte order. */
|
/* NOTE: We deal with port number as host byte order. */
|
||||||
printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family);
|
printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family);
|
||||||
|
@ -102,7 +102,7 @@ struct secasvar {
|
|||||||
size_t schedlen;
|
size_t schedlen;
|
||||||
|
|
||||||
struct secreplay *replay; /* replay prevention */
|
struct secreplay *replay; /* replay prevention */
|
||||||
long created; /* for lifetime */
|
time_t created; /* for lifetime */
|
||||||
|
|
||||||
struct sadb_lifetime *lft_c; /* CURRENT lifetime, it's constant. */
|
struct sadb_lifetime *lft_c; /* CURRENT lifetime, it's constant. */
|
||||||
struct sadb_lifetime *lft_h; /* HARD lifetime */
|
struct sadb_lifetime *lft_h; /* HARD lifetime */
|
||||||
@ -125,6 +125,13 @@ struct secasvar {
|
|||||||
u_int64_t tdb_cryptoid; /* crypto session id */
|
u_int64_t tdb_cryptoid; /* crypto session id */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SECASVAR_LOCK_INIT(_sav) \
|
||||||
|
mtx_init(&(_sav)->lock, "ipsec association", NULL, MTX_DEF)
|
||||||
|
#define SECASVAR_LOCK(_sav) mtx_lock(&(_sav)->lock)
|
||||||
|
#define SECASVAR_UNLOCK(_sav) mtx_unlock(&(_sav)->lock)
|
||||||
|
#define SECASVAR_LOCK_DESTROY(_sav) mtx_destroy(&(_sav)->lock)
|
||||||
|
#define SECASVAR_LOCK_ASSERT(_sav) mtx_assert(&(_sav)->lock, MA_OWNED)
|
||||||
|
|
||||||
/* replay prevention */
|
/* replay prevention */
|
||||||
struct secreplay {
|
struct secreplay {
|
||||||
u_int32_t count;
|
u_int32_t count;
|
||||||
@ -142,7 +149,6 @@ struct secreg {
|
|||||||
struct socket *so;
|
struct socket *so;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef IPSEC_NONBLOCK_ACQUIRE
|
|
||||||
/* acquiring list table. */
|
/* acquiring list table. */
|
||||||
struct secacq {
|
struct secacq {
|
||||||
LIST_ENTRY(secacq) chain;
|
LIST_ENTRY(secacq) chain;
|
||||||
@ -150,10 +156,9 @@ struct secacq {
|
|||||||
struct secasindex saidx;
|
struct secasindex saidx;
|
||||||
|
|
||||||
u_int32_t seq; /* sequence number */
|
u_int32_t seq; /* sequence number */
|
||||||
long created; /* for lifetime */
|
time_t created; /* for lifetime */
|
||||||
int count; /* for lifetime */
|
int count; /* for lifetime */
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sensitivity Level Specification */
|
/* Sensitivity Level Specification */
|
||||||
/* nothing */
|
/* nothing */
|
||||||
|
@ -94,7 +94,7 @@ key_output(m, va_alist)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (m == 0)
|
if (m == 0)
|
||||||
panic("key_output: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
pfkeystat.out_total++;
|
pfkeystat.out_total++;
|
||||||
pfkeystat.out_bytes += m->m_pkthdr.len;
|
pfkeystat.out_bytes += m->m_pkthdr.len;
|
||||||
@ -195,10 +195,10 @@ key_sendup(so, msg, len, target)
|
|||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (so == 0 || msg == 0)
|
if (so == 0 || msg == 0)
|
||||||
panic("key_sendup: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
KEYDEBUG(KEYDEBUG_KEY_DUMP,
|
KEYDEBUG(KEYDEBUG_KEY_DUMP,
|
||||||
printf("key_sendup: \n");
|
printf("%s: \n", __func__);
|
||||||
kdebug_sadb(msg));
|
kdebug_sadb(msg));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -283,7 +283,7 @@ key_sendup_mbuf(so, m, target)
|
|||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
panic("key_sendup_mbuf: NULL pointer was passed.\n");
|
panic("key_sendup_mbuf: NULL pointer was passed.\n");
|
||||||
if (so == NULL && target == KEY_SENDUP_ONE)
|
if (so == NULL && target == KEY_SENDUP_ONE)
|
||||||
panic("key_sendup_mbuf: NULL pointer was passed.\n");
|
panic("%s: NULL pointer was passed.\n", __func__);
|
||||||
|
|
||||||
pfkeystat.in_total++;
|
pfkeystat.in_total++;
|
||||||
pfkeystat.in_bytes += m->m_pkthdr.len;
|
pfkeystat.in_bytes += m->m_pkthdr.len;
|
||||||
|
@ -142,8 +142,7 @@ ah_hdrsiz(struct secasvar *sav)
|
|||||||
|
|
||||||
if (sav != NULL) {
|
if (sav != NULL) {
|
||||||
int authsize;
|
int authsize;
|
||||||
KASSERT(sav->tdb_authalgxform != NULL,
|
IPSEC_ASSERT(sav->tdb_authalgxform != NULL, ("null xform"));
|
||||||
("ah_hdrsiz: null xform"));
|
|
||||||
/*XXX not right for null algorithm--does it matter??*/
|
/*XXX not right for null algorithm--does it matter??*/
|
||||||
authsize = AUTHSIZE(sav);
|
authsize = AUTHSIZE(sav);
|
||||||
size = roundup(authsize, sizeof (u_int32_t)) + HDRSIZE(sav);
|
size = roundup(authsize, sizeof (u_int32_t)) + HDRSIZE(sav);
|
||||||
@ -165,8 +164,8 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria)
|
|||||||
|
|
||||||
thash = ah_algorithm_lookup(sav->alg_auth);
|
thash = ah_algorithm_lookup(sav->alg_auth);
|
||||||
if (thash == NULL) {
|
if (thash == NULL) {
|
||||||
DPRINTF(("ah_init: unsupported authentication algorithm %u\n",
|
DPRINTF(("%s: unsupported authentication algorithm %u\n",
|
||||||
sav->alg_auth));
|
__func__, sav->alg_auth));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -176,21 +175,21 @@ ah_init0(struct secasvar *sav, struct xformsw *xsp, struct cryptoini *cria)
|
|||||||
*/
|
*/
|
||||||
/* NB: replay state is setup elsewhere (sigh) */
|
/* NB: replay state is setup elsewhere (sigh) */
|
||||||
if (((sav->flags&SADB_X_EXT_OLD) == 0) ^ (sav->replay != NULL)) {
|
if (((sav->flags&SADB_X_EXT_OLD) == 0) ^ (sav->replay != NULL)) {
|
||||||
DPRINTF(("ah_init: replay state block inconsistency, "
|
DPRINTF(("%s: replay state block inconsistency, "
|
||||||
"%s algorithm %s replay state\n",
|
"%s algorithm %s replay state\n", __func__,
|
||||||
(sav->flags & SADB_X_EXT_OLD) ? "old" : "new",
|
(sav->flags & SADB_X_EXT_OLD) ? "old" : "new",
|
||||||
sav->replay == NULL ? "without" : "with"));
|
sav->replay == NULL ? "without" : "with"));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (sav->key_auth == NULL) {
|
if (sav->key_auth == NULL) {
|
||||||
DPRINTF(("ah_init: no authentication key for %s "
|
DPRINTF(("%s: no authentication key for %s algorithm\n",
|
||||||
"algorithm\n", thash->name));
|
__func__, thash->name));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
keylen = _KEYLEN(sav->key_auth);
|
keylen = _KEYLEN(sav->key_auth);
|
||||||
if (keylen != thash->keysize && thash->keysize != 0) {
|
if (keylen != thash->keysize && thash->keysize != 0) {
|
||||||
DPRINTF(("ah_init: invalid keylength %d, algorithm "
|
DPRINTF(("%s: invalid keylength %d, algorithm %s requires "
|
||||||
"%s requires keysize %d\n",
|
"keysize %d\n", __func__,
|
||||||
keylen, thash->name, thash->keysize));
|
keylen, thash->name, thash->keysize));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -271,7 +270,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
*/
|
*/
|
||||||
*m0 = m = m_pullup(m, skip);
|
*m0 = m = m_pullup(m, skip);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
DPRINTF(("ah_massage_headers: m_pullup failed\n"));
|
DPRINTF(("%s: m_pullup failed\n", __func__));
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,9 +307,8 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
off + 1 < skip)
|
off + 1 < skip)
|
||||||
;
|
;
|
||||||
else {
|
else {
|
||||||
DPRINTF(("ah_massage_headers: illegal IPv4 "
|
DPRINTF(("%s: illegal IPv4 option length for "
|
||||||
"option length for option %d\n",
|
"option %d\n", __func__, ptr[off]));
|
||||||
ptr[off]));
|
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -332,9 +330,9 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
case 0x95: /* RFC1770 */
|
case 0x95: /* RFC1770 */
|
||||||
/* Sanity check for option length. */
|
/* Sanity check for option length. */
|
||||||
if (ptr[off + 1] < 2) {
|
if (ptr[off + 1] < 2) {
|
||||||
DPRINTF(("ah_massage_headers: "
|
DPRINTF(("%s: illegal IPv4 option "
|
||||||
"illegal IPv4 option length for "
|
"length for option %d\n",
|
||||||
"option %d\n", ptr[off]));
|
__func__, ptr[off]));
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -347,9 +345,9 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
case IPOPT_SSRR:
|
case IPOPT_SSRR:
|
||||||
/* Sanity check for option length. */
|
/* Sanity check for option length. */
|
||||||
if (ptr[off + 1] < 2) {
|
if (ptr[off + 1] < 2) {
|
||||||
DPRINTF(("ah_massage_headers: "
|
DPRINTF(("%s: illegal IPv4 option "
|
||||||
"illegal IPv4 option length for "
|
"length for option %d\n",
|
||||||
"option %d\n", ptr[off]));
|
__func__, ptr[off]));
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -373,9 +371,9 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
default:
|
default:
|
||||||
/* Sanity check for option length. */
|
/* Sanity check for option length. */
|
||||||
if (ptr[off + 1] < 2) {
|
if (ptr[off + 1] < 2) {
|
||||||
DPRINTF(("ah_massage_headers: "
|
DPRINTF(("%s: illegal IPv4 option "
|
||||||
"illegal IPv4 option length for "
|
"length for option %d\n",
|
||||||
"option %d\n", ptr[off]));
|
__func__, ptr[off]));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -389,8 +387,8 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
|
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (off > skip) {
|
if (off > skip) {
|
||||||
DPRINTF(("ah_massage_headers(): malformed "
|
DPRINTF(("%s: malformed IPv4 options header\n",
|
||||||
"IPv4 options header\n"));
|
__func__));
|
||||||
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -407,7 +405,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
|
|
||||||
/* We don't do IPv6 Jumbograms. */
|
/* We don't do IPv6 Jumbograms. */
|
||||||
if (ip6.ip6_plen == 0) {
|
if (ip6.ip6_plen == 0) {
|
||||||
DPRINTF(("ah_massage_headers: unsupported IPv6 jumbogram\n"));
|
DPRINTF(("%s: unsupported IPv6 jumbogram\n", __func__));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EMSGSIZE;
|
return EMSGSIZE;
|
||||||
}
|
}
|
||||||
@ -433,9 +431,8 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
skip - sizeof(struct ip6_hdr),
|
skip - sizeof(struct ip6_hdr),
|
||||||
M_XDATA, M_NOWAIT);
|
M_XDATA, M_NOWAIT);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
DPRINTF(("ah_massage_headers: failed "
|
DPRINTF(("%s: failed to allocate memory"
|
||||||
"to allocate memory for IPv6 "
|
"for IPv6 headers\n",__func__));
|
||||||
"headers\n"));
|
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
@ -524,8 +521,8 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINTF(("ah_massage_headers: unexpected "
|
DPRINTF(("%s: unexpected IPv6 header type %d",
|
||||||
"IPv6 header type %d", off));
|
__func__, off));
|
||||||
if (alloc)
|
if (alloc)
|
||||||
FREE(ptr, M_XDATA);
|
FREE(ptr, M_XDATA);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
@ -563,15 +560,12 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
struct cryptodesc *crda;
|
struct cryptodesc *crda;
|
||||||
struct cryptop *crp;
|
struct cryptop *crp;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ah_input");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(sav != NULL, ("ah_input: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
KASSERT(sav->key_auth != NULL,
|
IPSEC_ASSERT(sav->key_auth != NULL, ("null authentication key"));
|
||||||
("ah_input: null authentication key"));
|
IPSEC_ASSERT(sav->tdb_authalgxform != NULL,
|
||||||
KASSERT(sav->tdb_authalgxform != NULL,
|
("null authentication xform"));
|
||||||
("ah_input: null authentication xform"));
|
|
||||||
|
|
||||||
/* Figure out header size. */
|
/* Figure out header size. */
|
||||||
rplen = HDRSIZE(sav);
|
rplen = HDRSIZE(sav);
|
||||||
@ -588,7 +582,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
/* Check replay window, if applicable. */
|
/* Check replay window, if applicable. */
|
||||||
if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
|
if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
|
||||||
ahstat.ahs_replay++;
|
ahstat.ahs_replay++;
|
||||||
DPRINTF(("ah_input: packet replay failure: %s\n",
|
DPRINTF(("%s: packet replay failure: %s\n", __func__,
|
||||||
ipsec_logsastr(sav)));
|
ipsec_logsastr(sav)));
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
@ -599,8 +593,8 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
ahx = sav->tdb_authalgxform;
|
ahx = sav->tdb_authalgxform;
|
||||||
authsize = AUTHSIZE(sav);
|
authsize = AUTHSIZE(sav);
|
||||||
if (hl != authsize + rplen - sizeof (struct ah)) {
|
if (hl != authsize + rplen - sizeof (struct ah)) {
|
||||||
DPRINTF(("ah_input: bad authenticator length %u (expecting %lu)"
|
DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
|
||||||
" for packet in SA %s/%08lx\n",
|
" for packet in SA %s/%08lx\n", __func__,
|
||||||
hl, (u_long) (authsize + rplen - sizeof (struct ah)),
|
hl, (u_long) (authsize + rplen - sizeof (struct ah)),
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -613,14 +607,14 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
/* Get crypto descriptors. */
|
/* Get crypto descriptors. */
|
||||||
crp = crypto_getreq(1);
|
crp = crypto_getreq(1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
DPRINTF(("ah_input: failed to acquire crypto descriptor\n"));
|
DPRINTF(("%s: failed to acquire crypto descriptor\n",__func__));
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
crda = crp->crp_desc;
|
crda = crp->crp_desc;
|
||||||
KASSERT(crda != NULL, ("ah_input: null crypto descriptor"));
|
IPSEC_ASSERT(crda != NULL, ("null crypto descriptor"));
|
||||||
|
|
||||||
crda->crd_skip = 0;
|
crda->crd_skip = 0;
|
||||||
crda->crd_len = m->m_pkthdr.len;
|
crda->crd_len = m->m_pkthdr.len;
|
||||||
@ -653,7 +647,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
M_XDATA, M_NOWAIT|M_ZERO);
|
M_XDATA, M_NOWAIT|M_ZERO);
|
||||||
}
|
}
|
||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
DPRINTF(("ah_input: failed to allocate tdb_crypto\n"));
|
DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
@ -743,7 +737,7 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
crd = crp->crp_desc;
|
crd = crp->crp_desc;
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("ah_input_cb: null opaque crypto data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque crypto data area!"));
|
||||||
skip = tc->tc_skip;
|
skip = tc->tc_skip;
|
||||||
nxt = tc->tc_nxt;
|
nxt = tc->tc_nxt;
|
||||||
protoff = tc->tc_protoff;
|
protoff = tc->tc_protoff;
|
||||||
@ -753,16 +747,15 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
ahstat.ahs_notdb++;
|
ahstat.ahs_notdb++;
|
||||||
DPRINTF(("ah_input_cb: SA expired while in crypto\n"));
|
DPRINTF(("%s: SA expired while in crypto\n", __func__));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
saidx = &sav->sah->saidx;
|
saidx = &sav->sah->saidx;
|
||||||
KASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
||||||
saidx->dst.sa.sa_family == AF_INET6,
|
saidx->dst.sa.sa_family == AF_INET6,
|
||||||
("ah_input_cb: unexpected protocol family %u",
|
("unexpected protocol family %u", saidx->dst.sa.sa_family));
|
||||||
saidx->dst.sa.sa_family));
|
|
||||||
|
|
||||||
ahx = (struct auth_hash *) sav->tdb_authalgxform;
|
ahx = (struct auth_hash *) sav->tdb_authalgxform;
|
||||||
|
|
||||||
@ -775,7 +768,7 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
return crypto_dispatch(crp);
|
return crypto_dispatch(crp);
|
||||||
|
|
||||||
ahstat.ahs_noxform++;
|
ahstat.ahs_noxform++;
|
||||||
DPRINTF(("ah_input_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
} else {
|
} else {
|
||||||
@ -787,7 +780,7 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
DPRINTF(("ah_input_cb: bogus returned buffer from crypto\n"));
|
DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -808,8 +801,8 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
/* Verify authenticator. */
|
/* Verify authenticator. */
|
||||||
if (bcmp(ptr + skip + rplen, calc, authsize)) {
|
if (bcmp(ptr + skip + rplen, calc, authsize)) {
|
||||||
DPRINTF(("ah_input: authentication hash mismatch "
|
DPRINTF(("%s: authentication hash mismatch for packet "
|
||||||
"for packet in SA %s/%08lx\n",
|
"in SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst),
|
ipsec_address(&saidx->dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
ahstat.ahs_badauth++;
|
ahstat.ahs_badauth++;
|
||||||
@ -854,7 +847,7 @@ ah_input_cb(struct cryptop *crp)
|
|||||||
*/
|
*/
|
||||||
error = m_striphdr(m, skip, rplen + authsize);
|
error = m_striphdr(m, skip, rplen + authsize);
|
||||||
if (error) {
|
if (error) {
|
||||||
DPRINTF(("ah_input_cb: mangled mbuf chain for SA %s/%08lx\n",
|
DPRINTF(("%s: mangled mbuf chain for SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
||||||
|
|
||||||
ahstat.ahs_hdrops++;
|
ahstat.ahs_hdrops++;
|
||||||
@ -900,14 +893,12 @@ ah_output(
|
|||||||
u_int8_t prot;
|
u_int8_t prot;
|
||||||
struct newah *ah;
|
struct newah *ah;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ah_output");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
KASSERT(sav != NULL, ("ah_output: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
ahx = sav->tdb_authalgxform;
|
ahx = sav->tdb_authalgxform;
|
||||||
KASSERT(ahx != NULL, ("ah_output: null authentication xform"));
|
IPSEC_ASSERT(ahx != NULL, ("null authentication xform"));
|
||||||
|
|
||||||
ahstat.ahs_output++;
|
ahstat.ahs_output++;
|
||||||
|
|
||||||
@ -927,8 +918,8 @@ ah_output(
|
|||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
DPRINTF(("ah_output: unknown/unsupported protocol "
|
DPRINTF(("%s: unknown/unsupported protocol family %u, "
|
||||||
"family %u, SA %s/%08lx\n",
|
"SA %s/%08lx\n", __func__,
|
||||||
sav->sah->saidx.dst.sa.sa_family,
|
sav->sah->saidx.dst.sa.sa_family,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -938,8 +929,8 @@ ah_output(
|
|||||||
}
|
}
|
||||||
authsize = AUTHSIZE(sav);
|
authsize = AUTHSIZE(sav);
|
||||||
if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
|
if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
|
||||||
DPRINTF(("ah_output: packet in SA %s/%08lx got too big "
|
DPRINTF(("%s: packet in SA %s/%08lx got too big "
|
||||||
"(len %u, max len %u)\n",
|
"(len %u, max len %u)\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi),
|
(u_long) ntohl(sav->spi),
|
||||||
rplen + authsize + m->m_pkthdr.len, maxpacketsize));
|
rplen + authsize + m->m_pkthdr.len, maxpacketsize));
|
||||||
@ -953,7 +944,7 @@ ah_output(
|
|||||||
|
|
||||||
m = m_clone(m);
|
m = m_clone(m);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
DPRINTF(("ah_output: cannot clone mbuf chain, SA %s/%08lx\n",
|
DPRINTF(("%s: cannot clone mbuf chain, SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
ahstat.ahs_hdrops++;
|
ahstat.ahs_hdrops++;
|
||||||
@ -964,8 +955,8 @@ ah_output(
|
|||||||
/* Inject AH header. */
|
/* Inject AH header. */
|
||||||
mi = m_makespace(m, skip, rplen + authsize, &roff);
|
mi = m_makespace(m, skip, rplen + authsize, &roff);
|
||||||
if (mi == NULL) {
|
if (mi == NULL) {
|
||||||
DPRINTF(("ah_output: failed to inject %u byte AH header for SA "
|
DPRINTF(("%s: failed to inject %u byte AH header for SA "
|
||||||
"%s/%08lx\n",
|
"%s/%08lx\n", __func__,
|
||||||
rplen + authsize,
|
rplen + authsize,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -993,8 +984,8 @@ ah_output(
|
|||||||
if (sav->replay) {
|
if (sav->replay) {
|
||||||
if (sav->replay->count == ~0 &&
|
if (sav->replay->count == ~0 &&
|
||||||
(sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
|
(sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
|
||||||
DPRINTF(("ah_output: replay counter wrapped for SA "
|
DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
|
||||||
"%s/%08lx\n",
|
__func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
ahstat.ahs_wrap++;
|
ahstat.ahs_wrap++;
|
||||||
@ -1008,7 +999,8 @@ ah_output(
|
|||||||
/* Get crypto descriptors. */
|
/* Get crypto descriptors. */
|
||||||
crp = crypto_getreq(1);
|
crp = crypto_getreq(1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
DPRINTF(("ah_output: failed to acquire crypto descriptors\n"));
|
DPRINTF(("%s: failed to acquire crypto descriptors\n",
|
||||||
|
__func__));
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -1030,7 +1022,7 @@ ah_output(
|
|||||||
sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT|M_ZERO);
|
sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT|M_ZERO);
|
||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
DPRINTF(("ah_output: failed to allocate tdb_crypto\n"));
|
DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -1123,22 +1115,22 @@ ah_output_cb(struct cryptop *crp)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("ah_output_cb: null opaque data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
|
||||||
skip = tc->tc_skip;
|
skip = tc->tc_skip;
|
||||||
protoff = tc->tc_protoff;
|
protoff = tc->tc_protoff;
|
||||||
ptr = (caddr_t) (tc + 1);
|
ptr = (caddr_t) (tc + 1);
|
||||||
m = (struct mbuf *) crp->crp_buf;
|
m = (struct mbuf *) crp->crp_buf;
|
||||||
|
|
||||||
isr = tc->tc_isr;
|
isr = tc->tc_isr;
|
||||||
mtx_lock(&isr->lock);
|
IPSECREQUEST_LOCK(isr);
|
||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
ahstat.ahs_notdb++;
|
ahstat.ahs_notdb++;
|
||||||
DPRINTF(("ah_output_cb: SA expired while in crypto\n"));
|
DPRINTF(("%s: SA expired while in crypto\n", __func__));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
KASSERT(isr->sav == sav, ("ah_output_cb: SA changed\n"));
|
IPSEC_ASSERT(isr->sav == sav, ("SA changed\n"));
|
||||||
|
|
||||||
/* Check for crypto errors. */
|
/* Check for crypto errors. */
|
||||||
if (crp->crp_etype) {
|
if (crp->crp_etype) {
|
||||||
@ -1147,12 +1139,12 @@ ah_output_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
if (crp->crp_etype == EAGAIN) {
|
if (crp->crp_etype == EAGAIN) {
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
return crypto_dispatch(crp);
|
return crypto_dispatch(crp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ahstat.ahs_noxform++;
|
ahstat.ahs_noxform++;
|
||||||
DPRINTF(("ah_output_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -1160,7 +1152,7 @@ ah_output_cb(struct cryptop *crp)
|
|||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
ahstat.ahs_crypto++;
|
ahstat.ahs_crypto++;
|
||||||
DPRINTF(("ah_output_cb: bogus returned buffer from crypto\n"));
|
DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -1179,13 +1171,13 @@ ah_output_cb(struct cryptop *crp)
|
|||||||
/* NB: m is reclaimed by ipsec_process_done. */
|
/* NB: m is reclaimed by ipsec_process_done. */
|
||||||
err = ipsec_process_done(m, isr);
|
err = ipsec_process_done(m, isr);
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
bad:
|
bad:
|
||||||
if (sav)
|
if (sav)
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
if (m)
|
if (m)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
free(tc, M_XDATA);
|
free(tc, M_XDATA);
|
||||||
|
@ -124,8 +124,8 @@ esp_hdrsiz(struct secasvar *sav)
|
|||||||
|
|
||||||
if (sav != NULL) {
|
if (sav != NULL) {
|
||||||
/*XXX not right for null algorithm--does it matter??*/
|
/*XXX not right for null algorithm--does it matter??*/
|
||||||
KASSERT(sav->tdb_encalgxform != NULL,
|
IPSEC_ASSERT(sav->tdb_encalgxform != NULL,
|
||||||
("esp_hdrsiz: SA with null xform"));
|
("SA with null xform"));
|
||||||
if (sav->flags & SADB_X_EXT_OLD)
|
if (sav->flags & SADB_X_EXT_OLD)
|
||||||
size = sizeof (struct esp);
|
size = sizeof (struct esp);
|
||||||
else
|
else
|
||||||
@ -161,23 +161,24 @@ esp_init(struct secasvar *sav, struct xformsw *xsp)
|
|||||||
|
|
||||||
txform = esp_algorithm_lookup(sav->alg_enc);
|
txform = esp_algorithm_lookup(sav->alg_enc);
|
||||||
if (txform == NULL) {
|
if (txform == NULL) {
|
||||||
DPRINTF(("esp_init: unsupported encryption algorithm %d\n",
|
DPRINTF(("%s: unsupported encryption algorithm %d\n",
|
||||||
sav->alg_enc));
|
__func__, sav->alg_enc));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (sav->key_enc == NULL) {
|
if (sav->key_enc == NULL) {
|
||||||
DPRINTF(("esp_init: no encoding key for %s algorithm\n",
|
DPRINTF(("%s: no encoding key for %s algorithm\n",
|
||||||
txform->name));
|
__func__, txform->name));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) {
|
if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) {
|
||||||
DPRINTF(("esp_init: 4-byte IV not supported with protocol\n"));
|
DPRINTF(("%s: 4-byte IV not supported with protocol\n",
|
||||||
|
__func__));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
keylen = _KEYLEN(sav->key_enc);
|
keylen = _KEYLEN(sav->key_enc);
|
||||||
if (txform->minkey > keylen || keylen > txform->maxkey) {
|
if (txform->minkey > keylen || keylen > txform->maxkey) {
|
||||||
DPRINTF(("esp_init: invalid key length %u, must be in "
|
DPRINTF(("%s: invalid key length %u, must be in the range "
|
||||||
"the range [%u..%u] for algorithm %s\n",
|
"[%u..%u] for algorithm %s\n", __func__,
|
||||||
keylen, txform->minkey, txform->maxkey,
|
keylen, txform->minkey, txform->maxkey,
|
||||||
txform->name));
|
txform->name));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -192,7 +193,7 @@ esp_init(struct secasvar *sav, struct xformsw *xsp)
|
|||||||
sav->ivlen = (txform == &enc_xform_null ? 0 : txform->blocksize);
|
sav->ivlen = (txform == &enc_xform_null ? 0 : txform->blocksize);
|
||||||
sav->iv = (caddr_t) malloc(sav->ivlen, M_XDATA, M_WAITOK);
|
sav->iv = (caddr_t) malloc(sav->ivlen, M_XDATA, M_WAITOK);
|
||||||
if (sav->iv == NULL) {
|
if (sav->iv == NULL) {
|
||||||
DPRINTF(("esp_init: no memory for IV\n"));
|
DPRINTF(("%s: no memory for IV\n", __func__));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
key_randomfill(sav->iv, sav->ivlen); /*XXX*/
|
key_randomfill(sav->iv, sav->ivlen); /*XXX*/
|
||||||
@ -230,7 +231,8 @@ esp_init(struct secasvar *sav, struct xformsw *xsp)
|
|||||||
&cria, crypto_support);
|
&cria, crypto_support);
|
||||||
} else {
|
} else {
|
||||||
/* XXX cannot happen? */
|
/* XXX cannot happen? */
|
||||||
DPRINTF(("esp_init: no encoding OR authentication xform!\n"));
|
DPRINTF(("%s: no encoding OR authentication xform!\n",
|
||||||
|
__func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
@ -247,7 +249,10 @@ esp_zeroize(struct secasvar *sav)
|
|||||||
|
|
||||||
if (sav->key_enc)
|
if (sav->key_enc)
|
||||||
bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
|
bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
|
||||||
/* NB: sav->iv is freed elsewhere, even though we malloc it! */
|
if (sav->iv) {
|
||||||
|
free(sav->iv, M_XDATA);
|
||||||
|
sav->iv = NULL;
|
||||||
|
}
|
||||||
sav->tdb_encalgxform = NULL;
|
sav->tdb_encalgxform = NULL;
|
||||||
sav->tdb_xform = NULL;
|
sav->tdb_xform = NULL;
|
||||||
return error;
|
return error;
|
||||||
@ -270,15 +275,12 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
struct cryptodesc *crde;
|
struct cryptodesc *crde;
|
||||||
struct cryptop *crp;
|
struct cryptop *crp;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "esp_input");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KASSERT(sav != NULL, ("esp_input: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
KASSERT(sav->tdb_encalgxform != NULL,
|
IPSEC_ASSERT(sav->tdb_encalgxform != NULL, ("null encoding xform"));
|
||||||
("esp_input: null encoding xform"));
|
IPSEC_ASSERT((skip&3) == 0 && (m->m_pkthdr.len&3) == 0,
|
||||||
KASSERT((skip&3) == 0 && (m->m_pkthdr.len&3) == 0,
|
("misaligned packet, skip %u pkt len %u",
|
||||||
("esp_input: misaligned packet, skip %u pkt len %u",
|
|
||||||
skip, m->m_pkthdr.len));
|
skip, m->m_pkthdr.len));
|
||||||
|
|
||||||
/* XXX don't pullup, just copy header */
|
/* XXX don't pullup, just copy header */
|
||||||
@ -305,9 +307,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
*/
|
*/
|
||||||
plen = m->m_pkthdr.len - (skip + hlen + alen);
|
plen = m->m_pkthdr.len - (skip + hlen + alen);
|
||||||
if ((plen & (espx->blocksize - 1)) || (plen <= 0)) {
|
if ((plen & (espx->blocksize - 1)) || (plen <= 0)) {
|
||||||
DPRINTF(("esp_input: "
|
DPRINTF(("%s: payload of %d octets not a multiple of %d octets,"
|
||||||
"payload of %d octets not a multiple of %d octets,"
|
" SA %s/%08lx\n", __func__,
|
||||||
" SA %s/%08lx\n",
|
|
||||||
plen, espx->blocksize,
|
plen, espx->blocksize,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -320,7 +321,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
* Check sequence number.
|
* Check sequence number.
|
||||||
*/
|
*/
|
||||||
if (esph && sav->replay && !ipsec_chkreplay(ntohl(esp->esp_seq), sav)) {
|
if (esph && sav->replay && !ipsec_chkreplay(ntohl(esp->esp_seq), sav)) {
|
||||||
DPRINTF(("esp_input: packet replay check for %s\n",
|
DPRINTF(("%s: packet replay check for %s\n", __func__,
|
||||||
ipsec_logsastr(sav))); /*XXX*/
|
ipsec_logsastr(sav))); /*XXX*/
|
||||||
espstat.esps_replay++;
|
espstat.esps_replay++;
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
@ -345,7 +346,8 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
/* Get crypto descriptors */
|
/* Get crypto descriptors */
|
||||||
crp = crypto_getreq(esph && espx ? 2 : 1);
|
crp = crypto_getreq(esph && espx ? 2 : 1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
DPRINTF(("esp_input: failed to acquire crypto descriptors\n"));
|
DPRINTF(("%s: failed to acquire crypto descriptors\n",
|
||||||
|
__func__));
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
@ -360,7 +362,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
M_XDATA, M_NOWAIT|M_ZERO);
|
M_XDATA, M_NOWAIT|M_ZERO);
|
||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
DPRINTF(("esp_input: failed to allocate tdb_crypto\n"));
|
DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
@ -371,7 +373,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
if (esph) {
|
if (esph) {
|
||||||
struct cryptodesc *crda = crp->crp_desc;
|
struct cryptodesc *crda = crp->crp_desc;
|
||||||
|
|
||||||
KASSERT(crda != NULL, ("esp_input: null ah crypto descriptor"));
|
IPSEC_ASSERT(crda != NULL, ("null ah crypto descriptor"));
|
||||||
|
|
||||||
/* Authentication descriptor */
|
/* Authentication descriptor */
|
||||||
crda->crd_skip = skip;
|
crda->crd_skip = skip;
|
||||||
@ -410,7 +412,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
|
|
||||||
/* Decryption descriptor */
|
/* Decryption descriptor */
|
||||||
if (espx) {
|
if (espx) {
|
||||||
KASSERT(crde != NULL, ("esp_input: null esp crypto descriptor"));
|
IPSEC_ASSERT(crde != NULL, ("null esp crypto descriptor"));
|
||||||
crde->crd_skip = skip + hlen;
|
crde->crd_skip = skip + hlen;
|
||||||
crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
|
crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
|
||||||
crde->crd_inject = skip + hlen - sav->ivlen;
|
crde->crd_inject = skip + hlen - sav->ivlen;
|
||||||
@ -459,10 +461,10 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
caddr_t ptr;
|
caddr_t ptr;
|
||||||
|
|
||||||
crd = crp->crp_desc;
|
crd = crp->crp_desc;
|
||||||
KASSERT(crd != NULL, ("esp_input_cb: null crypto descriptor!"));
|
IPSEC_ASSERT(crd != NULL, ("null crypto descriptor!"));
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("esp_input_cb: null opaque crypto data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque crypto data area!"));
|
||||||
skip = tc->tc_skip;
|
skip = tc->tc_skip;
|
||||||
protoff = tc->tc_protoff;
|
protoff = tc->tc_protoff;
|
||||||
mtag = (struct m_tag *) tc->tc_ptr;
|
mtag = (struct m_tag *) tc->tc_ptr;
|
||||||
@ -471,18 +473,17 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
espstat.esps_notdb++;
|
espstat.esps_notdb++;
|
||||||
DPRINTF(("esp_input_cb: SA expired while in crypto "
|
DPRINTF(("%s: SA gone during crypto (SA %s/%08lx proto %u)\n",
|
||||||
"(SA %s/%08lx proto %u)\n", ipsec_address(&tc->tc_dst),
|
__func__, ipsec_address(&tc->tc_dst),
|
||||||
(u_long) ntohl(tc->tc_spi), tc->tc_proto));
|
(u_long) ntohl(tc->tc_spi), tc->tc_proto));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
saidx = &sav->sah->saidx;
|
saidx = &sav->sah->saidx;
|
||||||
KASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
||||||
saidx->dst.sa.sa_family == AF_INET6,
|
saidx->dst.sa.sa_family == AF_INET6,
|
||||||
("ah_input_cb: unexpected protocol family %u",
|
("unexpected protocol family %u", saidx->dst.sa.sa_family));
|
||||||
saidx->dst.sa.sa_family));
|
|
||||||
|
|
||||||
esph = sav->tdb_authalgxform;
|
esph = sav->tdb_authalgxform;
|
||||||
espx = sav->tdb_encalgxform;
|
espx = sav->tdb_encalgxform;
|
||||||
@ -499,7 +500,7 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
espstat.esps_noxform++;
|
espstat.esps_noxform++;
|
||||||
DPRINTF(("esp_input_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -507,7 +508,7 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
DPRINTF(("esp_input_cb: bogus returned buffer from crypto\n"));
|
DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -530,8 +531,9 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
/* Verify authenticator */
|
/* Verify authenticator */
|
||||||
if (bcmp(ptr, aalg, esph->authsize) != 0) {
|
if (bcmp(ptr, aalg, esph->authsize) != 0) {
|
||||||
DPRINTF(("esp_input_cb: "
|
DPRINTF(("%s: "
|
||||||
"authentication hash mismatch for packet in SA %s/%08lx\n",
|
"authentication hash mismatch for packet in SA %s/%08lx\n",
|
||||||
|
__func__,
|
||||||
ipsec_address(&saidx->dst),
|
ipsec_address(&saidx->dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
espstat.esps_badauth++;
|
espstat.esps_badauth++;
|
||||||
@ -563,7 +565,7 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
error = m_striphdr(m, skip, hlen);
|
error = m_striphdr(m, skip, hlen);
|
||||||
if (error) {
|
if (error) {
|
||||||
espstat.esps_hdrops++;
|
espstat.esps_hdrops++;
|
||||||
DPRINTF(("esp_input_cb: bad mbuf chain, SA %s/%08lx\n",
|
DPRINTF(("%s: bad mbuf chain, SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -575,8 +577,8 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
/* Verify pad length */
|
/* Verify pad length */
|
||||||
if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
|
if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
|
||||||
espstat.esps_badilen++;
|
espstat.esps_badilen++;
|
||||||
DPRINTF(("esp_input_cb: invalid padding length %d "
|
DPRINTF(("%s: invalid padding length %d for %u byte packet "
|
||||||
"for %u byte packet in SA %s/%08lx\n",
|
"in SA %s/%08lx\n", __func__,
|
||||||
lastthree[1], m->m_pkthdr.len - skip,
|
lastthree[1], m->m_pkthdr.len - skip,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -588,11 +590,10 @@ esp_input_cb(struct cryptop *crp)
|
|||||||
if ((sav->flags & SADB_X_EXT_PMASK) != SADB_X_EXT_PRAND) {
|
if ((sav->flags & SADB_X_EXT_PMASK) != SADB_X_EXT_PRAND) {
|
||||||
if (lastthree[1] != lastthree[0] && lastthree[1] != 0) {
|
if (lastthree[1] != lastthree[0] && lastthree[1] != 0) {
|
||||||
espstat.esps_badenc++;
|
espstat.esps_badenc++;
|
||||||
DPRINTF(("esp_input_cb: decryption failed "
|
DPRINTF(("%s: decryption failed for packet in "
|
||||||
"for packet in SA %s/%08lx\n",
|
"SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
DPRINTF(("esp_input_cb: %x %x\n", lastthree[0], lastthree[1]));
|
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -646,15 +647,13 @@ esp_output(
|
|||||||
struct cryptodesc *crde = NULL, *crda = NULL;
|
struct cryptodesc *crde = NULL, *crda = NULL;
|
||||||
struct cryptop *crp;
|
struct cryptop *crp;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "esp_output");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
KASSERT(sav != NULL, ("esp_output: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
esph = sav->tdb_authalgxform;
|
esph = sav->tdb_authalgxform;
|
||||||
espx = sav->tdb_encalgxform;
|
espx = sav->tdb_encalgxform;
|
||||||
KASSERT(espx != NULL, ("esp_output: null encoding xform"));
|
IPSEC_ASSERT(espx != NULL, ("null encoding xform"));
|
||||||
|
|
||||||
if (sav->flags & SADB_X_EXT_OLD)
|
if (sav->flags & SADB_X_EXT_OLD)
|
||||||
hlen = sizeof (struct esp) + sav->ivlen;
|
hlen = sizeof (struct esp) + sav->ivlen;
|
||||||
@ -693,8 +692,8 @@ esp_output(
|
|||||||
break;
|
break;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
DPRINTF(("esp_output: unknown/unsupported protocol "
|
DPRINTF(("%s: unknown/unsupported protocol "
|
||||||
"family %d, SA %s/%08lx\n",
|
"family %d, SA %s/%08lx\n", __func__,
|
||||||
saidx->dst.sa.sa_family, ipsec_address(&saidx->dst),
|
saidx->dst.sa.sa_family, ipsec_address(&saidx->dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
espstat.esps_nopf++;
|
espstat.esps_nopf++;
|
||||||
@ -702,8 +701,8 @@ esp_output(
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (skip + hlen + rlen + padding + alen > maxpacketsize) {
|
if (skip + hlen + rlen + padding + alen > maxpacketsize) {
|
||||||
DPRINTF(("esp_output: packet in SA %s/%08lx got too big "
|
DPRINTF(("%s: packet in SA %s/%08lx got too big "
|
||||||
"(len %u, max len %u)\n",
|
"(len %u, max len %u)\n", __func__,
|
||||||
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi),
|
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi),
|
||||||
skip + hlen + rlen + padding + alen, maxpacketsize));
|
skip + hlen + rlen + padding + alen, maxpacketsize));
|
||||||
espstat.esps_toobig++;
|
espstat.esps_toobig++;
|
||||||
@ -716,7 +715,7 @@ esp_output(
|
|||||||
|
|
||||||
m = m_clone(m);
|
m = m_clone(m);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
DPRINTF(("esp_output: cannot clone mbuf chain, SA %s/%08lx\n",
|
DPRINTF(("%s: cannot clone mbuf chain, SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
||||||
espstat.esps_hdrops++;
|
espstat.esps_hdrops++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
@ -726,9 +725,8 @@ esp_output(
|
|||||||
/* Inject ESP header. */
|
/* Inject ESP header. */
|
||||||
mo = m_makespace(m, skip, hlen, &roff);
|
mo = m_makespace(m, skip, hlen, &roff);
|
||||||
if (mo == NULL) {
|
if (mo == NULL) {
|
||||||
DPRINTF(("esp_output: failed to inject %u byte ESP hdr for SA "
|
DPRINTF(("%s: %u byte ESP hdr inject failed for SA %s/%08lx\n",
|
||||||
"%s/%08lx\n",
|
__func__, hlen, ipsec_address(&saidx->dst),
|
||||||
hlen, ipsec_address(&saidx->dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
espstat.esps_hdrops++; /* XXX diffs from openbsd */
|
espstat.esps_hdrops++; /* XXX diffs from openbsd */
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
@ -750,7 +748,7 @@ esp_output(
|
|||||||
*/
|
*/
|
||||||
pad = (u_char *) m_pad(m, padding + alen);
|
pad = (u_char *) m_pad(m, padding + alen);
|
||||||
if (pad == NULL) {
|
if (pad == NULL) {
|
||||||
DPRINTF(("esp_output: m_pad failed for SA %s/%08lx\n",
|
DPRINTF(("%s: m_pad failed for SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
|
||||||
m = NULL; /* NB: free'd by m_pad */
|
m = NULL; /* NB: free'd by m_pad */
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
@ -785,7 +783,8 @@ esp_output(
|
|||||||
/* Get crypto descriptors. */
|
/* Get crypto descriptors. */
|
||||||
crp = crypto_getreq(esph && espx ? 2 : 1);
|
crp = crypto_getreq(esph && espx ? 2 : 1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
DPRINTF(("esp_output: failed to acquire crypto descriptors\n"));
|
DPRINTF(("%s: failed to acquire crypto descriptors\n",
|
||||||
|
__func__));
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -814,7 +813,7 @@ esp_output(
|
|||||||
M_XDATA, M_NOWAIT|M_ZERO);
|
M_XDATA, M_NOWAIT|M_ZERO);
|
||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
DPRINTF(("esp_output: failed to allocate tdb_crypto\n"));
|
DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -866,22 +865,22 @@ esp_output_cb(struct cryptop *crp)
|
|||||||
int err, error;
|
int err, error;
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("esp_output_cb: null opaque data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
|
||||||
m = (struct mbuf *) crp->crp_buf;
|
m = (struct mbuf *) crp->crp_buf;
|
||||||
|
|
||||||
isr = tc->tc_isr;
|
isr = tc->tc_isr;
|
||||||
mtx_lock(&isr->lock);
|
IPSECREQUEST_LOCK(isr);
|
||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
espstat.esps_notdb++;
|
espstat.esps_notdb++;
|
||||||
DPRINTF(("esp_output_cb: SA expired while in crypto "
|
DPRINTF(("%s: SA gone during crypto (SA %s/%08lx proto %u)\n",
|
||||||
"(SA %s/%08lx proto %u)\n", ipsec_address(&tc->tc_dst),
|
__func__, ipsec_address(&tc->tc_dst),
|
||||||
(u_long) ntohl(tc->tc_spi), tc->tc_proto));
|
(u_long) ntohl(tc->tc_spi), tc->tc_proto));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
KASSERT(isr->sav == sav,
|
IPSEC_ASSERT(isr->sav == sav,
|
||||||
("esp_output_cb: SA changed was %p now %p\n", isr->sav, sav));
|
("SA changed was %p now %p\n", isr->sav, sav));
|
||||||
|
|
||||||
/* Check for crypto errors. */
|
/* Check for crypto errors. */
|
||||||
if (crp->crp_etype) {
|
if (crp->crp_etype) {
|
||||||
@ -891,12 +890,12 @@ esp_output_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
if (crp->crp_etype == EAGAIN) {
|
if (crp->crp_etype == EAGAIN) {
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
return crypto_dispatch(crp);
|
return crypto_dispatch(crp);
|
||||||
}
|
}
|
||||||
|
|
||||||
espstat.esps_noxform++;
|
espstat.esps_noxform++;
|
||||||
DPRINTF(("esp_output_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -904,7 +903,7 @@ esp_output_cb(struct cryptop *crp)
|
|||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
espstat.esps_crypto++;
|
espstat.esps_crypto++;
|
||||||
DPRINTF(("esp_output_cb: bogus returned buffer from crypto\n"));
|
DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -919,13 +918,13 @@ esp_output_cb(struct cryptop *crp)
|
|||||||
/* NB: m is reclaimed by ipsec_process_done. */
|
/* NB: m is reclaimed by ipsec_process_done. */
|
||||||
err = ipsec_process_done(m, isr);
|
err = ipsec_process_done(m, isr);
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
bad:
|
bad:
|
||||||
if (sav)
|
if (sav)
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
if (m)
|
if (m)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
free(tc, M_XDATA);
|
free(tc, M_XDATA);
|
||||||
|
@ -102,7 +102,7 @@ ipcomp_init(struct secasvar *sav, struct xformsw *xsp)
|
|||||||
/* NB: algorithm really comes in alg_enc and not alg_comp! */
|
/* NB: algorithm really comes in alg_enc and not alg_comp! */
|
||||||
tcomp = ipcomp_algorithm_lookup(sav->alg_enc);
|
tcomp = ipcomp_algorithm_lookup(sav->alg_enc);
|
||||||
if (tcomp == NULL) {
|
if (tcomp == NULL) {
|
||||||
DPRINTF(("ipcomp_init: unsupported compression algorithm %d\n",
|
DPRINTF(("%s: unsupported compression algorithm %d\n", __func__,
|
||||||
sav->alg_comp));
|
sav->alg_comp));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@ -141,15 +141,13 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
struct cryptop *crp;
|
struct cryptop *crp;
|
||||||
int hlen = IPCOMP_HLENGTH;
|
int hlen = IPCOMP_HLENGTH;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipcomp_input");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get crypto descriptors */
|
/* Get crypto descriptors */
|
||||||
crp = crypto_getreq(1);
|
crp = crypto_getreq(1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
DPRINTF(("ipcomp_input: no crypto descriptors\n"));
|
DPRINTF(("%s: no crypto descriptors\n", __func__));
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
@ -158,7 +156,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
|||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
DPRINTF(("ipcomp_input: cannot allocate tdb_crypto\n"));
|
DPRINTF(("%s: cannot allocate tdb_crypto\n", __func__));
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
return ENOBUFS;
|
return ENOBUFS;
|
||||||
}
|
}
|
||||||
@ -224,7 +222,7 @@ ipcomp_input_cb(struct cryptop *crp)
|
|||||||
crd = crp->crp_desc;
|
crd = crp->crp_desc;
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("ipcomp_input_cb: null opaque crypto data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque crypto data area!"));
|
||||||
skip = tc->tc_skip;
|
skip = tc->tc_skip;
|
||||||
protoff = tc->tc_protoff;
|
protoff = tc->tc_protoff;
|
||||||
mtag = (struct mtag *) tc->tc_ptr;
|
mtag = (struct mtag *) tc->tc_ptr;
|
||||||
@ -233,16 +231,15 @@ ipcomp_input_cb(struct cryptop *crp)
|
|||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
ipcompstat.ipcomps_notdb++;
|
ipcompstat.ipcomps_notdb++;
|
||||||
DPRINTF(("ipcomp_input_cb: SA expired while in crypto\n"));
|
DPRINTF(("%s: SA expired while in crypto\n", __func__));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
saidx = &sav->sah->saidx;
|
saidx = &sav->sah->saidx;
|
||||||
KASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
|
||||||
saidx->dst.sa.sa_family == AF_INET6,
|
saidx->dst.sa.sa_family == AF_INET6,
|
||||||
("ah_input_cb: unexpected protocol family %u",
|
("unexpected protocol family %u", saidx->dst.sa.sa_family));
|
||||||
saidx->dst.sa.sa_family));
|
|
||||||
|
|
||||||
/* Check for crypto errors */
|
/* Check for crypto errors */
|
||||||
if (crp->crp_etype) {
|
if (crp->crp_etype) {
|
||||||
@ -256,14 +253,14 @@ ipcomp_input_cb(struct cryptop *crp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipcompstat.ipcomps_noxform++;
|
ipcompstat.ipcomps_noxform++;
|
||||||
DPRINTF(("ipcomp_input_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
DPRINTF(("ipcomp_input_cb: null mbuf returned from crypto\n"));
|
DPRINTF(("%s: null mbuf returned from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -280,7 +277,7 @@ ipcomp_input_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == 0) {
|
if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == 0) {
|
||||||
ipcompstat.ipcomps_hdrops++; /*XXX*/
|
ipcompstat.ipcomps_hdrops++; /*XXX*/
|
||||||
DPRINTF(("ipcomp_input_cb: m_pullup failed\n"));
|
DPRINTF(("%s: m_pullup failed\n", __func__));
|
||||||
error = EINVAL; /*XXX*/
|
error = EINVAL; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -293,7 +290,7 @@ ipcomp_input_cb(struct cryptop *crp)
|
|||||||
error = m_striphdr(m, skip, hlen);
|
error = m_striphdr(m, skip, hlen);
|
||||||
if (error) {
|
if (error) {
|
||||||
ipcompstat.ipcomps_hdrops++;
|
ipcompstat.ipcomps_hdrops++;
|
||||||
DPRINTF(("ipcomp_input_cb: bad mbuf chain, IPCA %s/%08lx\n",
|
DPRINTF(("%s: bad mbuf chain, IPCA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -340,14 +337,12 @@ ipcomp_output(
|
|||||||
struct mbuf *mo;
|
struct mbuf *mo;
|
||||||
struct ipcomp *ipcomp;
|
struct ipcomp *ipcomp;
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipcomp_output");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
KASSERT(sav != NULL, ("ipcomp_output: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
ipcompx = sav->tdb_compalgxform;
|
ipcompx = sav->tdb_compalgxform;
|
||||||
KASSERT(ipcompx != NULL, ("ipcomp_output: null compression xform"));
|
IPSEC_ASSERT(ipcompx != NULL, ("null compression xform"));
|
||||||
|
|
||||||
ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */
|
ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */
|
||||||
hlen = IPCOMP_HLENGTH;
|
hlen = IPCOMP_HLENGTH;
|
||||||
@ -368,8 +363,8 @@ ipcomp_output(
|
|||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
ipcompstat.ipcomps_nopf++;
|
ipcompstat.ipcomps_nopf++;
|
||||||
DPRINTF(("ipcomp_output: unknown/unsupported protocol family %d"
|
DPRINTF(("%s: unknown/unsupported protocol family %d, "
|
||||||
", IPCA %s/%08lx\n",
|
"IPCA %s/%08lx\n", __func__,
|
||||||
sav->sah->saidx.dst.sa.sa_family,
|
sav->sah->saidx.dst.sa.sa_family,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -378,8 +373,8 @@ ipcomp_output(
|
|||||||
}
|
}
|
||||||
if (skip + hlen + ralen > maxpacketsize) {
|
if (skip + hlen + ralen > maxpacketsize) {
|
||||||
ipcompstat.ipcomps_toobig++;
|
ipcompstat.ipcomps_toobig++;
|
||||||
DPRINTF(("ipcomp_output: packet in IPCA %s/%08lx got too big "
|
DPRINTF(("%s: packet in IPCA %s/%08lx got too big "
|
||||||
"(len %u, max len %u)\n",
|
"(len %u, max len %u)\n", __func__,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi),
|
(u_long) ntohl(sav->spi),
|
||||||
skip + hlen + ralen, maxpacketsize));
|
skip + hlen + ralen, maxpacketsize));
|
||||||
@ -393,8 +388,8 @@ ipcomp_output(
|
|||||||
m = m_clone(m);
|
m = m_clone(m);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
ipcompstat.ipcomps_hdrops++;
|
ipcompstat.ipcomps_hdrops++;
|
||||||
DPRINTF(("ipcomp_output: cannot clone mbuf chain, IPCA %s/%08lx\n",
|
DPRINTF(("%s: cannot clone mbuf chain, IPCA %s/%08lx\n",
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -404,9 +399,8 @@ ipcomp_output(
|
|||||||
mo = m_makespace(m, skip, hlen, &roff);
|
mo = m_makespace(m, skip, hlen, &roff);
|
||||||
if (mo == NULL) {
|
if (mo == NULL) {
|
||||||
ipcompstat.ipcomps_wrap++;
|
ipcompstat.ipcomps_wrap++;
|
||||||
DPRINTF(("ipcomp_output: failed to inject IPCOMP header for "
|
DPRINTF(("%s: IPCOMP header inject failed for IPCA %s/%08lx\n",
|
||||||
"IPCA %s/%08lx\n",
|
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -440,7 +434,7 @@ ipcomp_output(
|
|||||||
crp = crypto_getreq(1);
|
crp = crypto_getreq(1);
|
||||||
if (crp == NULL) {
|
if (crp == NULL) {
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
DPRINTF(("ipcomp_output: failed to acquire crypto descriptor\n"));
|
DPRINTF(("%s: failed to acquire crypto descriptor\n",__func__));
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -460,7 +454,7 @@ ipcomp_output(
|
|||||||
M_XDATA, M_NOWAIT|M_ZERO);
|
M_XDATA, M_NOWAIT|M_ZERO);
|
||||||
if (tc == NULL) {
|
if (tc == NULL) {
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
DPRINTF(("ipcomp_output: failed to allocate tdb_crypto\n"));
|
DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
|
||||||
crypto_freereq(crp);
|
crypto_freereq(crp);
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -500,21 +494,21 @@ ipcomp_output_cb(struct cryptop *crp)
|
|||||||
int error, skip, rlen;
|
int error, skip, rlen;
|
||||||
|
|
||||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||||
KASSERT(tc != NULL, ("ipcomp_output_cb: null opaque data area!"));
|
IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
|
||||||
m = (struct mbuf *) crp->crp_buf;
|
m = (struct mbuf *) crp->crp_buf;
|
||||||
skip = tc->tc_skip;
|
skip = tc->tc_skip;
|
||||||
rlen = crp->crp_ilen - skip;
|
rlen = crp->crp_ilen - skip;
|
||||||
|
|
||||||
isr = tc->tc_isr;
|
isr = tc->tc_isr;
|
||||||
mtx_lock(&isr->lock);
|
IPSECREQUEST_LOCK(isr);
|
||||||
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
|
||||||
if (sav == NULL) {
|
if (sav == NULL) {
|
||||||
ipcompstat.ipcomps_notdb++;
|
ipcompstat.ipcomps_notdb++;
|
||||||
DPRINTF(("ipcomp_output_cb: SA expired while in crypto\n"));
|
DPRINTF(("%s: SA expired while in crypto\n", __func__));
|
||||||
error = ENOBUFS; /*XXX*/
|
error = ENOBUFS; /*XXX*/
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
KASSERT(isr->sav == sav, ("ipcomp_output_cb: SA changed\n"));
|
IPSEC_ASSERT(isr->sav == sav, ("SA changed\n"));
|
||||||
|
|
||||||
/* Check for crypto errors */
|
/* Check for crypto errors */
|
||||||
if (crp->crp_etype) {
|
if (crp->crp_etype) {
|
||||||
@ -524,18 +518,18 @@ ipcomp_output_cb(struct cryptop *crp)
|
|||||||
|
|
||||||
if (crp->crp_etype == EAGAIN) {
|
if (crp->crp_etype == EAGAIN) {
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
return crypto_dispatch(crp);
|
return crypto_dispatch(crp);
|
||||||
}
|
}
|
||||||
ipcompstat.ipcomps_noxform++;
|
ipcompstat.ipcomps_noxform++;
|
||||||
DPRINTF(("ipcomp_output_cb: crypto error %d\n", crp->crp_etype));
|
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||||
error = crp->crp_etype;
|
error = crp->crp_etype;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
/* Shouldn't happen... */
|
/* Shouldn't happen... */
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
ipcompstat.ipcomps_crypto++;
|
ipcompstat.ipcomps_crypto++;
|
||||||
DPRINTF(("ipcomp_output_cb: bogus return buffer from crypto\n"));
|
DPRINTF(("%s: bogus return buffer from crypto\n", __func__));
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -557,8 +551,8 @@ ipcomp_output_cb(struct cryptop *crp)
|
|||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
default:
|
default:
|
||||||
ipcompstat.ipcomps_nopf++;
|
ipcompstat.ipcomps_nopf++;
|
||||||
DPRINTF(("ipcomp_output: unknown/unsupported protocol "
|
DPRINTF(("%s: unknown/unsupported protocol "
|
||||||
"family %d, IPCA %s/%08lx\n",
|
"family %d, IPCA %s/%08lx\n", __func__,
|
||||||
sav->sah->saidx.dst.sa.sa_family,
|
sav->sah->saidx.dst.sa.sa_family,
|
||||||
ipsec_address(&sav->sah->saidx.dst),
|
ipsec_address(&sav->sah->saidx.dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
@ -577,13 +571,13 @@ ipcomp_output_cb(struct cryptop *crp)
|
|||||||
/* NB: m is reclaimed by ipsec_process_done. */
|
/* NB: m is reclaimed by ipsec_process_done. */
|
||||||
error = ipsec_process_done(m, isr);
|
error = ipsec_process_done(m, isr);
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
bad:
|
bad:
|
||||||
if (sav)
|
if (sav)
|
||||||
KEY_FREESAV(&sav);
|
KEY_FREESAV(&sav);
|
||||||
mtx_unlock(&isr->lock);
|
IPSECREQUEST_UNLOCK(isr);
|
||||||
if (m)
|
if (m)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
free(tc, M_XDATA);
|
free(tc, M_XDATA);
|
||||||
|
@ -114,7 +114,7 @@ ip4_input6(struct mbuf **m, int *offp, int proto)
|
|||||||
#if 0
|
#if 0
|
||||||
/* If we do not accept IP-in-IP explicitly, drop. */
|
/* If we do not accept IP-in-IP explicitly, drop. */
|
||||||
if (!ipip_allow && ((*m)->m_flags & M_IPSEC) == 0) {
|
if (!ipip_allow && ((*m)->m_flags & M_IPSEC) == 0) {
|
||||||
DPRINTF(("ip4_input6: dropped due to policy\n"));
|
DPRINTF(("%s: dropped due to policy\n", __func__));
|
||||||
ipipstat.ipips_pdrops++;
|
ipipstat.ipips_pdrops++;
|
||||||
m_freem(*m);
|
m_freem(*m);
|
||||||
return IPPROTO_DONE;
|
return IPPROTO_DONE;
|
||||||
@ -138,7 +138,7 @@ ip4_input(struct mbuf *m, ...)
|
|||||||
#if 0
|
#if 0
|
||||||
/* If we do not accept IP-in-IP explicitly, drop. */
|
/* If we do not accept IP-in-IP explicitly, drop. */
|
||||||
if (!ipip_allow && (m->m_flags & M_IPSEC) == 0) {
|
if (!ipip_allow && (m->m_flags & M_IPSEC) == 0) {
|
||||||
DPRINTF(("ip4_input: dropped due to policy\n"));
|
DPRINTF(("%s: dropped due to policy\n", __func__));
|
||||||
ipipstat.ipips_pdrops++;
|
ipipstat.ipips_pdrops++;
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return;
|
return;
|
||||||
@ -201,7 +201,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
|
|||||||
/* Bring the IP header in the first mbuf, if not there already */
|
/* Bring the IP header in the first mbuf, if not there already */
|
||||||
if (m->m_len < hlen) {
|
if (m->m_len < hlen) {
|
||||||
if ((m = m_pullup(m, hlen)) == NULL) {
|
if ((m = m_pullup(m, hlen)) == NULL) {
|
||||||
DPRINTF(("ipip_input: m_pullup (1) failed\n"));
|
DPRINTF(("%s: m_pullup (1) failed\n", __func__));
|
||||||
ipipstat.ipips_hdrops++;
|
ipipstat.ipips_hdrops++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
|
|||||||
*/
|
*/
|
||||||
if (m->m_len < hlen) {
|
if (m->m_len < hlen) {
|
||||||
if ((m = m_pullup(m, hlen)) == NULL) {
|
if ((m = m_pullup(m, hlen)) == NULL) {
|
||||||
DPRINTF(("ipip_input: m_pullup (2) failed\n"));
|
DPRINTF(("%s: m_pullup (2) failed\n", __func__));
|
||||||
ipipstat.ipips_hdrops++;
|
ipipstat.ipips_hdrops++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -376,12 +376,13 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
panic("ipip_input: should never reach here");
|
panic("%s: bogus ip version %u", __func__, v>>4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!netisr_queue(isr, m)) {
|
if (!netisr_queue(isr, m)) {
|
||||||
ipipstat.ipips_qfull++;
|
ipipstat.ipips_qfull++;
|
||||||
DPRINTF(("ipip_input: packet dropped because of full queue\n"));
|
DPRINTF(("%s: packet dropped because of full queue\n",
|
||||||
|
__func__));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,13 +407,11 @@ ipip_output(
|
|||||||
struct ip6_hdr *ip6, *ip6o;
|
struct ip6_hdr *ip6, *ip6o;
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
|
|
||||||
#if 0
|
IPSEC_SPLASSERT_SOFTNET(__func__);
|
||||||
SPLASSERT(net, "ipip_output");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sav = isr->sav;
|
sav = isr->sav;
|
||||||
KASSERT(sav != NULL, ("ipip_output: null SA"));
|
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||||
KASSERT(sav->sah != NULL, ("ipip_output: null SAH"));
|
IPSEC_ASSERT(sav->sah != NULL, ("null SAH"));
|
||||||
|
|
||||||
/* XXX Deal with empty TDB source/destination addresses. */
|
/* XXX Deal with empty TDB source/destination addresses. */
|
||||||
|
|
||||||
@ -426,8 +425,8 @@ ipip_output(
|
|||||||
if (saidx->src.sa.sa_family != AF_INET ||
|
if (saidx->src.sa.sa_family != AF_INET ||
|
||||||
saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
|
saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
|
||||||
saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) {
|
saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) {
|
||||||
DPRINTF(("ipip_output: unspecified tunnel endpoint "
|
DPRINTF(("%s: unspecified tunnel endpoint "
|
||||||
"address in SA %s/%08lx\n",
|
"address in SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst),
|
ipsec_address(&saidx->dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
ipipstat.ipips_unspec++;
|
ipipstat.ipips_unspec++;
|
||||||
@ -437,7 +436,7 @@ ipip_output(
|
|||||||
|
|
||||||
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
|
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
DPRINTF(("ipip_output: M_PREPEND failed\n"));
|
DPRINTF(("%s: M_PREPEND failed\n", __func__));
|
||||||
ipipstat.ipips_hdrops++;
|
ipipstat.ipips_hdrops++;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
goto bad;
|
goto bad;
|
||||||
@ -507,8 +506,8 @@ ipip_output(
|
|||||||
if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
|
if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
|
||||||
saidx->src.sa.sa_family != AF_INET6 ||
|
saidx->src.sa.sa_family != AF_INET6 ||
|
||||||
IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
|
IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
|
||||||
DPRINTF(("ipip_output: unspecified tunnel endpoint "
|
DPRINTF(("%s: unspecified tunnel endpoint "
|
||||||
"address in SA %s/%08lx\n",
|
"address in SA %s/%08lx\n", __func__,
|
||||||
ipsec_address(&saidx->dst),
|
ipsec_address(&saidx->dst),
|
||||||
(u_long) ntohl(sav->spi)));
|
(u_long) ntohl(sav->spi)));
|
||||||
ipipstat.ipips_unspec++;
|
ipipstat.ipips_unspec++;
|
||||||
@ -525,7 +524,7 @@ ipip_output(
|
|||||||
|
|
||||||
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
|
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
DPRINTF(("ipip_output: M_PREPEND failed\n"));
|
DPRINTF(("%s: M_PREPEND failed\n", __func__));
|
||||||
ipipstat.ipips_hdrops++;
|
ipipstat.ipips_hdrops++;
|
||||||
*mp = NULL;
|
*mp = NULL;
|
||||||
error = ENOBUFS;
|
error = ENOBUFS;
|
||||||
@ -575,7 +574,7 @@ ipip_output(
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
nofamily:
|
nofamily:
|
||||||
DPRINTF(("ipip_output: unsupported protocol family %u\n",
|
DPRINTF(("%s: unsupported protocol family %u\n", __func__,
|
||||||
saidx->dst.sa.sa_family));
|
saidx->dst.sa.sa_family));
|
||||||
ipipstat.ipips_family++;
|
ipipstat.ipips_family++;
|
||||||
error = EAFNOSUPPORT; /* XXX diffs from openbsd */
|
error = EAFNOSUPPORT; /* XXX diffs from openbsd */
|
||||||
@ -634,7 +633,7 @@ static int
|
|||||||
ipe4_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
ipe4_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||||
{
|
{
|
||||||
/* This is a rather serious mistake, so no conditional printing. */
|
/* This is a rather serious mistake, so no conditional printing. */
|
||||||
printf("ipe4_input: should never be called\n");
|
printf("%s: should never be called\n", __func__);
|
||||||
if (m)
|
if (m)
|
||||||
m_freem(m);
|
m_freem(m);
|
||||||
return EOPNOTSUPP;
|
return EOPNOTSUPP;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user