X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..7ee9d059c4eecf68ae4f8b0fb99ae2471eda79af:/bsd/netinet6/ah_input.c diff --git a/bsd/netinet6/ah_input.c b/bsd/netinet6/ah_input.c index e055cd53b..a448295b7 100644 --- a/bsd/netinet6/ah_input.c +++ b/bsd/netinet6/ah_input.c @@ -1,3 +1,31 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ + /* $FreeBSD: src/sys/netinet6/ah_input.c,v 1.1.2.6 2002/04/28 05:40:26 suz Exp $ */ /* $KAME: ah_input.c,v 1.67 2002/01/07 11:39:56 kjc Exp $ */ @@ -48,8 +76,8 @@ #include #include -#include #include +#include #include #include @@ -86,6 +114,9 @@ #define KEYDEBUG(lev,arg) #endif +#include +#include +#include #include @@ -107,9 +138,8 @@ ah4_input(struct mbuf *m, int off) struct secasvar *sav = NULL; u_int16_t nxt; size_t hlen; - int s; size_t stripsiz = 0; - + sa_family_t ifamily; #ifndef PULLDOWN_TEST if (m->m_len < off + sizeof(struct newah)) { @@ -117,7 +147,7 @@ ah4_input(struct mbuf *m, int off) if (!m) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup;" "dropping the packet for simplicity\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } } @@ -130,7 +160,7 @@ ah4_input(struct mbuf *m, int off) if (ah == NULL) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup;" "dropping the packet for simplicity\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } #endif @@ -150,7 +180,7 @@ ah4_input(struct mbuf *m, int off) ipseclog((LOG_WARNING, "IPv4 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_nosa++; + IPSEC_STAT_INCREMENT(ipsecstat.in_nosa); goto fail; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -160,7 +190,7 @@ ah4_input(struct mbuf *m, int off) ipseclog((LOG_DEBUG, "IPv4 AH input: non-mature/dying SA found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + IPSEC_STAT_INCREMENT(ipsecstat.in_badspi); goto fail; } @@ -169,7 +199,7 @@ ah4_input(struct mbuf *m, int off) ipseclog((LOG_DEBUG, "IPv4 AH input: " "unsupported authentication algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + IPSEC_STAT_INCREMENT(ipsecstat.in_badspi); goto fail; } @@ -208,17 +238,17 @@ ah4_input(struct mbuf *m, int off) if (siz1 < siz) { ipseclog((LOG_NOTICE, "sum length too short in IPv4 AH input " "(%lu, should be at least %lu): %s\n", - (u_long)siz1, (u_long)siz, + (u_int32_t)siz1, (u_int32_t)siz, ipsec4_logpacketstr(ip, spi))); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } if ((ah->ah_len << 2) - sizoff != siz1) { ipseclog((LOG_NOTICE, "sum length mismatch in IPv4 AH input " "(%d should be %lu): %s\n", - (ah->ah_len << 2) - sizoff, (u_long)siz1, + (ah->ah_len << 2) - sizoff, (u_int32_t)siz1, ipsec4_logpacketstr(ip, spi))); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } @@ -227,7 +257,7 @@ ah4_input(struct mbuf *m, int off) m = m_pullup(m, off + sizeof(struct ah) + sizoff + siz1); if (!m) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } @@ -239,7 +269,7 @@ ah4_input(struct mbuf *m, int off) sizeof(struct ah) + sizoff + siz1); if (ah == NULL) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } #endif @@ -252,7 +282,7 @@ ah4_input(struct mbuf *m, int off) if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav)) ; /*okey*/ else { - ipsecstat.in_ahreplay++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahreplay); ipseclog((LOG_WARNING, "replay packet in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); @@ -268,7 +298,7 @@ ah4_input(struct mbuf *m, int off) if (!cksum) { ipseclog((LOG_DEBUG, "IPv4 AH input: " "couldn't alloc temporary region for cksum\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } @@ -280,10 +310,10 @@ ah4_input(struct mbuf *m, int off) ip->ip_off = htons(ip->ip_off); if (ah4_calccksum(m, (caddr_t)cksum, siz1, algo, sav)) { FREE(cksum, M_TEMP); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } - ipsecstat.in_ahhist[sav->alg_auth]++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahhist[sav->alg_auth]); /* * flip them back. */ @@ -306,7 +336,7 @@ ah4_input(struct mbuf *m, int off) "checksum mismatch in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); FREE(cksum, M_TEMP); - ipsecstat.in_ahauthfail++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahauthfail); goto fail; } } @@ -333,7 +363,7 @@ ah4_input(struct mbuf *m, int off) if (!m) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup\n")); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } } @@ -359,12 +389,12 @@ ah4_input(struct mbuf *m, int off) ipseclog((LOG_DEBUG, "IPv4 AH input: authentication succeess\n")); #endif - ipsecstat.in_ahauthsucc++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahauthsucc); } else { ipseclog((LOG_WARNING, "authentication failed in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_ahauthfail++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahauthfail); goto fail; } @@ -373,7 +403,7 @@ ah4_input(struct mbuf *m, int off) */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav)) { - ipsecstat.in_ahreplay++; + IPSEC_STAT_INCREMENT(ipsecstat.in_ahreplay); goto fail; } } @@ -386,7 +416,10 @@ ah4_input(struct mbuf *m, int off) /* RFC 2402 */ stripsiz = sizeof(struct newah) + siz1; } - if (ipsec4_tunnel_validate(m, off + stripsiz, nxt, sav)) { + if (ipsec4_tunnel_validate(m, off + stripsiz, nxt, sav, &ifamily)) { + ifaddr_t ifa; + struct sockaddr_storage addr; + /* * strip off all the headers that precedes AH. * IP xx AH IP' payload -> IP' payload @@ -395,13 +428,18 @@ ah4_input(struct mbuf *m, int off) * XXX relationship with gif? */ u_int8_t tos; - + + if (ifamily == AF_INET6) { + ipseclog((LOG_NOTICE, "ipsec tunnel protocol mismatch " + "in IPv4 AH input: %s\n", ipsec_logsastr(sav))); + goto fail; + } tos = ip->ip_tos; m_adj(m, off + stripsiz); if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (!m) { - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } } @@ -413,7 +451,7 @@ ah4_input(struct mbuf *m, int off) ipseclog((LOG_NOTICE, "ipsec tunnel address mismatch " "in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } @@ -444,20 +482,28 @@ ah4_input(struct mbuf *m, int off) key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) { - ipsecstat.in_nomem++; + IPSEC_STAT_INCREMENT(ipsecstat.in_nomem); goto fail; } - s = splimp(); - if (IF_QFULL(&ipintrq)) { - ipsecstat.in_inval++; - splx(s); - goto fail; + if (ip_doscopedroute) { + struct sockaddr_in *ipaddr; + + bzero(&addr, sizeof(addr)); + ipaddr = (__typeof__(ipaddr))&addr; + ipaddr->sin_family = AF_INET; + ipaddr->sin_len = sizeof(*ipaddr); + ipaddr->sin_addr = ip->ip_dst; + + // update the receiving interface address based on the inner address + ifa = ifa_ifwithaddr((struct sockaddr *)&addr); + if (ifa) { + m->m_pkthdr.rcvif = ifa->ifa_ifp; + IFA_REMREF(ifa); + } } - IF_ENQUEUE(&ipintrq, m); - m = NULL; - schednetisr(NETISR_IP); /*can be skipped but to make sure*/ - splx(s); + if (proto_input(PF_INET, m) != 0) + goto fail; nxt = IPPROTO_DONE; } else { /* @@ -506,7 +552,7 @@ ah4_input(struct mbuf *m, int off) if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (m == NULL) { - ipsecstat.in_inval++; + IPSEC_STAT_INCREMENT(ipsecstat.in_inval); goto fail; } } @@ -521,17 +567,21 @@ ah4_input(struct mbuf *m, int off) key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0) { - ipsecstat.in_nomem++; + IPSEC_STAT_INCREMENT(ipsecstat.in_nomem); goto fail; } + DTRACE_IP6(receive, struct mbuf *, m, struct inpcb *, NULL, + struct ip *, ip, struct ifnet *, m->m_pkthdr.rcvif, + struct ip *, ip, struct ip6_hdr *, NULL); + if (nxt != IPPROTO_DONE) { if ((ip_protox[nxt]->pr_flags & PR_LASTHDR) != 0 && ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + IPSEC_STAT_INCREMENT(ipsecstat.in_polvio); goto fail; } - (*ip_protox[nxt]->pr_input)(m, off); + ip_proto_dispatch_in(m, off, nxt, 0); } else m_freem(m); m = NULL; @@ -540,16 +590,16 @@ ah4_input(struct mbuf *m, int off) if (sav) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP ah4_input call free SA:%p\n", sav)); - key_freesav(sav); + key_freesav(sav, KEY_SADB_UNLOCKED); } - ipsecstat.in_success++; + IPSEC_STAT_INCREMENT(ipsecstat.in_success); return; fail: if (sav) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP ah4_input call free SA:%p\n", sav)); - key_freesav(sav); + key_freesav(sav, KEY_SADB_UNLOCKED); } if (m) m_freem(m); @@ -559,10 +609,9 @@ fail: #if INET6 int -ah6_input(mp, offp) - struct mbuf **mp; - int *offp; +ah6_input(struct mbuf **mp, int *offp, int proto) { +#pragma unused(proto) struct mbuf *m = *mp; int off = *offp; struct ip6_hdr *ip6; @@ -574,11 +623,11 @@ ah6_input(mp, offp) u_char *cksum; struct secasvar *sav = NULL; u_int16_t nxt; - int s; size_t stripsiz = 0; + #ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(struct ah), IPPROTO_DONE); + IP6_EXTHDR_CHECK(m, off, sizeof(struct ah), {return IPPROTO_DONE;}); ah = (struct ah *)(mtod(m, caddr_t) + off); #else IP6_EXTHDR_GET(ah, struct ah *, m, off, sizeof(struct newah)); @@ -597,7 +646,7 @@ ah6_input(mp, offp) if (ntohs(ip6->ip6_plen) == 0) { ipseclog((LOG_ERR, "IPv6 AH input: " "AH with IPv6 jumbogram is not supported.\n")); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } @@ -607,7 +656,7 @@ ah6_input(mp, offp) ipseclog((LOG_WARNING, "IPv6 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_nosa++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_nosa); goto fail; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -617,7 +666,7 @@ ah6_input(mp, offp) ipseclog((LOG_DEBUG, "IPv6 AH input: non-mature/dying SA found for spi %u; ", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_badspi); goto fail; } @@ -626,7 +675,7 @@ ah6_input(mp, offp) ipseclog((LOG_DEBUG, "IPv6 AH input: " "unsupported authentication algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_badspi); goto fail; } @@ -648,27 +697,28 @@ ah6_input(mp, offp) if (siz1 < siz) { ipseclog((LOG_NOTICE, "sum length too short in IPv6 AH input " "(%lu, should be at least %lu): %s\n", - (u_long)siz1, (u_long)siz, + (u_int32_t)siz1, (u_int32_t)siz, ipsec6_logpacketstr(ip6, spi))); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } if ((ah->ah_len << 2) - sizoff != siz1) { ipseclog((LOG_NOTICE, "sum length mismatch in IPv6 AH input " "(%d should be %lu): %s\n", - (ah->ah_len << 2) - sizoff, (u_long)siz1, + (ah->ah_len << 2) - sizoff, (u_int32_t)siz1, ipsec6_logpacketstr(ip6, spi))); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } #ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(struct ah) + sizoff + siz1, IPPROTO_DONE); + IP6_EXTHDR_CHECK(m, off, sizeof(struct ah) + sizoff + siz1, + {return IPPROTO_DONE;}); #else IP6_EXTHDR_GET(ah, struct ah *, m, off, sizeof(struct ah) + sizoff + siz1); if (ah == NULL) { ipseclog((LOG_NOTICE, "couldn't pullup gather IPv6 AH checksum part")); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); m = NULL; goto fail; } @@ -682,7 +732,7 @@ ah6_input(mp, offp) if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav)) ; /*okey*/ else { - ipsec6stat.in_ahreplay++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahreplay); ipseclog((LOG_WARNING, "replay packet in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), @@ -699,16 +749,16 @@ ah6_input(mp, offp) if (!cksum) { ipseclog((LOG_DEBUG, "IPv6 AH input: " "couldn't alloc temporary region for cksum\n")); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } if (ah6_calccksum(m, (caddr_t)cksum, siz1, algo, sav)) { FREE(cksum, M_TEMP); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } - ipsec6stat.in_ahhist[sav->alg_auth]++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahhist[sav->alg_auth]); { caddr_t sumpos = NULL; @@ -726,7 +776,7 @@ ah6_input(mp, offp) "checksum mismatch in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); FREE(cksum, M_TEMP); - ipsec6stat.in_ahauthfail++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahauthfail); goto fail; } } @@ -748,7 +798,8 @@ ah6_input(mp, offp) sizoff = (sav->flags & SADB_X_EXT_OLD) ? 0 : 4; IP6_EXTHDR_CHECK(m, off, sizeof(struct ah) + sizoff + siz1 - + sizeof(struct ip6_hdr), IPPROTO_DONE); + + sizeof(struct ip6_hdr), + {return IPPROTO_DONE;}); nip6 = (struct ip6_hdr *)((u_char *)(ah + 1) + sizoff + siz1); if (!IN6_ARE_ADDR_EQUAL(&nip6->ip6_src, &ip6->ip6_src) @@ -771,12 +822,12 @@ ah6_input(mp, offp) ipseclog((LOG_DEBUG, "IPv6 AH input: authentication succeess\n")); #endif - ipsec6stat.in_ahauthsucc++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahauthsucc); } else { ipseclog((LOG_WARNING, "authentication failed in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_ahauthfail++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahauthfail); goto fail; } @@ -785,7 +836,7 @@ ah6_input(mp, offp) */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav)) { - ipsec6stat.in_ahreplay++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_ahreplay); goto fail; } } @@ -799,6 +850,9 @@ ah6_input(mp, offp) stripsiz = sizeof(struct newah) + siz1; } if (ipsec6_tunnel_validate(m, off + stripsiz, nxt, sav)) { + ifaddr_t ifa; + struct sockaddr_storage addr; + /* * strip off all the headers that precedes AH. * IP6 xx AH IP6' payload -> IP6' payload @@ -817,7 +871,7 @@ ah6_input(mp, offp) */ m = m_pullup(m, sizeof(*ip6)); if (!m) { - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } } @@ -830,7 +884,7 @@ ah6_input(mp, offp) "in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_inval++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_inval); goto fail; } @@ -846,20 +900,29 @@ ah6_input(mp, offp) key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) { - ipsec6stat.in_nomem++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_nomem); goto fail; } - s = splimp(); - if (IF_QFULL(&ip6intrq)) { - ipsec6stat.in_inval++; - splx(s); - goto fail; + if (ip6_doscopedroute) { + struct sockaddr_in6 *ip6addr; + + bzero(&addr, sizeof(addr)); + ip6addr = (__typeof__(ip6addr))&addr; + ip6addr->sin6_family = AF_INET6; + ip6addr->sin6_len = sizeof(*ip6addr); + ip6addr->sin6_addr = ip6->ip6_dst; + + // update the receiving interface address based on the inner address + ifa = ifa_ifwithaddr((struct sockaddr *)&addr); + if (ifa) { + m->m_pkthdr.rcvif = ifa->ifa_ifp; + IFA_REMREF(ifa); + } } - IF_ENQUEUE(&ip6intrq, m); - m = NULL; - schednetisr(NETISR_IPV6); /* can be skipped but to make sure */ - splx(s); + + if (proto_input(PF_INET6, m) != 0) + goto fail; nxt = IPPROTO_DONE; } else { /* @@ -919,7 +982,7 @@ ah6_input(mp, offp) key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0) { - ipsec6stat.in_nomem++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_nomem); goto fail; } } @@ -930,16 +993,16 @@ ah6_input(mp, offp) if (sav) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP ah6_input call free SA:%p\n", sav)); - key_freesav(sav); + key_freesav(sav, KEY_SADB_UNLOCKED); } - ipsec6stat.in_success++; + IPSEC_STAT_INCREMENT(ipsec6stat.in_success); return nxt; fail: if (sav) { KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP ah6_input call free SA:%p\n", sav)); - key_freesav(sav); + key_freesav(sav, KEY_SADB_UNLOCKED); } if (m) m_freem(m); @@ -1015,7 +1078,7 @@ ah6_ctlinput(cmd, sa, d) if (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING) valid++; - key_freesav(sav); + key_freesav(sav, KEY_SADB_UNLOCKED); } /* XXX Further validation? */