root/net/pfkeyv2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pfdatatopacket
  2. pfkeyv2_create
  3. pfkeyv2_release
  4. pfkeyv2_sendmessage
  5. pfkeyv2_policy
  6. pfkeyv2_get
  7. pfkeyv2_dump_walker
  8. pfkeyv2_flush_walker
  9. pfkeyv2_get_proto_alg
  10. pfkeyv2_send
  11. pfkeyv2_acquire
  12. pfkeyv2_expire
  13. pfkeyv2_sysctl_walker
  14. pfkeyv2_dump_policy
  15. pfkeyv2_ipo_walk
  16. pfkeyv2_sysctl_policydumper
  17. pfkeyv2_sysctl
  18. pfkeyv2_init
  19. pfkeyv2_cleanup

    1 /* $OpenBSD: pfkeyv2.c,v 1.115 2007/06/22 12:14:05 markus Exp $ */
    2 
    3 /*
    4  *      @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
    5  * 
    6  * NRL grants permission for redistribution and use in source and binary
    7  * forms, with or without modification, of the software and documentation
    8  * created at NRL provided that the following conditions are met:
    9  * 
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgements:
   17  *      This product includes software developed by the University of
   18  *      California, Berkeley and its contributors.
   19  *      This product includes software developed at the Information
   20  *      Technology Division, US Naval Research Laboratory.
   21  * 4. Neither the name of the NRL nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  * 
   25  * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
   26  * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   28  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
   29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   32  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   33  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   34  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   35  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   36  * 
   37  * The views and conclusions contained in the software and documentation
   38  * are those of the authors and should not be interpreted as representing
   39  * official policies, either expressed or implied, of the US Naval
   40  * Research Laboratory (NRL).
   41  */
   42 
   43 /*
   44  * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved.
   45  *
   46  * Redistribution and use in source and binary forms, with or without
   47  * modification, are permitted provided that the following conditions
   48  * are met:
   49  * 1. Redistributions of source code must retain the above copyright
   50  *    notice, this list of conditions and the following disclaimer.
   51  * 2. Redistributions in binary form must reproduce the above copyright
   52  *    notice, this list of conditions and the following disclaimer in the
   53  *    documentation and/or other materials provided with the distribution.
   54  * 3. Neither the name of the author nor the names of any contributors
   55  *    may be used to endorse or promote products derived from this software
   56  *    without specific prior written permission.
   57  *
   58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   68  * SUCH DAMAGE.
   69  */
   70 
   71 #include "pf.h"
   72 
   73 #include <sys/types.h>
   74 #include <sys/param.h>
   75 #include <sys/socket.h>
   76 #include <sys/systm.h>
   77 #include <sys/mbuf.h>
   78 #include <sys/kernel.h>
   79 #include <sys/proc.h>
   80 #include <net/route.h>
   81 #include <netinet/ip_ipsp.h>
   82 #include <net/pfkeyv2.h>
   83 #include <netinet/ip_ah.h>
   84 #include <netinet/ip_esp.h>
   85 #include <netinet/ip_ipcomp.h>
   86 #include <crypto/blf.h>
   87 
   88 #if NPF > 0
   89 #include <net/if.h>
   90 #include <net/pfvar.h>
   91 #endif
   92 
   93 #define PFKEYV2_PROTOCOL 2
   94 #define GETSPI_TRIES 10
   95 
   96 /* Static globals */
   97 static struct pfkeyv2_socket *pfkeyv2_sockets = NULL;
   98 static struct pfkey_version pfkeyv2_version;
   99 static uint32_t pfkeyv2_seq = 1;
  100 static int nregistered = 0;
  101 static int npromisc = 0;
  102 
  103 static const struct sadb_alg ealgs[] = {
  104         { SADB_EALG_NULL, 0, 0, 0 },
  105         { SADB_EALG_DESCBC, 64, 64, 64 },
  106         { SADB_EALG_3DESCBC, 64, 192, 192 },
  107         { SADB_X_EALG_BLF, 64, 40, BLF_MAXKEYLEN * 8},
  108         { SADB_X_EALG_CAST, 64, 40, 128},
  109         { SADB_X_EALG_SKIPJACK, 64, 80, 80},
  110         { SADB_X_EALG_AES, 128, 128, 256},
  111         { SADB_X_EALG_AESCTR, 128, 128 + 32, 256 + 32}
  112 };
  113 
  114 static const struct sadb_alg aalgs[] = {
  115         { SADB_AALG_SHA1HMAC, 0, 160, 160 },
  116         { SADB_AALG_MD5HMAC, 0, 128, 128 },
  117         { SADB_X_AALG_RIPEMD160HMAC, 0, 160, 160 },
  118         { SADB_X_AALG_SHA2_256, 0, 256, 256 },
  119         { SADB_X_AALG_SHA2_384, 0, 384, 384 },
  120         { SADB_X_AALG_SHA2_512, 0, 512, 512 }
  121 };
  122 
  123 static const struct sadb_alg calgs[] = {
  124         { SADB_X_CALG_DEFLATE, 0, 0, 0},
  125         { SADB_X_CALG_LZS, 0, 0, 0}
  126 };
  127 
  128 extern uint64_t sadb_exts_allowed_out[SADB_MAX+1];
  129 extern uint64_t sadb_exts_required_out[SADB_MAX+1];
  130 
  131 extern struct pool ipsec_policy_pool;
  132 
  133 /*
  134  * Wrapper around m_devget(); copy data from contiguous buffer to mbuf
  135  * chain.
  136  */
  137 int
  138 pfdatatopacket(void *data, int len, struct mbuf **packet)
  139 {
  140         if (!(*packet = m_devget(data, len, 0, NULL, NULL)))
  141                 return (ENOMEM);
  142         return (0);
  143 }
  144 
  145 /*
  146  * Create a new PF_KEYv2 socket.
  147  */
  148 int
  149 pfkeyv2_create(struct socket *socket)
  150 {
  151         struct pfkeyv2_socket *pfkeyv2_socket;
  152 
  153         if (!(pfkeyv2_socket = malloc(sizeof(struct pfkeyv2_socket),
  154             M_PFKEY, M_DONTWAIT)))
  155                 return (ENOMEM);
  156 
  157         bzero(pfkeyv2_socket, sizeof(struct pfkeyv2_socket));
  158         pfkeyv2_socket->next = pfkeyv2_sockets;
  159         pfkeyv2_socket->socket = socket;
  160         pfkeyv2_socket->pid = curproc->p_pid;
  161 
  162         pfkeyv2_sockets = pfkeyv2_socket;
  163 
  164         return (0);
  165 }
  166 
  167 /*
  168  * Close a PF_KEYv2 socket.
  169  */
  170 int
  171 pfkeyv2_release(struct socket *socket)
  172 {
  173         struct pfkeyv2_socket **pp;
  174 
  175         for (pp = &pfkeyv2_sockets; *pp && ((*pp)->socket != socket);
  176             pp = &((*pp)->next))
  177                 /*EMPTY*/;
  178 
  179         if (*pp) {
  180                 struct pfkeyv2_socket *pfkeyv2_socket;
  181 
  182                 pfkeyv2_socket = *pp;
  183                 *pp = (*pp)->next;
  184 
  185                 if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)
  186                         nregistered--;
  187 
  188                 if (pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
  189                         npromisc--;
  190 
  191                 free(pfkeyv2_socket, M_PFKEY);
  192         }
  193 
  194         return (0);
  195 }
  196 
  197 /*
  198  * Send a PFKEYv2 message, possibly to many receivers, based on the
  199  * satype of the socket (which is set by the REGISTER message), and the
  200  * third argument.
  201  */
  202 int
  203 pfkeyv2_sendmessage(void **headers, int mode, struct socket *socket,
  204     u_int8_t satype, int count)
  205 {
  206         int i, j, rval;
  207         void *p, *buffer = NULL;
  208         struct mbuf *packet;
  209         struct pfkeyv2_socket *s;
  210         struct sadb_msg *smsg;
  211 
  212         /* Find out how much space we'll need... */
  213         j = sizeof(struct sadb_msg);
  214 
  215         for (i = 1; i <= SADB_EXT_MAX; i++)
  216                 if (headers[i])
  217                         j += ((struct sadb_ext *)headers[i])->sadb_ext_len *
  218                             sizeof(uint64_t);
  219 
  220         /* ...and allocate it */
  221         if (!(buffer = malloc(j + sizeof(struct sadb_msg), M_PFKEY,
  222             M_DONTWAIT))) {
  223                 rval = ENOMEM;
  224                 goto ret;
  225         }
  226 
  227         p = buffer + sizeof(struct sadb_msg);
  228         bcopy(headers[0], p, sizeof(struct sadb_msg));
  229         ((struct sadb_msg *) p)->sadb_msg_len = j / sizeof(uint64_t);
  230         p += sizeof(struct sadb_msg);
  231 
  232         /* Copy payloads in the packet */
  233         for (i = 1; i <= SADB_EXT_MAX; i++)
  234                 if (headers[i]) {
  235                         ((struct sadb_ext *) headers[i])->sadb_ext_type = i;
  236                         bcopy(headers[i], p, EXTLEN(headers[i]));
  237                         p += EXTLEN(headers[i]);
  238                 }
  239 
  240         if ((rval = pfdatatopacket(buffer + sizeof(struct sadb_msg),
  241             j, &packet)) != 0)
  242                 goto ret;
  243 
  244         switch (mode) {
  245         case PFKEYV2_SENDMESSAGE_UNICAST:
  246                 /*
  247                  * Send message to the specified socket, plus all
  248                  * promiscuous listeners.
  249                  */
  250                 pfkey_sendup(socket, packet, 0);
  251 
  252                 /*
  253                  * Promiscuous messages contain the original message
  254                  * encapsulated in another sadb_msg header.
  255                  */
  256                 bzero(buffer, sizeof(struct sadb_msg));
  257                 smsg = (struct sadb_msg *) buffer;
  258                 smsg->sadb_msg_version = PF_KEY_V2;
  259                 smsg->sadb_msg_type = SADB_X_PROMISC;
  260                 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
  261                     sizeof(uint64_t);
  262                 smsg->sadb_msg_seq = 0;
  263 
  264                 /* Copy to mbuf chain */
  265                 if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
  266                     &packet)) != 0)
  267                         goto ret;
  268 
  269                 /*
  270                  * Search for promiscuous listeners, skipping the
  271                  * original destination.
  272                  */
  273                 for (s = pfkeyv2_sockets; s; s = s->next)
  274                         if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
  275                             (s->socket != socket))
  276                                 pfkey_sendup(s->socket, packet, 1);
  277 
  278                 /* Done, let's be a bit paranoid */
  279                 m_zero(packet);
  280                 m_freem(packet);
  281                 break;
  282 
  283         case PFKEYV2_SENDMESSAGE_REGISTERED:
  284                 /*
  285                  * Send the message to all registered sockets that match
  286                  * the specified satype (e.g., all IPSEC-ESP negotiators)
  287                  */
  288                 for (s = pfkeyv2_sockets; s; s = s->next)
  289                         if (s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED) {
  290                                 if (!satype)    /* Just send to everyone registered */
  291                                         pfkey_sendup(s->socket, packet, 1);
  292                                 else {
  293                                         /* Check for specified satype */
  294                                         if ((1 << satype) & s->registration)
  295                                                 pfkey_sendup(s->socket, packet, 1);
  296                                 }
  297                         }
  298 
  299                 /* Free last/original copy of the packet */
  300                 m_freem(packet);
  301 
  302                 /* Encapsulate the original message "inside" an sadb_msg header */
  303                 bzero(buffer, sizeof(struct sadb_msg));
  304                 smsg = (struct sadb_msg *) buffer;
  305                 smsg->sadb_msg_version = PF_KEY_V2;
  306                 smsg->sadb_msg_type = SADB_X_PROMISC;
  307                 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) /
  308                     sizeof(uint64_t);
  309                 smsg->sadb_msg_seq = 0;
  310 
  311                 /* Convert to mbuf chain */
  312                 if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j,
  313                     &packet)) != 0)
  314                         goto ret;
  315 
  316                 /* Send to all registered promiscuous listeners */
  317                 for (s = pfkeyv2_sockets; s; s = s->next)
  318                         if ((s->flags & PFKEYV2_SOCKETFLAGS_PROMISC) &&
  319                             !(s->flags & PFKEYV2_SOCKETFLAGS_REGISTERED))
  320                                 pfkey_sendup(s->socket, packet, 1);
  321 
  322                 m_freem(packet);
  323                 break;
  324 
  325         case PFKEYV2_SENDMESSAGE_BROADCAST:
  326                 /* Send message to all sockets */
  327                 for (s = pfkeyv2_sockets; s; s = s->next)
  328                         pfkey_sendup(s->socket, packet, 1);
  329 
  330                 m_freem(packet);
  331                 break;
  332         }
  333 
  334 ret:
  335         if (buffer != NULL) {
  336                 bzero(buffer, j + sizeof(struct sadb_msg));
  337                 free(buffer, M_PFKEY);
  338         }
  339 
  340         return (rval);
  341 }
  342 
  343 /*
  344  * Get SPD information for an ACQUIRE. We setup the message such that
  345  * the SRC/DST payloads are relative to us (regardless of whether the
  346  * SPD rule was for incoming or outgoing packets).
  347  */
  348 int
  349 pfkeyv2_policy(struct ipsec_acquire *ipa, void **headers, void **buffer)
  350 {
  351         union sockaddr_union sunion;
  352         struct sadb_protocol *sp;
  353         int rval, i, dir;
  354         void *p;
  355 
  356         /* Find out how big a buffer we need */
  357         i = 4 * sizeof(struct sadb_address) + sizeof(struct sadb_protocol);
  358         bzero(&sunion, sizeof(union sockaddr_union));
  359 
  360         switch (ipa->ipa_info.sen_type) {
  361 #ifdef INET
  362         case SENT_IP4:
  363                 i += 4 * PADUP(sizeof(struct sockaddr_in));
  364                 sunion.sa.sa_family = AF_INET;
  365                 sunion.sa.sa_len = sizeof(struct sockaddr_in);
  366                 dir = ipa->ipa_info.sen_direction;
  367                 break;
  368 #endif /* INET */
  369 
  370 #ifdef INET6
  371         case SENT_IP6:
  372                 i += 4 * PADUP(sizeof(struct sockaddr_in6));
  373                 sunion.sa.sa_family = AF_INET6;
  374                 sunion.sa.sa_len = sizeof(struct sockaddr_in6);
  375                 dir = ipa->ipa_info.sen_ip6_direction;
  376                 break;
  377 #endif /* INET6 */
  378 
  379         default:
  380                 return (EINVAL);
  381         }
  382 
  383         if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
  384                 rval = ENOMEM;
  385                 goto ret;
  386         } else {
  387                 *buffer = p;
  388                 bzero(p, i);
  389         }
  390 
  391         if (dir == IPSP_DIRECTION_OUT)
  392                 headers[SADB_X_EXT_SRC_FLOW] = p;
  393         else
  394                 headers[SADB_X_EXT_DST_FLOW] = p;
  395         switch (sunion.sa.sa_family) {
  396 #ifdef INET
  397         case AF_INET:
  398                 sunion.sin.sin_addr = ipa->ipa_info.sen_ip_src;
  399                 sunion.sin.sin_port = ipa->ipa_info.sen_sport;
  400                 break;
  401 #endif /* INET */
  402 
  403 #ifdef INET6
  404         case AF_INET6:
  405                 sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_src;
  406                 sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_sport;
  407                 break;
  408 #endif /* INET6 */
  409         }
  410         export_address(&p, (struct sockaddr *) &sunion);
  411 
  412         if (dir == IPSP_DIRECTION_OUT)
  413                 headers[SADB_X_EXT_SRC_MASK] = p;
  414         else
  415                 headers[SADB_X_EXT_DST_MASK] = p;
  416         switch (sunion.sa.sa_family) {
  417 #ifdef INET
  418         case AF_INET:
  419                 sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_src;
  420                 sunion.sin.sin_port = ipa->ipa_mask.sen_sport;
  421                 break;
  422 #endif /* INET */
  423 
  424 #ifdef INET6
  425         case AF_INET6:
  426                 sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_src;
  427                 sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_sport;
  428                 break;
  429 #endif /* INET6 */
  430         }
  431         export_address(&p, (struct sockaddr *) &sunion);
  432 
  433         if (dir == IPSP_DIRECTION_OUT)
  434                 headers[SADB_X_EXT_DST_FLOW] = p;
  435         else
  436                 headers[SADB_X_EXT_SRC_FLOW] = p;
  437         switch (sunion.sa.sa_family) {
  438 #ifdef INET
  439         case AF_INET:
  440                 sunion.sin.sin_addr = ipa->ipa_info.sen_ip_dst;
  441                 sunion.sin.sin_port = ipa->ipa_info.sen_dport;
  442                 break;
  443 #endif /* INET */
  444 
  445 #ifdef INET6
  446         case AF_INET6:
  447                 sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_dst;
  448                 sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_dport;
  449                 break;
  450 #endif /* INET6 */
  451         }
  452         export_address(&p, (struct sockaddr *) &sunion);
  453 
  454         if (dir == IPSP_DIRECTION_OUT)
  455                 headers[SADB_X_EXT_DST_MASK] = p;
  456         else
  457                 headers[SADB_X_EXT_SRC_MASK] = p;
  458         switch (sunion.sa.sa_family) {
  459 #ifdef INET
  460         case AF_INET:
  461                 sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_dst;
  462                 sunion.sin.sin_port = ipa->ipa_mask.sen_dport;
  463                 break;
  464 #endif /* INET */
  465 
  466 #ifdef INET6
  467         case AF_INET6:
  468                 sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_dst;
  469                 sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_dport;
  470                 break;
  471 #endif /* INET6 */
  472         }
  473         export_address(&p, (struct sockaddr *) &sunion);
  474 
  475         headers[SADB_X_EXT_FLOW_TYPE] = p;
  476         sp = p;
  477         sp->sadb_protocol_len = sizeof(struct sadb_protocol) /
  478             sizeof(u_int64_t);
  479         switch (sunion.sa.sa_family) {
  480 #ifdef INET
  481         case AF_INET:
  482                 if (ipa->ipa_mask.sen_proto)
  483                         sp->sadb_protocol_proto = ipa->ipa_info.sen_proto;
  484                 sp->sadb_protocol_direction = ipa->ipa_info.sen_direction;
  485                 break;
  486 #endif /* INET */
  487 
  488 #ifdef INET6
  489         case AF_INET6:
  490                 if (ipa->ipa_mask.sen_ip6_proto)
  491                         sp->sadb_protocol_proto = ipa->ipa_info.sen_ip6_proto;
  492                 sp->sadb_protocol_direction = ipa->ipa_info.sen_ip6_direction;
  493                 break;
  494 #endif /* INET6 */
  495         }
  496 
  497         rval = 0;
  498 
  499 ret:
  500         return (rval);
  501 }
  502 
  503 /*
  504  * Get all the information contained in an SA to a PFKEYV2 message.
  505  */
  506 int
  507 pfkeyv2_get(struct tdb *sa, void **headers, void **buffer, int *lenp)
  508 {
  509         int rval, i;
  510         void *p;
  511 
  512         /* Find how much space we need */
  513         i = sizeof(struct sadb_sa) + sizeof(struct sadb_lifetime);
  514 
  515         if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
  516             sa->tdb_soft_timeout || sa->tdb_soft_first_use)
  517                 i += sizeof(struct sadb_lifetime);
  518 
  519         if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
  520             sa->tdb_exp_timeout || sa->tdb_exp_first_use)
  521                 i += sizeof(struct sadb_lifetime);
  522 
  523         if (sa->tdb_last_used)
  524                 i += sizeof(struct sadb_lifetime);
  525 
  526         if (sa->tdb_src.sa.sa_family)
  527                 i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa));
  528 
  529         if (sa->tdb_dst.sa.sa_family)
  530                 i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
  531 
  532         if (sa->tdb_proxy.sa.sa_family)
  533                 i += sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_proxy.sa));
  534 
  535         if (sa->tdb_srcid)
  536                 i += PADUP(sa->tdb_srcid->ref_len) + sizeof(struct sadb_ident);
  537 
  538         if (sa->tdb_dstid)
  539                 i += PADUP(sa->tdb_dstid->ref_len) + sizeof(struct sadb_ident);
  540 
  541         if (sa->tdb_local_cred)
  542                 i += PADUP(sa->tdb_local_cred->ref_len) + sizeof(struct sadb_x_cred);
  543 
  544         if (sa->tdb_remote_cred)
  545                 i += PADUP(sa->tdb_remote_cred->ref_len) + sizeof(struct sadb_x_cred);
  546 
  547         if (sa->tdb_local_auth)
  548                 i += PADUP(sa->tdb_local_auth->ref_len) + sizeof(struct sadb_x_cred);
  549 
  550         if (sa->tdb_remote_auth)
  551                 i += PADUP(sa->tdb_remote_auth->ref_len) + sizeof(struct sadb_x_cred);
  552 
  553         if (sa->tdb_amxkey)
  554                 i+= PADUP(sa->tdb_amxkeylen) + sizeof(struct sadb_key);
  555 
  556         if (sa->tdb_emxkey)
  557                 i+= PADUP(sa->tdb_emxkeylen) + sizeof(struct sadb_key);
  558 
  559         if (sa->tdb_filter.sen_type) {
  560                 i += 2 * sizeof(struct sadb_protocol);
  561 
  562                 /* We'll need four of them: src, src mask, dst, dst mask. */
  563                 switch (sa->tdb_filter.sen_type) {
  564 #ifdef INET
  565                 case SENT_IP4:
  566                         i += 4 * PADUP(sizeof(struct sockaddr_in));
  567                         i += 4 * sizeof(struct sadb_address);
  568                         break;
  569 #endif /* INET */
  570 #ifdef INET6
  571                 case SENT_IP6:
  572                         i += 4 * PADUP(sizeof(struct sockaddr_in6));
  573                         i += 4 * sizeof(struct sadb_address);
  574                         break;
  575 #endif /* INET6 */
  576                 default:
  577                         rval = EINVAL;
  578                         goto ret;
  579                 }
  580         }
  581 
  582         if (sa->tdb_udpencap_port)
  583                 i+= sizeof(struct sadb_x_udpencap);
  584 
  585 #if NPF > 0
  586         if (sa->tdb_tag)
  587                 i+= PADUP(PF_TAG_NAME_SIZE) + sizeof(struct sadb_x_tag);
  588 #endif
  589 
  590         if (lenp)
  591                 *lenp = i;
  592 
  593         if (buffer == NULL) {
  594                 rval = 0;
  595                 goto ret;
  596         }
  597 
  598         if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
  599                 rval = ENOMEM;
  600                 goto ret;
  601         } else {
  602                 *buffer = p;
  603                 bzero(p, i);
  604         }
  605 
  606         headers[SADB_EXT_SA] = p;
  607 
  608         export_sa(&p, sa);  /* Export SA information (mostly flags) */
  609 
  610         /* Export lifetimes where applicable */
  611         headers[SADB_EXT_LIFETIME_CURRENT] = p;
  612         export_lifetime(&p, sa, PFKEYV2_LIFETIME_CURRENT);
  613 
  614         if (sa->tdb_soft_allocations || sa->tdb_soft_bytes ||
  615             sa->tdb_soft_first_use || sa->tdb_soft_timeout) {
  616                 headers[SADB_EXT_LIFETIME_SOFT] = p;
  617                 export_lifetime(&p, sa, PFKEYV2_LIFETIME_SOFT);
  618         }
  619 
  620         if (sa->tdb_exp_allocations || sa->tdb_exp_bytes ||
  621             sa->tdb_exp_first_use || sa->tdb_exp_timeout) {
  622                 headers[SADB_EXT_LIFETIME_HARD] = p;
  623                 export_lifetime(&p, sa, PFKEYV2_LIFETIME_HARD);
  624         }
  625 
  626         if (sa->tdb_last_used) {
  627                 headers[SADB_X_EXT_LIFETIME_LASTUSE] = p;
  628                 export_lifetime(&p, sa, PFKEYV2_LIFETIME_LASTUSE);
  629         }
  630 
  631         /* Export TDB source address */
  632         headers[SADB_EXT_ADDRESS_SRC] = p;
  633         export_address(&p, (struct sockaddr *) &sa->tdb_src);
  634 
  635         /* Export TDB destination address */
  636         headers[SADB_EXT_ADDRESS_DST] = p;
  637         export_address(&p, (struct sockaddr *) &sa->tdb_dst);
  638 
  639         /* Export TDB proxy address, if present */
  640         if (SA_LEN(&sa->tdb_proxy.sa)) {
  641                 headers[SADB_EXT_ADDRESS_PROXY] = p;
  642                 export_address(&p, (struct sockaddr *) &sa->tdb_proxy);
  643         }
  644 
  645         /* Export source identity, if present */
  646         if (sa->tdb_srcid) {
  647                 headers[SADB_EXT_IDENTITY_SRC] = p;
  648                 export_identity(&p, sa, PFKEYV2_IDENTITY_SRC);
  649         }
  650 
  651         /* Export destination identity, if present */
  652         if (sa->tdb_dstid) {
  653                 headers[SADB_EXT_IDENTITY_DST] = p;
  654                 export_identity(&p, sa, PFKEYV2_IDENTITY_DST);
  655         }
  656 
  657         /* Export credentials, if present */
  658         if (sa->tdb_local_cred) {
  659                 headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
  660                 export_credentials(&p, sa, PFKEYV2_CRED_LOCAL);
  661         }
  662 
  663         if (sa->tdb_remote_cred) {
  664                 headers[SADB_X_EXT_REMOTE_CREDENTIALS] = p;
  665                 export_credentials(&p, sa, PFKEYV2_CRED_REMOTE);
  666         }
  667 
  668         /* Export authentication information, if present */
  669         if (sa->tdb_local_auth) {
  670                 headers[SADB_X_EXT_LOCAL_AUTH] = p;
  671                 export_auth(&p, sa, PFKEYV2_AUTH_LOCAL);
  672         }
  673 
  674         if (sa->tdb_remote_auth) {
  675                 headers[SADB_X_EXT_REMOTE_AUTH] = p;
  676                 export_auth(&p, sa, PFKEYV2_AUTH_REMOTE);
  677         }
  678 
  679         /* Export authentication key, if present */
  680         if (sa->tdb_amxkey) {
  681                 headers[SADB_EXT_KEY_AUTH] = p;
  682                 export_key(&p, sa, PFKEYV2_AUTHENTICATION_KEY);
  683         }
  684 
  685         /* Export encryption key, if present */
  686         if (sa->tdb_emxkey) {
  687                 headers[SADB_EXT_KEY_ENCRYPT] = p;
  688                 export_key(&p, sa, PFKEYV2_ENCRYPTION_KEY);
  689         }
  690 
  691         /* Export flow/filter, if present */
  692         if (sa->tdb_filter.sen_type)
  693                 export_flow(&p, IPSP_IPSEC_USE, &sa->tdb_filter,
  694                     &sa->tdb_filtermask, headers);
  695 
  696         /* Export UDP encapsulation port, if present */
  697         if (sa->tdb_udpencap_port) {
  698                 headers[SADB_X_EXT_UDPENCAP] = p;
  699                 export_udpencap(&p, sa);
  700         }
  701 
  702 #if NPF > 0
  703         /* Export tag information, if present */
  704         if (sa->tdb_tag) {
  705                 headers[SADB_X_EXT_TAG] = p;
  706                 export_tag(&p, sa);
  707         }
  708 #endif
  709 
  710         rval = 0;
  711 
  712  ret:
  713         return (rval);
  714 }
  715 
  716 /*
  717  * Dump a TDB.
  718  */
  719 int
  720 pfkeyv2_dump_walker(struct tdb *sa, void *state, int last)
  721 {
  722         struct dump_state *dump_state = (struct dump_state *) state;
  723         void *headers[SADB_EXT_MAX+1], *buffer;
  724         int rval;
  725 
  726         /* If not satype was specified, dump all TDBs */
  727         if (!dump_state->sadb_msg->sadb_msg_satype ||
  728             (sa->tdb_satype == dump_state->sadb_msg->sadb_msg_satype)) {
  729                 bzero(headers, sizeof(headers));
  730                 headers[0] = (void *) dump_state->sadb_msg;
  731 
  732                 /* Get the information from the TDB to a PFKEYv2 message */
  733                 if ((rval = pfkeyv2_get(sa, headers, &buffer, NULL)) != 0)
  734                         return (rval);
  735 
  736                 if (last)
  737                         ((struct sadb_msg *)headers[0])->sadb_msg_seq = 0;
  738 
  739                 /* Send the message to the specified socket */
  740                 rval = pfkeyv2_sendmessage(headers,
  741                     PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0);
  742 
  743                 free(buffer, M_PFKEY);
  744                 if (rval)
  745                         return (rval);
  746         }
  747 
  748         return (0);
  749 }
  750 
  751 /*
  752  * Delete an SA.
  753  */
  754 int
  755 pfkeyv2_flush_walker(struct tdb *sa, void *satype_vp, int last)
  756 {
  757         if (!(*((u_int8_t *) satype_vp)) ||
  758             sa->tdb_satype == *((u_int8_t *) satype_vp))
  759                 tdb_delete(sa);
  760         return (0);
  761 }
  762 
  763 /*
  764  * Convert between SATYPEs and IPsec protocols, taking into consideration
  765  * sysctl variables enabling/disabling ESP/AH and the presence of the old
  766  * IPsec transforms.
  767  */
  768 int
  769 pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg)
  770 {
  771         switch (satype) {
  772 #ifdef IPSEC
  773         case SADB_SATYPE_AH:
  774                 if (!ah_enable)
  775                         return (EOPNOTSUPP);
  776 
  777                 *sproto = IPPROTO_AH;
  778 
  779                 if(alg != NULL)
  780                         *alg = satype = XF_AH;
  781 
  782                 break;
  783 
  784         case SADB_SATYPE_ESP:
  785                 if (!esp_enable)
  786                         return (EOPNOTSUPP);
  787 
  788                 *sproto = IPPROTO_ESP;
  789 
  790                 if(alg != NULL)
  791                         *alg = satype = XF_ESP;
  792 
  793                 break;
  794 
  795         case SADB_X_SATYPE_IPIP:
  796                 *sproto = IPPROTO_IPIP;
  797 
  798                 if (alg != NULL)
  799                         *alg = XF_IP4;
  800 
  801                 break;
  802 
  803         case SADB_X_SATYPE_IPCOMP:
  804                 if (!ipcomp_enable)
  805                         return (EOPNOTSUPP);
  806 
  807                 *sproto = IPPROTO_IPCOMP;
  808 
  809                 if(alg != NULL)
  810                         *alg = satype = XF_IPCOMP;
  811 
  812                 break;
  813 #endif /* IPSEC */
  814 #ifdef TCP_SIGNATURE
  815         case SADB_X_SATYPE_TCPSIGNATURE:
  816                 *sproto = IPPROTO_TCP;
  817 
  818                 if (alg != NULL)
  819                         *alg = XF_TCPSIGNATURE;
  820 
  821                 break;
  822 #endif /* TCP_SIGNATURE */
  823 
  824         default: /* Nothing else supported */
  825                 return (EOPNOTSUPP);
  826         }
  827 
  828         return (0);
  829 }
  830 
  831 /*
  832  * Handle all messages from userland to kernel.
  833  */
  834 int
  835 pfkeyv2_send(struct socket *socket, void *message, int len)
  836 {
  837         int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST;
  838         int delflag = 0, s;
  839         struct sockaddr_encap encapdst, encapnetmask, encapgw;
  840         struct ipsec_policy *ipo, *tmpipo;
  841         struct ipsec_acquire *ipa;
  842 
  843         struct pfkeyv2_socket *pfkeyv2_socket, *so = NULL;
  844 
  845         void *freeme = NULL, *bckptr = NULL;
  846         void *headers[SADB_EXT_MAX + 1];
  847 
  848         union sockaddr_union *sunionp;
  849 
  850         struct tdb sa, *sa2 = NULL;
  851 
  852         struct sadb_msg *smsg;
  853         struct sadb_spirange *sprng;
  854         struct sadb_sa *ssa;
  855         struct sadb_supported *ssup;
  856         struct sadb_ident *sid;
  857 
  858         /* Verify that we received this over a legitimate pfkeyv2 socket */
  859         bzero(headers, sizeof(headers));
  860 
  861         for (pfkeyv2_socket = pfkeyv2_sockets; pfkeyv2_socket;
  862             pfkeyv2_socket = pfkeyv2_socket->next)
  863                 if (pfkeyv2_socket->socket == socket)
  864                         break;
  865 
  866         if (!pfkeyv2_socket) {
  867                 rval = EINVAL;
  868                 goto ret;
  869         }
  870 
  871         /* If we have any promiscuous listeners, send them a copy of the message */
  872         if (npromisc) {
  873                 struct mbuf *packet;
  874 
  875                 if (!(freeme = malloc(sizeof(struct sadb_msg) + len, M_PFKEY,
  876                     M_DONTWAIT))) {
  877                         rval = ENOMEM;
  878                         goto ret;
  879                 }
  880 
  881                 /* Initialize encapsulating header */
  882                 bzero(freeme, sizeof(struct sadb_msg));
  883                 smsg = (struct sadb_msg *) freeme;
  884                 smsg->sadb_msg_version = PF_KEY_V2;
  885                 smsg->sadb_msg_type = SADB_X_PROMISC;
  886                 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + len) /
  887                     sizeof(uint64_t);
  888                 smsg->sadb_msg_seq = curproc->p_pid;
  889 
  890                 bcopy(message, freeme + sizeof(struct sadb_msg), len);
  891 
  892                 /* Convert to mbuf chain */
  893                 if ((rval = pfdatatopacket(freeme,
  894                     sizeof(struct sadb_msg) + len, &packet)) != 0)
  895                         goto ret;
  896 
  897                 /* Send to all promiscuous listeners */
  898                 for (so = pfkeyv2_sockets; so; so = so->next)
  899                         if (so->flags & PFKEYV2_SOCKETFLAGS_PROMISC)
  900                                 pfkey_sendup(so->socket, packet, 1);
  901 
  902                 /* Paranoid */
  903                 m_zero(packet);
  904                 m_freem(packet);
  905 
  906                 /* Even more paranoid */
  907                 bzero(freeme, sizeof(struct sadb_msg) + len);
  908                 free(freeme, M_PFKEY);
  909                 freeme = NULL;
  910         }
  911 
  912         /* Validate message format */
  913         if ((rval = pfkeyv2_parsemessage(message, len, headers)) != 0)
  914                 goto ret;
  915 
  916         smsg = (struct sadb_msg *) headers[0];
  917         switch (smsg->sadb_msg_type) {
  918         case SADB_GETSPI:  /* Reserve an SPI */
  919                 bzero(&sa, sizeof(struct tdb));
  920 
  921                 sa.tdb_satype = smsg->sadb_msg_satype;
  922                 if ((rval = pfkeyv2_get_proto_alg(sa.tdb_satype,
  923                     &sa.tdb_sproto, 0)))
  924                         goto ret;
  925 
  926                 import_address((struct sockaddr *) &sa.tdb_src,
  927                     headers[SADB_EXT_ADDRESS_SRC]);
  928                 import_address((struct sockaddr *) &sa.tdb_dst,
  929                     headers[SADB_EXT_ADDRESS_DST]);
  930 
  931                 /* Find an unused SA identifier */
  932                 sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE];
  933                 sa.tdb_spi = reserve_spi(sprng->sadb_spirange_min,
  934                     sprng->sadb_spirange_max, &sa.tdb_src, &sa.tdb_dst,
  935                     sa.tdb_sproto, &rval);
  936                 if (sa.tdb_spi == 0)
  937                         goto ret;
  938 
  939                 /* Send a message back telling what the SA (the SPI really) is */
  940                 if (!(freeme = malloc(sizeof(struct sadb_sa), M_PFKEY,
  941                     M_DONTWAIT))) {
  942                         rval = ENOMEM;
  943                         goto ret;
  944                 }
  945 
  946                 bzero(freeme, sizeof(struct sadb_sa));
  947                 headers[SADB_EXT_SPIRANGE] = NULL;
  948                 headers[SADB_EXT_SA] = freeme;
  949                 bckptr = freeme;
  950 
  951                 /* We really only care about the SPI, but we'll export the SA */
  952                 export_sa((void **) &bckptr, &sa);
  953                 break;
  954 
  955         case SADB_UPDATE:
  956                 ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
  957                 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
  958                     sizeof(struct sadb_address));
  959 
  960                 /* Either all or none of the flow must be included */
  961                 if ((headers[SADB_X_EXT_SRC_FLOW] ||
  962                     headers[SADB_X_EXT_PROTOCOL] ||
  963                     headers[SADB_X_EXT_FLOW_TYPE] ||
  964                     headers[SADB_X_EXT_DST_FLOW] ||
  965                     headers[SADB_X_EXT_SRC_MASK] ||
  966                     headers[SADB_X_EXT_DST_MASK]) &&
  967                     !(headers[SADB_X_EXT_SRC_FLOW] &&
  968                     headers[SADB_X_EXT_PROTOCOL] &&
  969                     headers[SADB_X_EXT_FLOW_TYPE] &&
  970                     headers[SADB_X_EXT_DST_FLOW] &&
  971                     headers[SADB_X_EXT_SRC_MASK] &&
  972                     headers[SADB_X_EXT_DST_MASK])) {
  973                         rval = EINVAL;
  974                         goto ret;
  975                 }
  976 #ifdef IPSEC
  977                 /* UDP encap has to be enabled and is only supported for ESP */
  978                 if (headers[SADB_X_EXT_UDPENCAP] &&
  979                     (!udpencap_enable ||
  980                     smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
  981                         rval = EINVAL;
  982                         goto ret;
  983                 }
  984 #endif /* IPSEC */
  985 
  986                 s = spltdb();
  987 
  988                 /* Find TDB */
  989                 sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
  990                     SADB_X_GETSPROTO(smsg->sadb_msg_satype));
  991 
  992                 /* If there's no such SA, we're done */
  993                 if (sa2 == NULL) {
  994                         rval = ESRCH;
  995                         goto splxret;
  996                 }
  997 
  998                 /* If this is a reserved SA */
  999                 if (sa2->tdb_flags & TDBF_INVALID) {
 1000                         struct tdb *newsa;
 1001                         struct ipsecinit ii;
 1002                         int alg;
 1003 
 1004                         /* Create new TDB */
 1005                         freeme = tdb_alloc();
 1006                         bzero(&ii, sizeof(struct ipsecinit));
 1007 
 1008                         newsa = (struct tdb *) freeme;
 1009                         newsa->tdb_satype = smsg->sadb_msg_satype;
 1010 
 1011                         if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
 1012                             &newsa->tdb_sproto, &alg))) {
 1013                                 tdb_free(freeme);
 1014                                 freeme = NULL;
 1015                                 goto splxret;
 1016                         }
 1017 
 1018                         /* Initialize SA */
 1019                         import_sa(newsa, headers[SADB_EXT_SA], &ii);
 1020                         import_address((struct sockaddr *) &newsa->tdb_src,
 1021                             headers[SADB_EXT_ADDRESS_SRC]);
 1022                         import_address((struct sockaddr *) &newsa->tdb_dst,
 1023                             headers[SADB_EXT_ADDRESS_DST]);
 1024                         import_address((struct sockaddr *) &newsa->tdb_proxy,
 1025                             headers[SADB_EXT_ADDRESS_PROXY]);
 1026                         import_lifetime(newsa,
 1027                             headers[SADB_EXT_LIFETIME_CURRENT],
 1028                             PFKEYV2_LIFETIME_CURRENT);
 1029                         import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
 1030                             PFKEYV2_LIFETIME_SOFT);
 1031                         import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
 1032                             PFKEYV2_LIFETIME_HARD);
 1033                         import_key(&ii, headers[SADB_EXT_KEY_AUTH],
 1034                             PFKEYV2_AUTHENTICATION_KEY);
 1035                         import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
 1036                             PFKEYV2_ENCRYPTION_KEY);
 1037                         import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
 1038                             PFKEYV2_IDENTITY_SRC);
 1039                         import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
 1040                             PFKEYV2_IDENTITY_DST);
 1041                         import_credentials(newsa,
 1042                             headers[SADB_X_EXT_LOCAL_CREDENTIALS],
 1043                             PFKEYV2_CRED_LOCAL);
 1044                         import_credentials(newsa,
 1045                             headers[SADB_X_EXT_REMOTE_CREDENTIALS],
 1046                             PFKEYV2_CRED_REMOTE);
 1047                         import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
 1048                             PFKEYV2_AUTH_LOCAL);
 1049                         import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
 1050                             PFKEYV2_AUTH_REMOTE);
 1051                         import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
 1052                             headers[SADB_X_EXT_SRC_FLOW],
 1053                             headers[SADB_X_EXT_SRC_MASK],
 1054                             headers[SADB_X_EXT_DST_FLOW],
 1055                             headers[SADB_X_EXT_DST_MASK],
 1056                             headers[SADB_X_EXT_PROTOCOL],
 1057                             headers[SADB_X_EXT_FLOW_TYPE]);
 1058                         import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
 1059 #if NPF > 0
 1060                         import_tag(newsa, headers[SADB_X_EXT_TAG]);
 1061 #endif
 1062 
 1063                         headers[SADB_EXT_KEY_AUTH] = NULL;
 1064                         headers[SADB_EXT_KEY_ENCRYPT] = NULL;
 1065                         headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
 1066 
 1067                         newsa->tdb_seq = smsg->sadb_msg_seq;
 1068 
 1069                         rval = tdb_init(newsa, alg, &ii);
 1070                         if (rval) {
 1071                                 rval = EINVAL;
 1072                                 tdb_free(freeme);
 1073                                 freeme = NULL;
 1074                                 goto splxret;
 1075                         }
 1076 
 1077                         newsa->tdb_cur_allocations = sa2->tdb_cur_allocations;
 1078 
 1079                         /* Delete old version of the SA, insert new one */
 1080                         tdb_delete(sa2);
 1081                         puttdb((struct tdb *) freeme);
 1082                         sa2 = freeme = NULL;
 1083                 } else {
 1084                         /*
 1085                          * The SA is already initialized, so we're only allowed to
 1086                          * change lifetimes and some other information; we're
 1087                          * not allowed to change keys, addresses or identities.
 1088                          */
 1089                         if (headers[SADB_EXT_ADDRESS_PROXY] ||
 1090                             headers[SADB_EXT_KEY_AUTH] ||
 1091                             headers[SADB_EXT_KEY_ENCRYPT] ||
 1092                             headers[SADB_EXT_IDENTITY_SRC] ||
 1093                             headers[SADB_EXT_IDENTITY_DST] ||
 1094                             headers[SADB_EXT_SENSITIVITY]) {
 1095                                 rval = EINVAL;
 1096                                 goto splxret;
 1097                         }
 1098 
 1099                         import_sa(sa2, headers[SADB_EXT_SA], NULL);
 1100                         import_lifetime(sa2,
 1101                             headers[SADB_EXT_LIFETIME_CURRENT],
 1102                             PFKEYV2_LIFETIME_CURRENT);
 1103                         import_lifetime(sa2, headers[SADB_EXT_LIFETIME_SOFT],
 1104                             PFKEYV2_LIFETIME_SOFT);
 1105                         import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD],
 1106                             PFKEYV2_LIFETIME_HARD);
 1107                         import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]);
 1108 #if NPF > 0
 1109                         import_tag(sa2, headers[SADB_X_EXT_TAG]);
 1110 #endif
 1111                 }
 1112 
 1113                 splx(s);
 1114                 break;
 1115         case SADB_ADD:
 1116                 ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
 1117                 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
 1118                     sizeof(struct sadb_address));
 1119 
 1120                 /* Either all or none of the flow must be included */
 1121                 if ((headers[SADB_X_EXT_SRC_FLOW] ||
 1122                     headers[SADB_X_EXT_PROTOCOL] ||
 1123                     headers[SADB_X_EXT_FLOW_TYPE] ||
 1124                     headers[SADB_X_EXT_DST_FLOW] ||
 1125                     headers[SADB_X_EXT_SRC_MASK] ||
 1126                     headers[SADB_X_EXT_DST_MASK]) &&
 1127                     !(headers[SADB_X_EXT_SRC_FLOW] &&
 1128                     headers[SADB_X_EXT_PROTOCOL] &&
 1129                     headers[SADB_X_EXT_FLOW_TYPE] &&
 1130                     headers[SADB_X_EXT_DST_FLOW] &&
 1131                     headers[SADB_X_EXT_SRC_MASK] &&
 1132                     headers[SADB_X_EXT_DST_MASK])) {
 1133                         rval = EINVAL;
 1134                         goto ret;
 1135                 }
 1136 #ifdef IPSEC
 1137                 /* UDP encap has to be enabled and is only supported for ESP */
 1138                 if (headers[SADB_X_EXT_UDPENCAP] &&
 1139                     (!udpencap_enable ||
 1140                     smsg->sadb_msg_satype != SADB_SATYPE_ESP)) {
 1141                         rval = EINVAL;
 1142                         goto ret;
 1143                 }
 1144 #endif /* IPSEC */
 1145 
 1146                 s = spltdb();
 1147 
 1148                 sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
 1149                     SADB_X_GETSPROTO(smsg->sadb_msg_satype));
 1150 
 1151                 /* We can't add an existing SA! */
 1152                 if (sa2 != NULL) {
 1153                         rval = EEXIST;
 1154                         goto splxret;
 1155                 }
 1156 
 1157                 /* We can only add "mature" SAs */
 1158                 if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) {
 1159                         rval = EINVAL;
 1160                         goto splxret;
 1161                 }
 1162 
 1163                 /* Allocate and initialize new TDB */
 1164                 freeme = tdb_alloc();
 1165 
 1166                 {
 1167                         struct tdb *newsa = (struct tdb *) freeme;
 1168                         struct ipsecinit ii;
 1169                         int alg;
 1170 
 1171                         bzero(&ii, sizeof(struct ipsecinit));
 1172 
 1173                         newsa->tdb_satype = smsg->sadb_msg_satype;
 1174                         if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype,
 1175                             &newsa->tdb_sproto, &alg))) {
 1176                                 tdb_free(freeme);
 1177                                 freeme = NULL;
 1178                                 goto splxret;
 1179                         }
 1180 
 1181                         import_sa(newsa, headers[SADB_EXT_SA], &ii);
 1182                         import_address((struct sockaddr *) &newsa->tdb_src,
 1183                             headers[SADB_EXT_ADDRESS_SRC]);
 1184                         import_address((struct sockaddr *) &newsa->tdb_dst,
 1185                             headers[SADB_EXT_ADDRESS_DST]);
 1186                         import_address((struct sockaddr *) &newsa->tdb_proxy,
 1187                             headers[SADB_EXT_ADDRESS_PROXY]);
 1188 
 1189                         import_lifetime(newsa,
 1190                             headers[SADB_EXT_LIFETIME_CURRENT],
 1191                             PFKEYV2_LIFETIME_CURRENT);
 1192                         import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT],
 1193                             PFKEYV2_LIFETIME_SOFT);
 1194                         import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD],
 1195                             PFKEYV2_LIFETIME_HARD);
 1196 
 1197                         import_key(&ii, headers[SADB_EXT_KEY_AUTH],
 1198                             PFKEYV2_AUTHENTICATION_KEY);
 1199                         import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT],
 1200                             PFKEYV2_ENCRYPTION_KEY);
 1201 
 1202                         import_identity(newsa, headers[SADB_EXT_IDENTITY_SRC],
 1203                             PFKEYV2_IDENTITY_SRC);
 1204                         import_identity(newsa, headers[SADB_EXT_IDENTITY_DST],
 1205                             PFKEYV2_IDENTITY_DST);
 1206 
 1207                         import_credentials(newsa,
 1208                             headers[SADB_X_EXT_LOCAL_CREDENTIALS],
 1209                             PFKEYV2_CRED_LOCAL);
 1210                         import_credentials(newsa,
 1211                             headers[SADB_X_EXT_REMOTE_CREDENTIALS],
 1212                             PFKEYV2_CRED_REMOTE);
 1213                         import_auth(newsa, headers[SADB_X_EXT_LOCAL_AUTH],
 1214                             PFKEYV2_AUTH_LOCAL);
 1215                         import_auth(newsa, headers[SADB_X_EXT_REMOTE_AUTH],
 1216                             PFKEYV2_AUTH_REMOTE);
 1217                         import_flow(&newsa->tdb_filter, &newsa->tdb_filtermask,
 1218                             headers[SADB_X_EXT_SRC_FLOW],
 1219                             headers[SADB_X_EXT_SRC_MASK],
 1220                             headers[SADB_X_EXT_DST_FLOW],
 1221                             headers[SADB_X_EXT_DST_MASK],
 1222                             headers[SADB_X_EXT_PROTOCOL],
 1223                             headers[SADB_X_EXT_FLOW_TYPE]);
 1224                         import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]);
 1225 #if NPF > 0
 1226                         import_tag(newsa, headers[SADB_X_EXT_TAG]);
 1227 #endif
 1228 
 1229                         headers[SADB_EXT_KEY_AUTH] = NULL;
 1230                         headers[SADB_EXT_KEY_ENCRYPT] = NULL;
 1231                         headers[SADB_X_EXT_LOCAL_AUTH] = NULL;
 1232 
 1233                         newsa->tdb_seq = smsg->sadb_msg_seq;
 1234 
 1235                         rval = tdb_init(newsa, alg, &ii);
 1236                         if (rval) {
 1237                                 rval = EINVAL;
 1238                                 tdb_free(freeme);
 1239                                 freeme = NULL;
 1240                                 goto splxret;
 1241                         }
 1242                 }
 1243 
 1244                 /* Add TDB in table */
 1245                 puttdb((struct tdb *) freeme);
 1246 
 1247                 splx(s);
 1248 
 1249                 freeme = NULL;
 1250                 break;
 1251 
 1252         case SADB_DELETE:
 1253                 ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
 1254                 sunionp =
 1255                     (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
 1256                         sizeof(struct sadb_address));
 1257                 s = spltdb();
 1258 
 1259                 sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
 1260                     SADB_X_GETSPROTO(smsg->sadb_msg_satype));
 1261                 if (sa2 == NULL) {
 1262                         rval = ESRCH;
 1263                         goto splxret;
 1264                 }
 1265 
 1266                 tdb_delete(sa2);
 1267 
 1268                 splx(s);
 1269 
 1270                 sa2 = NULL;
 1271                 break;
 1272 
 1273         case SADB_X_ASKPOLICY:
 1274                 /* Get the relevant policy */
 1275                 ipa = ipsec_get_acquire(((struct sadb_x_policy *) headers[SADB_X_EXT_POLICY])->sadb_x_policy_seq);
 1276                 if (ipa == NULL) {
 1277                         rval = ESRCH;
 1278                         goto ret;
 1279                 }
 1280 
 1281                 rval = pfkeyv2_policy(ipa, headers, &freeme);
 1282                 if (rval)
 1283                         mode = PFKEYV2_SENDMESSAGE_UNICAST;
 1284 
 1285                 break;
 1286 
 1287         case SADB_GET:
 1288                 ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
 1289                 sunionp =
 1290                     (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] +
 1291                         sizeof(struct sadb_address));
 1292 
 1293                 s = spltdb();
 1294 
 1295                 sa2 = gettdb(ssa->sadb_sa_spi, sunionp,
 1296                     SADB_X_GETSPROTO(smsg->sadb_msg_satype));
 1297                 if (sa2 == NULL) {
 1298                         rval = ESRCH;
 1299                         goto splxret;
 1300                 }
 1301 
 1302                 rval = pfkeyv2_get(sa2, headers, &freeme, NULL);
 1303                 if (rval)
 1304                         mode = PFKEYV2_SENDMESSAGE_UNICAST;
 1305 
 1306                 splx(s);
 1307 
 1308                 break;
 1309 
 1310         case SADB_REGISTER:
 1311                 if (!(pfkeyv2_socket->flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) {
 1312                         pfkeyv2_socket->flags |= PFKEYV2_SOCKETFLAGS_REGISTERED;
 1313                         nregistered++;
 1314                 }
 1315 
 1316                 i = sizeof(struct sadb_supported) + sizeof(ealgs);
 1317 
 1318                 if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
 1319                         rval = ENOMEM;
 1320                         goto ret;
 1321                 }
 1322 
 1323                 bzero(freeme, i);
 1324 
 1325                 ssup = (struct sadb_supported *) freeme;
 1326                 ssup->sadb_supported_len = i / sizeof(uint64_t);
 1327 
 1328                 {
 1329                         void *p = freeme + sizeof(struct sadb_supported);
 1330 
 1331                         bcopy(&ealgs[0], p, sizeof(ealgs));
 1332                 }
 1333 
 1334                 headers[SADB_EXT_SUPPORTED_ENCRYPT] = freeme;
 1335 
 1336                 i = sizeof(struct sadb_supported) + sizeof(aalgs);
 1337 
 1338                 if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
 1339                         rval = ENOMEM;
 1340                         goto ret;
 1341                 }
 1342 
 1343                 /* Keep track what this socket has registered for */
 1344                 pfkeyv2_socket->registration |= (1 << ((struct sadb_msg *)message)->sadb_msg_satype);
 1345 
 1346                 bzero(freeme, i);
 1347 
 1348                 ssup = (struct sadb_supported *) freeme;
 1349                 ssup->sadb_supported_len = i / sizeof(uint64_t);
 1350 
 1351                 {
 1352                         void *p = freeme + sizeof(struct sadb_supported);
 1353 
 1354                         bcopy(&aalgs[0], p, sizeof(aalgs));
 1355                 }
 1356 
 1357                 headers[SADB_EXT_SUPPORTED_AUTH] = freeme;
 1358 
 1359                 i = sizeof(struct sadb_supported) + sizeof(calgs);
 1360 
 1361                 if (!(freeme = malloc(i, M_PFKEY, M_DONTWAIT))) {
 1362                         rval = ENOMEM;
 1363                         goto ret;
 1364                 }
 1365 
 1366                 bzero(freeme, i);
 1367 
 1368                 ssup = (struct sadb_supported *) freeme;
 1369                 ssup->sadb_supported_len = i / sizeof(uint64_t);
 1370 
 1371                 {
 1372                         void *p = freeme + sizeof(struct sadb_supported);
 1373 
 1374                         bcopy(&calgs[0], p, sizeof(calgs));
 1375                 }
 1376 
 1377                 headers[SADB_X_EXT_SUPPORTED_COMP] = freeme;
 1378 
 1379                 break;
 1380 
 1381         case SADB_ACQUIRE:
 1382         case SADB_EXPIRE:
 1383                 /* Nothing to handle */
 1384                 rval = 0;
 1385                 break;
 1386 
 1387         case SADB_FLUSH:
 1388                 rval = 0;
 1389 
 1390                 switch (smsg->sadb_msg_satype) {
 1391                 case SADB_SATYPE_UNSPEC:
 1392                         s = spltdb();
 1393 
 1394                         /*
 1395                          * Go through the list of policies, delete those that
 1396                          * are not socket-attached.
 1397                          */
 1398                         for (ipo = TAILQ_FIRST(&ipsec_policy_head);
 1399                             ipo != NULL; ipo = tmpipo) {
 1400                                 tmpipo = TAILQ_NEXT(ipo, ipo_list);
 1401                                 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
 1402                                         ipsec_delete_policy(ipo);
 1403                         }
 1404                         splx(s);
 1405                         /* FALLTHROUGH */
 1406                 case SADB_SATYPE_AH:
 1407                 case SADB_SATYPE_ESP:
 1408                 case SADB_X_SATYPE_IPIP:
 1409                 case SADB_X_SATYPE_IPCOMP:
 1410 #ifdef TCP_SIGNATURE
 1411                 case SADB_X_SATYPE_TCPSIGNATURE:
 1412 #endif /* TCP_SIGNATURE */
 1413                         s = spltdb();
 1414 
 1415                         tdb_walk(pfkeyv2_flush_walker,
 1416                             (u_int8_t *) &(smsg->sadb_msg_satype));
 1417 
 1418                         splx(s);
 1419                         break;
 1420 
 1421                 default:
 1422                         rval = EINVAL; /* Unknown/unsupported type */
 1423                 }
 1424 
 1425                 break;
 1426 
 1427         case SADB_DUMP:
 1428         {
 1429                 struct dump_state dump_state;
 1430                 dump_state.sadb_msg = (struct sadb_msg *) headers[0];
 1431                 dump_state.socket = socket;
 1432 
 1433                 s = spltdb();
 1434                 rval = tdb_walk(pfkeyv2_dump_walker, &dump_state);
 1435                 splx(s);
 1436 
 1437                 if (!rval)
 1438                         goto realret;
 1439 
 1440                 if ((rval == ENOMEM) || (rval == ENOBUFS))
 1441                         rval = 0;
 1442         }
 1443         break;
 1444 
 1445         case SADB_X_GRPSPIS:
 1446         {
 1447                 struct tdb *tdb1, *tdb2, *tdb3;
 1448                 struct sadb_protocol *sa_proto;
 1449 
 1450                 ssa = (struct sadb_sa *) headers[SADB_EXT_SA];
 1451                 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] +
 1452                     sizeof(struct sadb_address));
 1453 
 1454                 s = spltdb();
 1455 
 1456                 tdb1 = gettdb(ssa->sadb_sa_spi, sunionp,
 1457                     SADB_X_GETSPROTO(smsg->sadb_msg_satype));
 1458                 if (tdb1 == NULL) {
 1459                         rval = ESRCH;
 1460                         goto splxret;
 1461                 }
 1462 
 1463                 ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
 1464                 sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] +
 1465                     sizeof(struct sadb_address));
 1466                 sa_proto = ((struct sadb_protocol *) headers[SADB_X_EXT_PROTOCOL]);
 1467 
 1468                 tdb2 = gettdb(ssa->sadb_sa_spi, sunionp,
 1469                     SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
 1470                 if (tdb2 == NULL) {
 1471                         rval = ESRCH;
 1472                         goto splxret;
 1473                 }
 1474 
 1475                 /* Detect cycles */
 1476                 for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext)
 1477                         if (tdb3 == tdb1) {
 1478                                 rval = ESRCH;
 1479                                 goto splxret;
 1480                         }
 1481 
 1482                 /* Maintenance */
 1483                 if ((tdb1->tdb_onext) &&
 1484                     (tdb1->tdb_onext->tdb_inext == tdb1))
 1485                         tdb1->tdb_onext->tdb_inext = NULL;
 1486 
 1487                 if ((tdb2->tdb_inext) &&
 1488                     (tdb2->tdb_inext->tdb_onext == tdb2))
 1489                         tdb2->tdb_inext->tdb_onext = NULL;
 1490 
 1491                 /* Link them */
 1492                 tdb1->tdb_onext = tdb2;
 1493                 tdb2->tdb_inext = tdb1;
 1494 
 1495                 splx(s);
 1496         }
 1497         break;
 1498 
 1499         case SADB_X_DELFLOW:
 1500                 delflag = 1;
 1501                 /*FALLTHROUGH*/
 1502         case SADB_X_ADDFLOW:
 1503         {
 1504                 struct sadb_protocol *sab;
 1505                 union sockaddr_union *ssrc;
 1506                 struct route_enc re;
 1507                 int exists = 0;
 1508 
 1509                 sab = (struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE];
 1510 
 1511                 if ((sab->sadb_protocol_direction != IPSP_DIRECTION_IN) &&
 1512                     (sab->sadb_protocol_direction != IPSP_DIRECTION_OUT)) {
 1513                         rval = EINVAL;
 1514                         goto ret;
 1515                 }
 1516 
 1517                 /* If the security protocol wasn't specified, pretend it was ESP */
 1518                 if (smsg->sadb_msg_satype == 0)
 1519                         smsg->sadb_msg_satype = SADB_SATYPE_ESP;
 1520 
 1521                 if (headers[SADB_EXT_ADDRESS_DST])
 1522                         sunionp = (union sockaddr_union *)
 1523                             (headers[SADB_EXT_ADDRESS_DST] +
 1524                                 sizeof(struct sadb_address));
 1525                 else
 1526                         sunionp = NULL;
 1527 
 1528                 if (headers[SADB_EXT_ADDRESS_SRC])
 1529                         ssrc = (union sockaddr_union *)
 1530                             (headers[SADB_EXT_ADDRESS_SRC] +
 1531                                 sizeof(struct sadb_address));
 1532                 else
 1533                         ssrc = NULL;
 1534 
 1535                 import_flow(&encapdst, &encapnetmask,
 1536                     headers[SADB_X_EXT_SRC_FLOW], headers[SADB_X_EXT_SRC_MASK],
 1537                     headers[SADB_X_EXT_DST_FLOW], headers[SADB_X_EXT_DST_MASK],
 1538                     headers[SADB_X_EXT_PROTOCOL], headers[SADB_X_EXT_FLOW_TYPE]);
 1539 
 1540                 /* Determine whether the exact same SPD entry already exists. */
 1541                 bzero(&encapgw, sizeof(struct sockaddr_encap));
 1542                 bzero(&re, sizeof(struct route_enc));
 1543                 bcopy(&encapdst, &re.re_dst, sizeof(struct sockaddr_encap));
 1544 
 1545                 s = spltdb();
 1546 
 1547                 rtalloc((struct route *) &re);
 1548                 if (re.re_rt != NULL) {
 1549                         ipo = ((struct sockaddr_encap *) re.re_rt->rt_gateway)->sen_ipsp;
 1550                         RTFREE(re.re_rt);
 1551 
 1552                         /* Verify that the entry is identical */
 1553                         if (bcmp(&ipo->ipo_addr, &encapdst,
 1554                                 sizeof(struct sockaddr_encap)) ||
 1555                             bcmp(&ipo->ipo_mask, &encapnetmask,
 1556                                 sizeof(struct sockaddr_encap)))
 1557                                 ipo = NULL; /* Fall through */
 1558                         else
 1559                                 exists = 1;
 1560                 } else
 1561                         ipo = NULL;
 1562 
 1563                 /*
 1564                  * If the existing policy is static, only delete or update
 1565                  * it if the new one is also static.
 1566                  */
 1567                 if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) {
 1568                         if (!(sab->sadb_protocol_flags &
 1569                                 SADB_X_POLICYFLAGS_POLICY)) {
 1570                                 splx(s);
 1571                                 goto ret;
 1572                         }
 1573                 }
 1574 
 1575                 /* Delete ? */
 1576                 if (delflag) {
 1577                         if (exists) {
 1578                                 rval = ipsec_delete_policy(ipo);
 1579                                 splx(s);
 1580                                 goto ret;
 1581                         }
 1582 
 1583                         /* If we were asked to delete something non-existant, error. */
 1584                         splx(s);
 1585                         rval = ESRCH;
 1586                         break;
 1587                 }
 1588 
 1589                 if (!exists) {
 1590                         if (ipsec_policy_pool_initialized == 0) {
 1591                                 ipsec_policy_pool_initialized = 1;
 1592                                 pool_init(&ipsec_policy_pool,
 1593                                     sizeof(struct ipsec_policy), 0, 0, 0,
 1594                                     "ipsec policy", NULL);
 1595                         }
 1596 
 1597                         /* Allocate policy entry */
 1598                         ipo = pool_get(&ipsec_policy_pool, 0);
 1599                         if (ipo == NULL) {
 1600                                 splx(s);
 1601                                 rval = ENOMEM;
 1602                                 goto ret;
 1603                         }
 1604 
 1605                         bzero(ipo, sizeof(struct ipsec_policy));
 1606                         ipo->ipo_ref_count = 1;
 1607                         TAILQ_INIT(&ipo->ipo_acquires);
 1608 
 1609                         /* Finish initialization of SPD entry */
 1610                         encapgw.sen_len = SENT_LEN;
 1611                         encapgw.sen_family = PF_KEY;
 1612                         encapgw.sen_type = SENT_IPSP;
 1613                         encapgw.sen_ipsp = ipo;
 1614 
 1615                         /* Initialize policy entry */
 1616                         bcopy(&encapdst, &ipo->ipo_addr,
 1617                             sizeof(struct sockaddr_encap));
 1618                         bcopy(&encapnetmask, &ipo->ipo_mask,
 1619                             sizeof(struct sockaddr_encap));
 1620                 }
 1621 
 1622                 switch (((struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE])->sadb_protocol_proto) {
 1623                 case SADB_X_FLOW_TYPE_USE:
 1624                         ipo->ipo_type = IPSP_IPSEC_USE;
 1625                         break;
 1626 
 1627                 case SADB_X_FLOW_TYPE_ACQUIRE:
 1628                         ipo->ipo_type = IPSP_IPSEC_ACQUIRE;
 1629                         break;
 1630 
 1631                 case SADB_X_FLOW_TYPE_REQUIRE:
 1632                         ipo->ipo_type = IPSP_IPSEC_REQUIRE;
 1633                         break;
 1634 
 1635                 case SADB_X_FLOW_TYPE_DENY:
 1636                         ipo->ipo_type = IPSP_DENY;
 1637                         break;
 1638 
 1639                 case SADB_X_FLOW_TYPE_BYPASS:
 1640                         ipo->ipo_type = IPSP_PERMIT;
 1641                         break;
 1642 
 1643                 case SADB_X_FLOW_TYPE_DONTACQ:
 1644                         ipo->ipo_type = IPSP_IPSEC_DONTACQ;
 1645                         break;
 1646 
 1647                 default:
 1648                         if (!exists)
 1649                                 pool_put(&ipsec_policy_pool, ipo);
 1650                         else
 1651                                 ipsec_delete_policy(ipo);
 1652 
 1653                         splx(s);
 1654                         rval = EINVAL;
 1655                         goto ret;
 1656                 }
 1657 
 1658                 if (sab->sadb_protocol_flags & SADB_X_POLICYFLAGS_POLICY)
 1659                         ipo->ipo_flags |= IPSP_POLICY_STATIC;
 1660 
 1661                 if (sunionp)
 1662                         bcopy(sunionp, &ipo->ipo_dst,
 1663                             sizeof(union sockaddr_union));
 1664                 else
 1665                         bzero(&ipo->ipo_dst, sizeof(union sockaddr_union));
 1666 
 1667                 if (ssrc)
 1668                         bcopy(ssrc, &ipo->ipo_src,
 1669                             sizeof(union sockaddr_union));
 1670                 else
 1671                         bzero(&ipo->ipo_src, sizeof(union sockaddr_union));
 1672 
 1673                 ipo->ipo_sproto = SADB_X_GETSPROTO(smsg->sadb_msg_satype);
 1674 
 1675                 if (ipo->ipo_srcid) {
 1676                         ipsp_reffree(ipo->ipo_srcid);
 1677                         ipo->ipo_srcid = NULL;
 1678                 }
 1679 
 1680                 if (ipo->ipo_dstid) {
 1681                         ipsp_reffree(ipo->ipo_dstid);
 1682                         ipo->ipo_dstid = NULL;
 1683                 }
 1684 
 1685                 if ((sid = headers[SADB_EXT_IDENTITY_SRC]) != NULL) {
 1686                         int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
 1687                             sizeof(struct sadb_ident);
 1688 
 1689                         MALLOC(ipo->ipo_srcid, struct ipsec_ref *, clen +
 1690                             sizeof(struct ipsec_ref), M_CREDENTIALS, M_DONTWAIT);
 1691                         if (ipo->ipo_srcid == NULL) {
 1692                                 if (exists)
 1693                                         ipsec_delete_policy(ipo);
 1694                                 else
 1695                                         pool_put(&ipsec_policy_pool, ipo);
 1696                                 splx(s);
 1697                                 rval = ENOBUFS;
 1698                                 goto ret;
 1699                         }
 1700                         ipo->ipo_srcid->ref_type = sid->sadb_ident_type;
 1701                         ipo->ipo_srcid->ref_len = clen;
 1702                         ipo->ipo_srcid->ref_count = 1;
 1703                         ipo->ipo_srcid->ref_malloctype = M_CREDENTIALS;
 1704                         bcopy(sid + 1, ipo->ipo_srcid + 1, ipo->ipo_srcid->ref_len);
 1705                 }
 1706 
 1707                 if ((sid = headers[SADB_EXT_IDENTITY_DST]) != NULL) {
 1708                         int clen =  (sid->sadb_ident_len * sizeof(u_int64_t)) -
 1709                             sizeof(struct sadb_ident);
 1710 
 1711                         MALLOC(ipo->ipo_dstid, struct ipsec_ref *,
 1712                             clen + sizeof(struct ipsec_ref),
 1713                             M_CREDENTIALS, M_DONTWAIT);
 1714                         if (ipo->ipo_dstid == NULL) {
 1715                                 if (exists)
 1716                                         ipsec_delete_policy(ipo);
 1717                                 else {
 1718                                         if (ipo->ipo_dstid)
 1719                                                 ipsp_reffree(ipo->ipo_dstid);
 1720                                         pool_put(&ipsec_policy_pool, ipo);
 1721                                 }
 1722 
 1723                                 splx(s);
 1724                                 rval = ENOBUFS;
 1725                                 goto ret;
 1726                         }
 1727                         ipo->ipo_dstid->ref_type = sid->sadb_ident_type;
 1728                         ipo->ipo_dstid->ref_len = clen;
 1729                         ipo->ipo_dstid->ref_count = 1;
 1730                         ipo->ipo_dstid->ref_malloctype = M_CREDENTIALS;
 1731                         bcopy(sid + 1, ipo->ipo_dstid + 1,
 1732                             ipo->ipo_dstid->ref_len);
 1733                 }
 1734 
 1735                 /* Flow type */
 1736                 if (!exists) {
 1737                         /* Add SPD entry */
 1738                         if ((rval = rtrequest(RTM_ADD,
 1739                                  (struct sockaddr *) &encapdst,
 1740                                  (struct sockaddr *) &encapgw,
 1741                                  (struct sockaddr *) &encapnetmask,
 1742                                  RTF_UP | RTF_GATEWAY | RTF_STATIC,
 1743                                  (struct rtentry **) 0, 0)) != 0) {
 1744                                 /* Remove from linked list of policies on TDB */
 1745                                 if (ipo->ipo_tdb)
 1746                                         TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
 1747                                             ipo, ipo_tdb_next);
 1748 
 1749                                 if (ipo->ipo_srcid)
 1750                                         ipsp_reffree(ipo->ipo_srcid);
 1751                                 if (ipo->ipo_dstid)
 1752                                         ipsp_reffree(ipo->ipo_dstid);
 1753                                 pool_put(&ipsec_policy_pool, ipo);
 1754 
 1755                                 splx(s);
 1756                                 goto ret;
 1757                         }
 1758 
 1759                         TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
 1760                         ipsec_in_use++;
 1761                 } else {
 1762                         ipo->ipo_last_searched = ipo->ipo_flags = 0;
 1763                 }
 1764 
 1765                 splx(s);
 1766         }
 1767         break;
 1768 
 1769         case SADB_X_PROMISC:
 1770                 if (len >= 2 * sizeof(struct sadb_msg)) {
 1771                         struct mbuf *packet;
 1772 
 1773                         if ((rval = pfdatatopacket(message, len, &packet)) != 0)
 1774                                 goto ret;
 1775 
 1776                         for (so = pfkeyv2_sockets; so; so = so->next)
 1777                                 if ((so != pfkeyv2_socket) &&
 1778                                     (!smsg->sadb_msg_seq ||
 1779                                     (smsg->sadb_msg_seq == pfkeyv2_socket->pid)))
 1780                                         pfkey_sendup(so->socket, packet, 1);
 1781 
 1782                         m_freem(packet);
 1783                 } else {
 1784                         if (len != sizeof(struct sadb_msg)) {
 1785                                 rval = EINVAL;
 1786                                 goto ret;
 1787                         }
 1788 
 1789                         i = (pfkeyv2_socket->flags &
 1790                             PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0;
 1791                         j = smsg->sadb_msg_satype ? 1 : 0;
 1792 
 1793                         if (i ^ j) {
 1794                                 if (j) {
 1795                                         pfkeyv2_socket->flags |=
 1796                                             PFKEYV2_SOCKETFLAGS_PROMISC;
 1797                                         npromisc++;
 1798                                 } else {
 1799                                         pfkeyv2_socket->flags &=
 1800                                             ~PFKEYV2_SOCKETFLAGS_PROMISC;
 1801                                         npromisc--;
 1802                                 }
 1803                         }
 1804                 }
 1805         
 1806 
 1807                 break;
 1808 
 1809         default:
 1810                 rval = EINVAL;
 1811                 goto ret;
 1812         }
 1813 
 1814 ret:
 1815         if (rval) {
 1816                 if ((rval == EINVAL) || (rval == ENOMEM) || (rval == ENOBUFS))
 1817                         goto realret;
 1818 
 1819                 for (i = 1; i <= SADB_EXT_MAX; i++)
 1820                         headers[i] = NULL;
 1821 
 1822                 smsg->sadb_msg_errno = abs(rval);
 1823         } else {
 1824                 uint64_t seen = 0LL;
 1825 
 1826                 for (i = 1; i <= SADB_EXT_MAX; i++)
 1827                         if (headers[i])
 1828                                 seen |= (1LL << i);
 1829 
 1830                 if ((seen & sadb_exts_allowed_out[smsg->sadb_msg_type])
 1831                     != seen)
 1832                         goto realret;
 1833 
 1834                 if ((seen & sadb_exts_required_out[smsg->sadb_msg_type]) !=
 1835                     sadb_exts_required_out[smsg->sadb_msg_type])
 1836                         goto realret;
 1837         }
 1838 
 1839         rval = pfkeyv2_sendmessage(headers, mode, socket, 0, 0);
 1840 
 1841 realret:
 1842         if (freeme)
 1843                 free(freeme, M_PFKEY);
 1844 
 1845         free(message, M_PFKEY);
 1846 
 1847         return (rval);
 1848 
 1849 splxret:
 1850         splx(s);
 1851         goto ret;
 1852 }
 1853 
 1854 /*
 1855  * Send an ACQUIRE message to key management, to get a new SA.
 1856  */
 1857 int
 1858 pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw,
 1859     union sockaddr_union *laddr, u_int32_t *seq, struct sockaddr_encap *ddst)
 1860 {
 1861         void *p, *headers[SADB_EXT_MAX + 1], *buffer = NULL;
 1862         struct sadb_ident *srcid, *dstid;
 1863         struct sadb_x_cred *lcred, *lauth;
 1864         struct sadb_comb *sadb_comb;
 1865         struct sadb_address *sadd;
 1866         struct sadb_prop *sa_prop;
 1867         struct sadb_msg *smsg;
 1868         int rval = 0;
 1869         int i, j;
 1870 
 1871         *seq = pfkeyv2_seq++;
 1872 
 1873         if (!nregistered) {
 1874                 rval = ESRCH;
 1875                 goto ret;
 1876         }
 1877 
 1878         /* How large a buffer do we need... XXX we only do one proposal for now */
 1879         i = sizeof(struct sadb_msg) +
 1880             (laddr == NULL ? 0 : sizeof(struct sadb_address) +
 1881                 PADUP(SA_LEN(&ipo->ipo_src.sa))) +
 1882             sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa)) +
 1883             sizeof(struct sadb_prop) + 1 * sizeof(struct sadb_comb);
 1884 
 1885         if (ipo->ipo_srcid)
 1886                 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
 1887 
 1888         if (ipo->ipo_dstid)
 1889                 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
 1890 
 1891         if (ipo->ipo_local_cred)
 1892                 i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
 1893 
 1894         if (ipo->ipo_local_auth)
 1895                 i += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
 1896 
 1897         /* Allocate */
 1898         if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
 1899                 rval = ENOMEM;
 1900                 goto ret;
 1901         }
 1902 
 1903         bzero(headers, sizeof(headers));
 1904 
 1905         buffer = p;
 1906         bzero(p, i);
 1907 
 1908         headers[0] = p;
 1909         p += sizeof(struct sadb_msg);
 1910 
 1911         smsg = (struct sadb_msg *) headers[0];
 1912         smsg->sadb_msg_version = PF_KEY_V2;
 1913         smsg->sadb_msg_type = SADB_ACQUIRE;
 1914         smsg->sadb_msg_len = i / sizeof(uint64_t);
 1915         smsg->sadb_msg_seq = *seq;
 1916 
 1917         if (ipo->ipo_sproto == IPPROTO_ESP)
 1918                 smsg->sadb_msg_satype = SADB_SATYPE_ESP;
 1919         else if (ipo->ipo_sproto == IPPROTO_AH)
 1920                 smsg->sadb_msg_satype = SADB_SATYPE_AH;
 1921         else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
 1922                 smsg->sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
 1923 
 1924         if (laddr) {
 1925                 headers[SADB_EXT_ADDRESS_SRC] = p;
 1926                 p += sizeof(struct sadb_address) + PADUP(SA_LEN(&laddr->sa));
 1927                 sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_SRC];
 1928                 sadd->sadb_address_len = (sizeof(struct sadb_address) +
 1929                     SA_LEN(&laddr->sa) + sizeof(uint64_t) - 1) /
 1930                     sizeof(uint64_t);
 1931                 bcopy(laddr, headers[SADB_EXT_ADDRESS_SRC] +
 1932                     sizeof(struct sadb_address), SA_LEN(&laddr->sa));
 1933         }
 1934 
 1935         headers[SADB_EXT_ADDRESS_DST] = p;
 1936         p += sizeof(struct sadb_address) + PADUP(SA_LEN(&gw->sa));
 1937         sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_DST];
 1938         sadd->sadb_address_len = (sizeof(struct sadb_address) +
 1939             SA_LEN(&gw->sa) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
 1940         bcopy(gw, headers[SADB_EXT_ADDRESS_DST] + sizeof(struct sadb_address),
 1941             SA_LEN(&gw->sa));
 1942 
 1943         if (ipo->ipo_srcid) {
 1944                 headers[SADB_EXT_IDENTITY_SRC] = p;
 1945                 p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
 1946                 srcid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_SRC];
 1947                 srcid->sadb_ident_len = (sizeof(struct sadb_ident) +
 1948                     PADUP(ipo->ipo_srcid->ref_len)) / sizeof(u_int64_t);
 1949                 srcid->sadb_ident_type = ipo->ipo_srcid->ref_type;
 1950                 bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
 1951                     sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
 1952         }
 1953 
 1954         if (ipo->ipo_dstid) {
 1955                 headers[SADB_EXT_IDENTITY_DST] = p;
 1956                 p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
 1957                 dstid = (struct sadb_ident *) headers[SADB_EXT_IDENTITY_DST];
 1958                 dstid->sadb_ident_len = (sizeof(struct sadb_ident) +
 1959                     PADUP(ipo->ipo_dstid->ref_len)) / sizeof(u_int64_t);
 1960                 dstid->sadb_ident_type = ipo->ipo_dstid->ref_type;
 1961                 bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
 1962                     sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
 1963         }
 1964 
 1965         if (ipo->ipo_local_cred) {
 1966                 headers[SADB_X_EXT_LOCAL_CREDENTIALS] = p;
 1967                 p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_cred->ref_len);
 1968                 lcred = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_CREDENTIALS];
 1969                 lcred->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
 1970                     PADUP(ipo->ipo_local_cred->ref_len)) / sizeof(u_int64_t);
 1971                 switch (ipo->ipo_local_cred->ref_type) {
 1972                 case IPSP_CRED_KEYNOTE:
 1973                         lcred->sadb_x_cred_type = SADB_X_CREDTYPE_KEYNOTE;
 1974                         break;
 1975                 case IPSP_CRED_X509:
 1976                         lcred->sadb_x_cred_type = SADB_X_CREDTYPE_X509;
 1977                         break;
 1978                 }
 1979                 bcopy(ipo->ipo_local_cred + 1, headers[SADB_X_EXT_LOCAL_CREDENTIALS] +
 1980                     sizeof(struct sadb_x_cred), ipo->ipo_local_cred->ref_len);
 1981         }
 1982 
 1983         if (ipo->ipo_local_auth) {
 1984                 headers[SADB_X_EXT_LOCAL_AUTH] = p;
 1985                 p += sizeof(struct sadb_x_cred) + PADUP(ipo->ipo_local_auth->ref_len);
 1986                 lauth = (struct sadb_x_cred *) headers[SADB_X_EXT_LOCAL_AUTH];
 1987                 lauth->sadb_x_cred_len = (sizeof(struct sadb_x_cred) +
 1988                     PADUP(ipo->ipo_local_auth->ref_len)) / sizeof(u_int64_t);
 1989                 switch (ipo->ipo_local_auth->ref_type) {
 1990                 case IPSP_AUTH_PASSPHRASE:
 1991                         lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_PASSPHRASE;
 1992                         break;
 1993                 case IPSP_AUTH_RSA:
 1994                         lauth->sadb_x_cred_type = SADB_X_AUTHTYPE_RSA;
 1995                         break;
 1996                 }
 1997 
 1998                 bcopy(ipo->ipo_local_auth + 1, headers[SADB_X_EXT_LOCAL_AUTH] +
 1999                     sizeof(struct sadb_x_cred), ipo->ipo_local_auth->ref_len);
 2000         }
 2001 
 2002         headers[SADB_EXT_PROPOSAL] = p;
 2003         p += sizeof(struct sadb_prop);
 2004         sa_prop = (struct sadb_prop *) headers[SADB_EXT_PROPOSAL];
 2005         sa_prop->sadb_prop_num = 1; /* XXX One proposal only */
 2006         sa_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
 2007             (sizeof(struct sadb_comb) * sa_prop->sadb_prop_num)) /
 2008             sizeof(uint64_t);
 2009 
 2010         sadb_comb = p;
 2011 
 2012         /* XXX Should actually ask the crypto layer what's supported */
 2013         for (j = 0; j < sa_prop->sadb_prop_num; j++) {
 2014                 sadb_comb->sadb_comb_flags = 0;
 2015 
 2016                 if (ipsec_require_pfs)
 2017                         sadb_comb->sadb_comb_flags |= SADB_SAFLAGS_PFS;
 2018 
 2019                 /* Set the encryption algorithm */
 2020                 if (ipo->ipo_sproto == IPPROTO_ESP) {
 2021                         if (!strncasecmp(ipsec_def_enc, "aes",
 2022                             sizeof("aes"))) {
 2023                                 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES;
 2024                                 sadb_comb->sadb_comb_encrypt_minbits = 128;
 2025                                 sadb_comb->sadb_comb_encrypt_maxbits = 256;
 2026                         } else if (!strncasecmp(ipsec_def_enc, "aesctr",
 2027                             sizeof("aesctr"))) {
 2028                                 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR;
 2029                                 sadb_comb->sadb_comb_encrypt_minbits = 128+32;
 2030                                 sadb_comb->sadb_comb_encrypt_maxbits = 256+32;
 2031                         } else if (!strncasecmp(ipsec_def_enc, "3des",
 2032                             sizeof("3des"))) {
 2033                                 sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC;
 2034                                 sadb_comb->sadb_comb_encrypt_minbits = 192;
 2035                                 sadb_comb->sadb_comb_encrypt_maxbits = 192;
 2036                         } else if (!strncasecmp(ipsec_def_enc, "des",
 2037                             sizeof("des"))) {
 2038                                 sadb_comb->sadb_comb_encrypt = SADB_EALG_DESCBC;
 2039                                 sadb_comb->sadb_comb_encrypt_minbits = 64;
 2040                                 sadb_comb->sadb_comb_encrypt_maxbits = 64;
 2041                         } else if (!strncasecmp(ipsec_def_enc, "blowfish",
 2042                             sizeof("blowfish"))) {
 2043                                 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_BLF;
 2044                                 sadb_comb->sadb_comb_encrypt_minbits = 40;
 2045                                 sadb_comb->sadb_comb_encrypt_maxbits = BLF_MAXKEYLEN * 8;
 2046                         } else if (!strncasecmp(ipsec_def_enc, "skipjack",
 2047                             sizeof("skipjack"))) {
 2048                                 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_SKIPJACK;
 2049                                 sadb_comb->sadb_comb_encrypt_minbits = 80;
 2050                                 sadb_comb->sadb_comb_encrypt_maxbits = 80;
 2051                         } else if (!strncasecmp(ipsec_def_enc, "cast128",
 2052                             sizeof("cast128"))) {
 2053                                 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_CAST;
 2054                                 sadb_comb->sadb_comb_encrypt_minbits = 40;
 2055                                 sadb_comb->sadb_comb_encrypt_maxbits = 128;
 2056                         }
 2057                 } else if (ipo->ipo_sproto == IPPROTO_IPCOMP) {
 2058                         /* Set the compression algorithm */
 2059                         if (!strncasecmp(ipsec_def_comp, "deflate",
 2060                             sizeof("deflate"))) {
 2061                                 sadb_comb->sadb_comb_encrypt = SADB_X_CALG_DEFLATE;
 2062                                 sadb_comb->sadb_comb_encrypt_minbits = 0;
 2063                                 sadb_comb->sadb_comb_encrypt_maxbits = 0;
 2064                         } else if (!strncasecmp(ipsec_def_comp, "lzs",
 2065                             sizeof("lzs"))) {
 2066                                 sadb_comb->sadb_comb_encrypt = SADB_X_CALG_LZS;
 2067                                 sadb_comb->sadb_comb_encrypt_minbits = 0;
 2068                                 sadb_comb->sadb_comb_encrypt_maxbits = 0;
 2069                         }
 2070                 }
 2071 
 2072                 /* Set the authentication algorithm */
 2073                 if (!strncasecmp(ipsec_def_auth, "hmac-sha1",
 2074                     sizeof("hmac-sha1"))) {
 2075                         sadb_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC;
 2076                         sadb_comb->sadb_comb_auth_minbits = 160;
 2077                         sadb_comb->sadb_comb_auth_maxbits = 160;
 2078                 } else if (!strncasecmp(ipsec_def_auth, "hmac-ripemd160",
 2079                     sizeof("hmac_ripemd160"))) {
 2080                         sadb_comb->sadb_comb_auth = SADB_X_AALG_RIPEMD160HMAC;
 2081                         sadb_comb->sadb_comb_auth_minbits = 160;
 2082                         sadb_comb->sadb_comb_auth_maxbits = 160;
 2083                 } else if (!strncasecmp(ipsec_def_auth, "hmac-md5",
 2084                     sizeof("hmac-md5"))) {
 2085                         sadb_comb->sadb_comb_auth = SADB_AALG_MD5HMAC;
 2086                         sadb_comb->sadb_comb_auth_minbits = 128;
 2087                         sadb_comb->sadb_comb_auth_maxbits = 128;
 2088                 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-256",
 2089                     sizeof("hmac-sha2-256"))) {
 2090                         sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
 2091                         sadb_comb->sadb_comb_auth_minbits = 256;
 2092                         sadb_comb->sadb_comb_auth_maxbits = 256;
 2093                 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-384",
 2094                     sizeof("hmac-sha2-384"))) {
 2095                         sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_384;
 2096                         sadb_comb->sadb_comb_auth_minbits = 384;
 2097                         sadb_comb->sadb_comb_auth_maxbits = 384;
 2098                 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-512",
 2099                     sizeof("hmac-sha2-512"))) {
 2100                         sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_512;
 2101                         sadb_comb->sadb_comb_auth_minbits = 512;
 2102                         sadb_comb->sadb_comb_auth_maxbits = 512;
 2103                 }
 2104 
 2105                 sadb_comb->sadb_comb_soft_allocations = ipsec_soft_allocations;
 2106                 sadb_comb->sadb_comb_hard_allocations = ipsec_exp_allocations;
 2107 
 2108                 sadb_comb->sadb_comb_soft_bytes = ipsec_soft_bytes;
 2109                 sadb_comb->sadb_comb_hard_bytes = ipsec_exp_bytes;
 2110 
 2111                 sadb_comb->sadb_comb_soft_addtime = ipsec_soft_timeout;
 2112                 sadb_comb->sadb_comb_hard_addtime = ipsec_exp_timeout;
 2113 
 2114                 sadb_comb->sadb_comb_soft_usetime = ipsec_soft_first_use;
 2115                 sadb_comb->sadb_comb_hard_usetime = ipsec_exp_first_use;
 2116                 sadb_comb++;
 2117         }
 2118 
 2119         /* Send the ACQUIRE message to all compliant registered listeners. */
 2120         if ((rval = pfkeyv2_sendmessage(headers,
 2121             PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0))
 2122             != 0)
 2123                 goto ret;
 2124 
 2125         rval = 0;
 2126 ret:
 2127         if (buffer != NULL) {
 2128                 bzero(buffer, i);
 2129                 free(buffer, M_PFKEY);
 2130         }
 2131 
 2132         return (rval);
 2133 }
 2134 
 2135 /*
 2136  * Notify key management that an expiration went off. The second argument
 2137  * specifies the type of expiration (soft or hard).
 2138  */
 2139 int
 2140 pfkeyv2_expire(struct tdb *sa, u_int16_t type)
 2141 {
 2142         void *p, *headers[SADB_EXT_MAX+1], *buffer = NULL;
 2143         struct sadb_msg *smsg;
 2144         int rval = 0;
 2145         int i;
 2146 
 2147         switch (sa->tdb_sproto) {
 2148         case IPPROTO_AH:
 2149         case IPPROTO_ESP:
 2150         case IPPROTO_IPIP:
 2151         case IPPROTO_IPCOMP:
 2152 #ifdef TCP_SIGNATURE
 2153         case IPPROTO_TCP:
 2154 #endif /* TCP_SIGNATURE */
 2155                 break;
 2156 
 2157         default:
 2158                 rval = EOPNOTSUPP;
 2159                 goto ret;
 2160         }
 2161 
 2162         i = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) +
 2163             2 * sizeof(struct sadb_lifetime) +
 2164             sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_src.sa)) +
 2165             sizeof(struct sadb_address) + PADUP(SA_LEN(&sa->tdb_dst.sa));
 2166 
 2167         if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
 2168                 rval = ENOMEM;
 2169                 goto ret;
 2170         }
 2171 
 2172         bzero(headers, sizeof(headers));
 2173 
 2174         buffer = p;
 2175         bzero(p, i);
 2176 
 2177         headers[0] = p;
 2178         p += sizeof(struct sadb_msg);
 2179 
 2180         smsg = (struct sadb_msg *) headers[0];
 2181         smsg->sadb_msg_version = PF_KEY_V2;
 2182         smsg->sadb_msg_type = SADB_EXPIRE;
 2183         smsg->sadb_msg_satype = sa->tdb_satype;
 2184         smsg->sadb_msg_len = i / sizeof(uint64_t);
 2185         smsg->sadb_msg_seq = pfkeyv2_seq++;
 2186 
 2187         headers[SADB_EXT_SA] = p;
 2188         export_sa(&p, sa);
 2189 
 2190         headers[SADB_EXT_LIFETIME_CURRENT] = p;
 2191         export_lifetime(&p, sa, 2);
 2192 
 2193         headers[type] = p;
 2194         export_lifetime(&p, sa, type == SADB_EXT_LIFETIME_SOFT ?
 2195             PFKEYV2_LIFETIME_SOFT : PFKEYV2_LIFETIME_HARD);
 2196 
 2197         headers[SADB_EXT_ADDRESS_SRC] = p;
 2198         export_address(&p, (struct sockaddr *) &sa->tdb_src);
 2199 
 2200         headers[SADB_EXT_ADDRESS_DST] = p;
 2201         export_address(&p, (struct sockaddr *) &sa->tdb_dst);
 2202 
 2203         if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST,
 2204             NULL, 0, 0)) != 0)
 2205                 goto ret;
 2206 
 2207         rval = 0;
 2208 
 2209  ret:
 2210         if (buffer != NULL) {
 2211                 bzero(buffer, i);
 2212                 free(buffer, M_PFKEY);
 2213         }
 2214 
 2215         return (rval);
 2216 }
 2217 
 2218 struct pfkeyv2_sysctl_walk {
 2219         void            *w_where;
 2220         size_t           w_len;
 2221         int              w_op;
 2222         u_int8_t         w_satype;
 2223 };
 2224 
 2225 int
 2226 pfkeyv2_sysctl_walker(struct tdb *sa, void *arg, int last)
 2227 {
 2228         struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
 2229         void *buffer = NULL;
 2230         int error = 0;
 2231         int buflen, i;
 2232 
 2233         if (w->w_satype != SADB_SATYPE_UNSPEC &&
 2234             w->w_satype != sa->tdb_satype)
 2235                 return (0);
 2236 
 2237         if (w->w_where) {
 2238                 void *headers[SADB_EXT_MAX+1];
 2239                 struct sadb_msg msg;
 2240 
 2241                 bzero(headers, sizeof(headers));
 2242                 if ((error = pfkeyv2_get(sa, headers, &buffer, &buflen)) != 0)
 2243                         goto done;
 2244                 if (w->w_len < sizeof(msg) + buflen) {
 2245                         error = ENOMEM;
 2246                         goto done;
 2247                 }
 2248                 /* prepend header */
 2249                 bzero(&msg, sizeof(msg));
 2250                 msg.sadb_msg_version = PF_KEY_V2;
 2251                 msg.sadb_msg_satype = sa->tdb_satype;
 2252                 msg.sadb_msg_type = SADB_DUMP;
 2253                 msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
 2254                 if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
 2255                         goto done;
 2256                 w->w_where += sizeof(msg);
 2257                 w->w_len -= sizeof(msg);
 2258                 /* set extension type */
 2259                 for (i = 1; i <= SADB_EXT_MAX; i++)
 2260                         if (headers[i])
 2261                                 ((struct sadb_ext *)
 2262                                     headers[i])->sadb_ext_type = i;
 2263                 if ((error = copyout(buffer, w->w_where, buflen)) != 0)
 2264                         goto done;
 2265                 w->w_where += buflen;
 2266                 w->w_len -= buflen;
 2267         } else {
 2268                 if ((error = pfkeyv2_get(sa, NULL, NULL, &buflen)) != 0)
 2269                         return (error);
 2270                 w->w_len += buflen;
 2271                 w->w_len += sizeof(struct sadb_msg);
 2272         }
 2273 
 2274 done:
 2275         if (buffer)
 2276                 free(buffer, M_PFKEY);
 2277         return (error);
 2278 }
 2279 
 2280 int
 2281 pfkeyv2_dump_policy(struct ipsec_policy *ipo, void **headers, void **buffer,
 2282     int *lenp)
 2283 {
 2284         struct sadb_ident *ident;
 2285         int i, rval, perm;
 2286         void *p;
 2287 
 2288         /* Find how much space we need. */
 2289         i = 2 * sizeof(struct sadb_protocol);
 2290 
 2291         /* We'll need four of them: src, src mask, dst, dst mask. */
 2292         switch (ipo->ipo_addr.sen_type) {
 2293 #ifdef INET
 2294         case SENT_IP4:
 2295                 i += 4 * PADUP(sizeof(struct sockaddr_in));
 2296                 i += 4 * sizeof(struct sadb_address);
 2297                 break;
 2298 #endif /* INET */
 2299 #ifdef INET6
 2300         case SENT_IP6:
 2301                 i += 4 * PADUP(sizeof(struct sockaddr_in6));
 2302                 i += 4 * sizeof(struct sadb_address);
 2303                 break;
 2304 #endif /* INET6 */
 2305         default:
 2306                 return (EINVAL);
 2307         }
 2308 
 2309         /* Local address, might be zeroed. */
 2310         switch (ipo->ipo_src.sa.sa_family) {
 2311         case 0:
 2312                 break;
 2313 #ifdef INET
 2314         case AF_INET:
 2315                 i += PADUP(sizeof(struct sockaddr_in));
 2316                 i += sizeof(struct sadb_address);
 2317                 break;
 2318 #endif /* INET */
 2319 #ifdef INET6
 2320         case AF_INET6:
 2321                 i += PADUP(sizeof(struct sockaddr_in6));
 2322                 i += sizeof(struct sadb_address);
 2323                 break;
 2324 #endif /* INET6 */
 2325         default:
 2326                 return (EINVAL);
 2327         }
 2328 
 2329         /* Remote address, might be zeroed. XXX ??? */
 2330         switch (ipo->ipo_dst.sa.sa_family) {
 2331         case 0:
 2332                 break;
 2333 #ifdef INET
 2334         case AF_INET:
 2335                 i += PADUP(sizeof(struct sockaddr_in));
 2336                 i += sizeof(struct sadb_address);
 2337                 break;
 2338 #endif /* INET */
 2339 #ifdef INET6
 2340         case AF_INET6:
 2341                 i += PADUP(sizeof(struct sockaddr_in6));
 2342                 i += sizeof(struct sadb_address);
 2343                 break;
 2344 #endif /* INET6 */
 2345         default:
 2346                 return (EINVAL);
 2347         }
 2348 
 2349         if (ipo->ipo_srcid)
 2350                 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
 2351         if (ipo->ipo_dstid)
 2352                 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
 2353 
 2354         if (lenp)
 2355                 *lenp = i;
 2356 
 2357         if (buffer == NULL) {
 2358                 rval = 0;
 2359                 goto ret;
 2360         }
 2361 
 2362         if (!(p = malloc(i, M_PFKEY, M_DONTWAIT))) {
 2363                 rval = ENOMEM;
 2364                 goto ret;
 2365         } else {
 2366                 *buffer = p;
 2367                 bzero(p, i);
 2368         }
 2369 
 2370         /* Local address. */
 2371         if (ipo->ipo_src.sa.sa_family) {
 2372                 headers[SADB_EXT_ADDRESS_SRC] = p;
 2373                 export_address(&p, (struct sockaddr *)&ipo->ipo_src);
 2374         }
 2375         
 2376         /* Remote address. */
 2377         if (ipo->ipo_dst.sa.sa_family) {
 2378                 headers[SADB_EXT_ADDRESS_DST] = p;
 2379                 export_address(&p, (struct sockaddr *)&ipo->ipo_dst);
 2380         }
 2381 
 2382         /* Get actual flow. */
 2383         export_flow(&p, ipo->ipo_type, &ipo->ipo_addr, &ipo->ipo_mask,
 2384             headers);
 2385 
 2386         /* Add ids only when we are root. */
 2387         perm = suser(curproc, 0);
 2388         if (perm == 0 && ipo->ipo_srcid) {
 2389                 headers[SADB_EXT_IDENTITY_SRC] = p;
 2390                 p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_srcid->ref_len);
 2391                 ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_SRC];
 2392                 ident->sadb_ident_len = (sizeof(struct sadb_ident) +
 2393                     PADUP(ipo->ipo_srcid->ref_len)) / sizeof(uint64_t);
 2394                 ident->sadb_ident_type = ipo->ipo_srcid->ref_type;
 2395                 bcopy(ipo->ipo_srcid + 1, headers[SADB_EXT_IDENTITY_SRC] +
 2396                     sizeof(struct sadb_ident), ipo->ipo_srcid->ref_len);
 2397         }
 2398         if (perm == 0 && ipo->ipo_dstid) {
 2399                 headers[SADB_EXT_IDENTITY_DST] = p;
 2400                 p += sizeof(struct sadb_ident) + PADUP(ipo->ipo_dstid->ref_len);
 2401                 ident = (struct sadb_ident *)headers[SADB_EXT_IDENTITY_DST];
 2402                 ident->sadb_ident_len = (sizeof(struct sadb_ident) +
 2403                     PADUP(ipo->ipo_dstid->ref_len)) / sizeof(uint64_t);
 2404                 ident->sadb_ident_type = ipo->ipo_dstid->ref_type;
 2405                 bcopy(ipo->ipo_dstid + 1, headers[SADB_EXT_IDENTITY_DST] +
 2406                     sizeof(struct sadb_ident), ipo->ipo_dstid->ref_len);
 2407         }
 2408 
 2409         rval = 0;
 2410 ret:
 2411         return (rval);
 2412 }
 2413 
 2414 /*
 2415  * Caller is responsible for setting at least spltdb().
 2416  */
 2417 int
 2418 pfkeyv2_ipo_walk(int (*walker)(struct ipsec_policy *, void *), void *arg)
 2419 {
 2420         int rval = 0;
 2421         struct ipsec_policy *ipo;
 2422 
 2423         TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list)
 2424                 rval = walker(ipo, (void *)arg);
 2425         return (rval);
 2426 }
 2427 
 2428 int
 2429 pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg)
 2430 {
 2431         struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
 2432         void *buffer = 0;
 2433         int i, buflen, error = 0;
 2434 
 2435         /* Do not dump policies attached to a socket. */
 2436         if (ipo->ipo_flags & IPSP_POLICY_SOCKET)
 2437                 return (0);
 2438 
 2439         if (w->w_where) {
 2440                 void *headers[SADB_EXT_MAX + 1];
 2441                 struct sadb_msg msg;
 2442 
 2443                 bzero(headers, sizeof(headers));
 2444                 if ((error = pfkeyv2_dump_policy(ipo, headers, &buffer,
 2445                     &buflen)) != 0)
 2446                         goto done;
 2447                 if (w->w_len < buflen) {
 2448                         error = ENOMEM;
 2449                         goto done;
 2450                 }
 2451                 /* prepend header */
 2452                 bzero(&msg, sizeof(msg));
 2453                 msg.sadb_msg_version = PF_KEY_V2;
 2454                 if (ipo->ipo_sproto == IPPROTO_ESP)
 2455                         msg.sadb_msg_satype = SADB_SATYPE_ESP;
 2456                 else if (ipo->ipo_sproto == IPPROTO_AH)
 2457                         msg.sadb_msg_satype = SADB_SATYPE_AH;
 2458                 else if (ipo->ipo_sproto == IPPROTO_IPCOMP)
 2459                         msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP;
 2460                 else if (ipo->ipo_sproto == IPPROTO_IPIP)
 2461                         msg.sadb_msg_satype = SADB_X_SATYPE_IPIP;
 2462                 msg.sadb_msg_type = SADB_X_SPDDUMP;
 2463                 msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t);
 2464                 if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0)
 2465                         goto done;
 2466                 w->w_where += sizeof(msg);
 2467                 w->w_len -= sizeof(msg);
 2468                 /* set extension type */
 2469                 for (i = 1; i < SADB_EXT_MAX; i++)
 2470                         if (headers[i])
 2471                                 ((struct sadb_ext *)
 2472                                     headers[i])->sadb_ext_type = i;
 2473                 if ((error = copyout(buffer, w->w_where, buflen)) != 0)
 2474                         goto done;
 2475                 w->w_where += buflen;
 2476                 w->w_len -= buflen;
 2477         } else {
 2478                 if ((error = pfkeyv2_dump_policy(ipo, NULL, NULL,
 2479                     &buflen)) != 0)
 2480                         goto done;
 2481                 w->w_len += buflen;
 2482                 w->w_len += sizeof(struct sadb_msg);
 2483         }
 2484 
 2485 done:
 2486         if (buffer)
 2487                 free(buffer, M_PFKEY);
 2488         return (error);
 2489 }
 2490 
 2491 int
 2492 pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
 2493     void *new, size_t newlen)
 2494 {
 2495         struct pfkeyv2_sysctl_walk w;
 2496         int s, error = EINVAL;
 2497 
 2498         if (new)
 2499                 return (EPERM);
 2500         if (namelen < 1)
 2501                 return (EINVAL);
 2502         w.w_op = name[0];
 2503         w.w_satype = name[1];
 2504         w.w_where = oldp;
 2505         w.w_len = oldp ? *oldlenp : 0;
 2506 
 2507         switch(w.w_op) {
 2508         case NET_KEY_SADB_DUMP:
 2509                 if ((error = suser(curproc, 0)) != 0)
 2510                         return (error);
 2511                 s = spltdb();
 2512                 error = tdb_walk(pfkeyv2_sysctl_walker, &w);
 2513                 splx(s);
 2514                 if (oldp)
 2515                         *oldlenp = w.w_where - oldp;
 2516                 else
 2517                         *oldlenp = w.w_len;
 2518                 break;
 2519 
 2520         case NET_KEY_SPD_DUMP:
 2521                 s = spltdb();
 2522                 error = pfkeyv2_ipo_walk(pfkeyv2_sysctl_policydumper, &w);
 2523                 splx(s);
 2524                 if (oldp)
 2525                         *oldlenp = w.w_where - oldp;
 2526                 else
 2527                         *oldlenp = w.w_len;
 2528                 break;
 2529         }
 2530 
 2531         return (error);
 2532 }
 2533 
 2534 int
 2535 pfkeyv2_init(void)
 2536 {
 2537         int rval;
 2538 
 2539         bzero(&pfkeyv2_version, sizeof(struct pfkey_version));
 2540         pfkeyv2_version.protocol = PFKEYV2_PROTOCOL;
 2541         pfkeyv2_version.create = &pfkeyv2_create;
 2542         pfkeyv2_version.release = &pfkeyv2_release;
 2543         pfkeyv2_version.send = &pfkeyv2_send;
 2544         pfkeyv2_version.sysctl = &pfkeyv2_sysctl;
 2545 
 2546         rval = pfkey_register(&pfkeyv2_version);
 2547         return (rval);
 2548 }
 2549 
 2550 int
 2551 pfkeyv2_cleanup(void)
 2552 {
 2553         pfkey_unregister(&pfkeyv2_version);
 2554         return (0);
 2555 }

/* [<][>][^][v][top][bottom][index][help] */