ipsec4_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
{
struct secpolicy *sp = NULL;
+ struct secpolicyindex spidx;
/* sanity check */
if (m == NULL || error == NULL)
panic("ipsec4_getpolicybyaddr: NULL pointer was passed.");
- {
- struct secpolicyindex spidx;
-
bzero(&spidx, sizeof(spidx));
/* make a index to look for a policy */
*error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET, m,
- (flag & IP_FORWARDING) ? 0 : 1);
+ (flag & IP_FORWARDING) ? 0 : 1);
if (*error != 0)
return NULL;
+ lwkt_gettoken(&key_token);
sp = key_allocsp(&spidx, dir);
- }
/* SP found */
if (sp != NULL) {
kprintf("DP ipsec4_getpolicybyaddr called "
"to allocate SP:%p\n", sp));
*error = 0;
+ lwkt_reltoken(&key_token);
return sp;
}
}
ip4_def_policy.refcnt++;
*error = 0;
+ lwkt_reltoken(&key_token);
return &ip4_def_policy;
}
panic("ipsec6_getpolicybysock: socket domain != inet6");
#endif
+ lwkt_gettoken(&key_token);
+
/* set spidx in pcb */
ipsec6_setspidx_in6pcb(m, so->so_pcb);
-
pcbsp = sotoin6pcb(so)->in6p_sp;
/* sanity check */
case IPSEC_POLICY_BYPASS:
currsp->refcnt++;
*error = 0;
- return currsp;
-
+ break;
case IPSEC_POLICY_ENTRUST:
/* look for a policy in SPD */
kernsp = key_allocsp(&currsp->spidx, dir);
kprintf("DP ipsec6_getpolicybysock called "
"to allocate SP:%p\n", kernsp));
*error = 0;
- return kernsp;
+ currsp = kernsp;
+ break;
}
/* no SP found */
ip6_def_policy.policy, IPSEC_POLICY_NONE));
ip6_def_policy.policy = IPSEC_POLICY_NONE;
}
- ip6_def_policy.refcnt++;
+ currsp = &ip6_def_policy;
+ currsp->refcnt++;
*error = 0;
- return &ip6_def_policy;
-
+ break;
case IPSEC_POLICY_IPSEC:
currsp->refcnt++;
*error = 0;
- return currsp;
-
+ break;
default:
ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
"Invalid policy for PCB %d\n", currsp->policy));
*error = EINVAL;
- return NULL;
+ lwkt_reltoken(&key_token);
+ currsp = NULL;
+ break;
}
+ lwkt_reltoken(&key_token);
+ return currsp;
/* NOTREACHED */
}
kprintf("DP ipsec6_getpolicybysock called "
"to allocate SP:%p\n", kernsp));
*error = 0;
+ lwkt_reltoken(&key_token);
return kernsp;
}
"Illegal policy for non-priviliged defined %d\n",
currsp->policy));
*error = EINVAL;
- return NULL;
-
+ currsp = NULL;
+ break;
case IPSEC_POLICY_ENTRUST:
if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
&& ip6_def_policy.policy != IPSEC_POLICY_NONE) {
ip6_def_policy.policy, IPSEC_POLICY_NONE));
ip6_def_policy.policy = IPSEC_POLICY_NONE;
}
- ip6_def_policy.refcnt++;
+ currsp = &ip6_def_policy;
+ currsp->refcnt++;
*error = 0;
- return &ip6_def_policy;
-
+ break;
case IPSEC_POLICY_IPSEC:
currsp->refcnt++;
*error = 0;
- return currsp;
-
+ break;
default:
ipseclog((LOG_ERR,
"ipsec6_policybysock: Invalid policy for PCB %d\n",
currsp->policy));
*error = EINVAL;
- return NULL;
+ currsp = NULL;
+ break;
}
- /* NOTREACHED */
+ lwkt_reltoken(&key_token);
+ return currsp;
}
/*
ipsec6_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
{
struct secpolicy *sp = NULL;
+ struct secpolicyindex spidx;
/* sanity check */
if (m == NULL || error == NULL)
panic("ipsec6_getpolicybyaddr: NULL pointer was passed.");
-
- {
- struct secpolicyindex spidx;
-
bzero(&spidx, sizeof(spidx));
+ lwkt_gettoken(&key_token);
+
/* make a index to look for a policy */
*error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET6, m,
- (flag & IP_FORWARDING) ? 0 : 1);
-
- if (*error != 0)
+ (flag & IP_FORWARDING) ? 0 : 1);
+ if (*error != 0) {
+ lwkt_reltoken(&key_token);
return NULL;
+ }
sp = key_allocsp(&spidx, dir);
- }
/* SP found */
if (sp != NULL) {
kprintf("DP ipsec6_getpolicybyaddr called "
"to allocate SP:%p\n", sp));
*error = 0;
+ lwkt_reltoken(&key_token);
return sp;
}
ip6_def_policy.policy, IPSEC_POLICY_NONE));
ip6_def_policy.policy = IPSEC_POLICY_NONE;
}
- ip6_def_policy.refcnt++;
+ sp = &ip6_def_policy;
+ sp->refcnt++;
*error = 0;
- return &ip6_def_policy;
+ lwkt_reltoken(&key_token);
+
+ return sp;
}
#endif /* INET6 */
if (so == NULL || pcb_sp == NULL)
panic("ipsec_init_policy: NULL pointer was passed.");
+ lwkt_gettoken(&key_token);
+
new = ipsec_newpcbpolicy();
if (new == NULL) {
ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
+ lwkt_reltoken(&key_token);
return ENOBUFS;
}
bzero(new, sizeof(*new));
if ((new->sp_in = key_newsp()) == NULL) {
ipsec_delpcbpolicy(new);
+ lwkt_reltoken(&key_token);
return ENOBUFS;
}
new->sp_in->state = IPSEC_SPSTATE_ALIVE;
if ((new->sp_out = key_newsp()) == NULL) {
key_freesp(new->sp_in);
ipsec_delpcbpolicy(new);
+ lwkt_reltoken(&key_token);
return ENOBUFS;
}
new->sp_out->state = IPSEC_SPSTATE_ALIVE;
new->sp_out->policy = IPSEC_POLICY_ENTRUST;
*pcb_sp = new;
+ lwkt_reltoken(&key_token);
return 0;
}
{
struct secpolicy *sp;
+ lwkt_gettoken(&key_token);
sp = ipsec_deepcopy_policy(old->sp_in);
if (sp) {
key_freesp(new->sp_in);
new->sp_in = sp;
- } else
+ } else {
+ lwkt_reltoken(&key_token);
return ENOBUFS;
+ }
sp = ipsec_deepcopy_policy(old->sp_out);
if (sp) {
key_freesp(new->sp_out);
new->sp_out = sp;
- } else
+ } else {
+ lwkt_reltoken(&key_token);
return ENOBUFS;
+ }
new->priv = old->priv;
+ lwkt_reltoken(&key_token);
return 0;
}
struct ipsecrequest *r;
struct secpolicy *dst;
+ lwkt_gettoken(&key_token);
dst = key_newsp();
- if (src == NULL || dst == NULL)
+ if (src == NULL || dst == NULL) {
+ lwkt_reltoken(&key_token);
return NULL;
+ }
/*
* deep-copy IPsec request chain. This is required since struct
dst->state = src->state;
dst->policy = src->policy;
/* do not touch the refcnt fields */
+ lwkt_reltoken(&key_token);
return dst;
fail:
+ lwkt_reltoken(&key_token);
for (p = newchain; p; p = r) {
r = p->next;
kfree(p, M_SECA);
{
struct sadb_x_policy *xpl;
struct secpolicy **pcb_sp;
+ int error;
/* sanity check. */
if (inp == NULL || request == NULL)
return EINVAL;
xpl = (struct sadb_x_policy *)request;
+ lwkt_gettoken(&key_token);
/* select direction */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
default:
ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
xpl->sadb_x_policy_dir));
+ lwkt_reltoken(&key_token);
return EINVAL;
}
-
- return ipsec_set_policy(pcb_sp, optname, request, len, priv);
+ error = ipsec_set_policy(pcb_sp, optname, request, len, priv);
+ lwkt_reltoken(&key_token);
+ return error;
}
int
{
struct sadb_x_policy *xpl;
struct secpolicy *pcb_sp;
+ int error;
/* sanity check. */
if (inp == NULL || request == NULL || mp == NULL)
return EINVAL;
xpl = (struct sadb_x_policy *)request;
+ lwkt_gettoken(&key_token);
+
/* select direction */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
default:
ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
xpl->sadb_x_policy_dir));
+ lwkt_reltoken(&key_token);
return EINVAL;
}
-
- return ipsec_get_policy(pcb_sp, mp);
+ error = ipsec_get_policy(pcb_sp, mp);
+ lwkt_reltoken(&key_token);
+ return error;
}
/* delete policy in PCB */
int
ipsec4_delete_pcbpolicy(struct inpcb *inp)
{
+ struct inpcbpolicy *isp;
+
/* sanity check. */
if (inp == NULL)
panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.");
- if (inp->inp_sp == NULL)
- return 0;
+ lwkt_gettoken(&key_token);
- if (inp->inp_sp->sp_in != NULL) {
- key_freesp(inp->inp_sp->sp_in);
- inp->inp_sp->sp_in = NULL;
+ if ((isp = inp->inp_sp) == NULL) {
+ lwkt_reltoken(&key_token);
+ return 0;
}
- if (inp->inp_sp->sp_out != NULL) {
- key_freesp(inp->inp_sp->sp_out);
- inp->inp_sp->sp_out = NULL;
+ if (isp->sp_in != NULL) {
+ key_freesp(isp->sp_in);
+ isp->sp_in = NULL;
}
- ipsec_delpcbpolicy(inp->inp_sp);
+ if (isp->sp_out != NULL) {
+ key_freesp(isp->sp_out);
+ isp->sp_out = NULL;
+ }
+ KKASSERT(inp->inp_sp == isp);
inp->inp_sp = NULL;
+ ipsec_delpcbpolicy(isp);
+ lwkt_reltoken(&key_token);
return 0;
}
{
struct sadb_x_policy *xpl;
struct secpolicy **pcb_sp;
+ int error;
/* sanity check. */
if (in6p == NULL || request == NULL)
return EINVAL;
xpl = (struct sadb_x_policy *)request;
+ lwkt_gettoken(&key_token);
+
/* select direction */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
default:
ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
xpl->sadb_x_policy_dir));
+ lwkt_reltoken(&key_token);
return EINVAL;
}
- return ipsec_set_policy(pcb_sp, optname, request, len, priv);
+ error = ipsec_set_policy(pcb_sp, optname, request, len, priv);
+ lwkt_reltoken(&key_token);
+ return error;
}
int
{
struct sadb_x_policy *xpl;
struct secpolicy *pcb_sp;
+ int error;
/* sanity check. */
if (in6p == NULL || request == NULL || mp == NULL)
return EINVAL;
xpl = (struct sadb_x_policy *)request;
+ lwkt_gettoken(&key_token);
+
/* select direction */
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_INBOUND:
default:
ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
xpl->sadb_x_policy_dir));
+ lwkt_reltoken(&key_token);
return EINVAL;
}
- return ipsec_get_policy(pcb_sp, mp);
+ error = ipsec_get_policy(pcb_sp, mp);
+ lwkt_reltoken(&key_token);
+ return error;
}
int
ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
{
+ struct inpcbpolicy *isp;
+
/* sanity check. */
if (in6p == NULL)
panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.");
- if (in6p->in6p_sp == NULL)
- return 0;
+ lwkt_gettoken(&key_token);
- if (in6p->in6p_sp->sp_in != NULL) {
- key_freesp(in6p->in6p_sp->sp_in);
- in6p->in6p_sp->sp_in = NULL;
+ if ((isp = in6p->in6p_sp) == NULL) {
+ lwkt_reltoken(&key_token);
+ return 0;
}
- if (in6p->in6p_sp->sp_out != NULL) {
- key_freesp(in6p->in6p_sp->sp_out);
- in6p->in6p_sp->sp_out = NULL;
+ if (isp->sp_in != NULL) {
+ key_freesp(isp->sp_in);
+ isp->sp_in = NULL;
}
- ipsec_delpcbpolicy(in6p->in6p_sp);
+ if (isp->sp_out != NULL) {
+ key_freesp(isp->sp_out);
+ isp->sp_out = NULL;
+ }
+ KKASSERT(in6p->in6p_sp == isp);
in6p->in6p_sp = NULL;
+ ipsec_delpcbpolicy(isp);
+ lwkt_reltoken(&key_token);
return 0;
}
* When we are called from ip_forward(), we call
* ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
*/
+ lwkt_gettoken(&key_token);
if (so == NULL)
sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
else
sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
- if (sp == NULL)
- return 0; /* XXX should be panic ?
- * -> No, there may be error. */
+ if (sp == NULL) {
+ lwkt_reltoken(&key_token);
+ return 0;
+ }
result = ipsec_in_reject(sp, m);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
kprintf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
key_freesp(sp);
+ lwkt_reltoken(&key_token);
return result;
}
* When we are called from ip_forward(), we call
* ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
*/
+ lwkt_gettoken(&key_token);
if (so == NULL)
sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
else
sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
- if (sp == NULL)
+ if (sp == NULL) {
+ lwkt_reltoken(&key_token);
return 0; /* XXX should be panic ? */
+ }
result = ipsec_in_reject(sp, m);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
kprintf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
key_freesp(sp);
+ lwkt_reltoken(&key_token);
return result;
}
* When we are called from ip_forward(), we call
* ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
*/
+ lwkt_gettoken(&key_token);
if (inp == NULL)
sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
else
sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
- if (sp == NULL)
+ if (sp == NULL) {
+ lwkt_reltoken(&key_token);
return 0; /* XXX should be panic ? */
+ }
size = ipsec_hdrsiz(sp);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
kprintf("ipsec4_hdrsiz: size:%lu.\n", (unsigned long)size));
key_freesp(sp);
+ lwkt_reltoken(&key_token);
return size;
}
/* get SP for this packet */
/* XXX Is it right to call with IP_FORWARDING. */
+ lwkt_gettoken(&key_token);
if (in6p == NULL)
sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
else
sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
- if (sp == NULL)
+ if (sp == NULL) {
+ lwkt_reltoken(&key_token);
return 0;
+ }
size = ipsec_hdrsiz(sp);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
kprintf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
kprintf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
key_freesp(sp);
+ lwkt_reltoken(&key_token);
return size;
}
kprintf("ipsec6_output_trans: applyed SP\n");
kdebug_secpolicy(sp));
+ lwkt_gettoken(&key_token);
+
*tun = 0;
for (isr = sp->req; isr; isr = isr->next) {
if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
/* if we have more to go, we need a tunnel mode processing */
if (isr != NULL)
*tun = 1;
-
+ lwkt_reltoken(&key_token);
return 0;
bad:
+ lwkt_reltoken(&key_token);
m_freem(state->m);
state->m = NULL;
return error;
* transport mode ipsec (before the 1st tunnel mode) is already
* processed by ipsec6_output_trans().
*/
+ lwkt_gettoken(&key_token);
for (isr = sp->req; isr; isr = isr->next) {
if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
break;
ip6 = mtod(state->m, struct ip6_hdr *);
ip6->ip6_plen = htons(plen);
}
+ lwkt_reltoken(&key_token);
return 0;
bad:
+ lwkt_reltoken(&key_token);
m_freem(state->m);
state->m = NULL;
return error;
* therefore, we do not do anything special about inner source.
*/
+ lwkt_gettoken(&key_token);
sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
- (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
- if (!sp)
+ (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
+ if (sp) {
+ key_freesp(sp);
+ lwkt_reltoken(&key_token);
+ return 1;
+ } else{
+ lwkt_reltoken(&key_token);
return 0;
- key_freesp(sp);
-
- return 1;
+ }
}
#ifdef INET6
* in ipsec4_tunnel_validate.
*/
+ lwkt_gettoken(&key_token);
sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
- (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
+ (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
/*
* when there is no suitable inbound policy for the packet of the ipsec
* tunnel mode, the kernel never decapsulate the tunneled packet
* packet. if there is no rule of the generic tunnel, the packet
* is rejected and the statistics will be counted up.
*/
- if (!sp)
+ if (sp) {
+ key_freesp(sp);
+ lwkt_reltoken(&key_token);
+ return 1;
+ } else {
+ lwkt_reltoken(&key_token);
return 0;
- key_freesp(sp);
-
- return 1;
+ }
}
#endif