The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net/pfkeyv2.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e92d03debd3679b85b774bf19a41d8e2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.