root/netinet/ip_spd.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipsp_spd_lookup
  2. ipsec_delete_policy
  3. ipsec_add_policy
  4. ipsec_update_policy
  5. ipsp_delete_acquire
  6. ipsp_pending_acquire
  7. ipsp_acquire_sa
  8. ipsp_spd_inp
  9. ipsec_get_acquire

    1 /* $OpenBSD: ip_spd.c,v 1.53 2007/02/14 00:53:48 jsg Exp $ */
    2 /*
    3  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
    4  *
    5  * Copyright (c) 2000-2001 Angelos D. Keromytis.
    6  *
    7  * Permission to use, copy, and modify this software with or without fee
    8  * is hereby granted, provided that this entire notice is included in
    9  * all copies of any software which is or includes a copy or
   10  * modification of this software.
   11  * You may use this code under the GNU public license if you so wish. Please
   12  * contribute changes back to the authors under this freer than GPL license
   13  * so that we may further the use of strong encryption without limitations to
   14  * all.
   15  *
   16  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   17  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   18  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   19  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   20  * PURPOSE.
   21  */
   22 
   23 #include <sys/param.h>
   24 #include <sys/systm.h>
   25 #include <sys/mbuf.h>
   26 #include <sys/socket.h>
   27 #include <sys/kernel.h>
   28 #include <sys/socketvar.h>
   29 #include <sys/protosw.h>
   30 
   31 #include <net/if.h>
   32 #include <net/route.h>
   33 #include <net/netisr.h>
   34 
   35 #ifdef INET
   36 #include <netinet/in.h>
   37 #include <netinet/in_systm.h>
   38 #include <netinet/ip.h>
   39 #include <netinet/in_pcb.h>
   40 #include <netinet/in_var.h>
   41 #endif /* INET */
   42 
   43 #ifdef INET6
   44 #ifndef INET
   45 #include <netinet/in.h>
   46 #endif
   47 #include <netinet6/in6_var.h>
   48 #endif /* INET6 */
   49 
   50 #include <netinet/ip_ipsp.h>
   51 #include <net/pfkeyv2.h>
   52 
   53 #ifdef ENCDEBUG
   54 #define DPRINTF(x)      if (encdebug) printf x
   55 #else
   56 #define DPRINTF(x)
   57 #endif
   58 
   59 struct pool ipsec_policy_pool;
   60 struct pool ipsec_acquire_pool;
   61 int ipsec_policy_pool_initialized = 0;
   62 int ipsec_acquire_pool_initialized = 0;
   63 
   64 /*
   65  * Lookup at the SPD based on the headers contained on the mbuf. The second
   66  * argument indicates what protocol family the header at the beginning of
   67  * the mbuf is. hlen is the offset of the transport protocol header
   68  * in the mbuf.
   69  *
   70  * Return combinations (of return value and in *error):
   71  * - NULL/0 -> no IPsec required on packet
   72  * - NULL/-EINVAL -> silently drop the packet
   73  * - NULL/errno -> drop packet and return error
   74  * or a pointer to a TDB (and 0 in *error).
   75  *
   76  * In the case of incoming flows, only the first three combinations are
   77  * returned.
   78  */
   79 struct tdb *
   80 ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction,
   81     struct tdb *tdbp, struct inpcb *inp)
   82 {
   83         struct route_enc re0, *re = &re0;
   84         union sockaddr_union sdst, ssrc;
   85         struct sockaddr_encap *ddst;
   86         struct ipsec_policy *ipo;
   87         int signore = 0, dignore = 0;
   88 
   89         /*
   90          * If there are no flows in place, there's no point
   91          * continuing with the SPD lookup.
   92          */
   93         if (!ipsec_in_use && inp == NULL) {
   94                 *error = 0;
   95                 return NULL;
   96         }
   97 
   98         /*
   99          * If an input packet is destined to a BYPASS socket, just accept it.
  100          */
  101         if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) &&
  102             (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
  103             (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) &&
  104             (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
  105                 *error = 0;
  106                 return NULL;
  107         }
  108 
  109         bzero((caddr_t) re, sizeof(struct route_enc));
  110         bzero((caddr_t) &sdst, sizeof(union sockaddr_union));
  111         bzero((caddr_t) &ssrc, sizeof(union sockaddr_union));
  112         ddst = (struct sockaddr_encap *) &re->re_dst;
  113         ddst->sen_family = PF_KEY;
  114         ddst->sen_len = SENT_LEN;
  115 
  116         switch (af) {
  117 #ifdef INET
  118         case AF_INET:
  119                 if (hlen < sizeof (struct ip) || m->m_pkthdr.len < hlen) {
  120                         *error = EINVAL;
  121                         return NULL;
  122                 }
  123                 ddst->sen_direction = direction;
  124                 ddst->sen_type = SENT_IP4;
  125 
  126                 m_copydata(m, offsetof(struct ip, ip_src),
  127                     sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src));
  128                 m_copydata(m, offsetof(struct ip, ip_dst),
  129                     sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst));
  130                 m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t),
  131                     (caddr_t) &(ddst->sen_proto));
  132 
  133                 sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET;
  134                 sdst.sin.sin_len = ssrc.sin.sin_len =
  135                     sizeof(struct sockaddr_in);
  136                 ssrc.sin.sin_addr = ddst->sen_ip_src;
  137                 sdst.sin.sin_addr = ddst->sen_ip_dst;
  138 
  139                 /*
  140                  * If TCP/UDP, extract the port numbers to use in the lookup.
  141                  */
  142                 switch (ddst->sen_proto) {
  143                 case IPPROTO_UDP:
  144                 case IPPROTO_TCP:
  145                         /* Make sure there's enough data in the packet. */
  146                         if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
  147                                 *error = EINVAL;
  148                                 return NULL;
  149                         }
  150 
  151                         /*
  152                          * Luckily, the offset of the src/dst ports in
  153                          * both the UDP and TCP headers is the same (first
  154                          * two 16-bit values in the respective headers),
  155                          * so we can just copy them.
  156                          */
  157                         m_copydata(m, hlen, sizeof(u_int16_t),
  158                             (caddr_t) &(ddst->sen_sport));
  159                         m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
  160                             (caddr_t) &(ddst->sen_dport));
  161                         break;
  162 
  163                 default:
  164                         ddst->sen_sport = 0;
  165                         ddst->sen_dport = 0;
  166                 }
  167 
  168                 break;
  169 #endif /* INET */
  170 
  171 #ifdef INET6
  172         case AF_INET6:
  173                 if (hlen < sizeof (struct ip6_hdr) || m->m_pkthdr.len < hlen) {
  174                         *error = EINVAL;
  175                         return NULL;
  176                 }
  177                 ddst->sen_type = SENT_IP6;
  178                 ddst->sen_ip6_direction = direction;
  179 
  180                 m_copydata(m, offsetof(struct ip6_hdr, ip6_src),
  181                     sizeof(struct in6_addr),
  182                     (caddr_t) &(ddst->sen_ip6_src));
  183                 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
  184                     sizeof(struct in6_addr),
  185                     (caddr_t) &(ddst->sen_ip6_dst));
  186                 m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt),
  187                     sizeof(u_int8_t),
  188                     (caddr_t) &(ddst->sen_ip6_proto));
  189 
  190                 sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6;
  191                 sdst.sin6.sin6_len = ssrc.sin6.sin6_family =
  192                     sizeof(struct sockaddr_in6);
  193                 in6_recoverscope(&ssrc.sin6, &ddst->sen_ip6_src, NULL);
  194                 in6_recoverscope(&sdst.sin6, &ddst->sen_ip6_dst, NULL);
  195 
  196                 /*
  197                  * If TCP/UDP, extract the port numbers to use in the lookup.
  198                  */
  199                 switch (ddst->sen_ip6_proto) {
  200                 case IPPROTO_UDP:
  201                 case IPPROTO_TCP:
  202                         /* Make sure there's enough data in the packet. */
  203                         if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) {
  204                                 *error = EINVAL;
  205                                 return NULL;
  206                         }
  207 
  208                         /*
  209                          * Luckily, the offset of the src/dst ports in
  210                          * both the UDP and TCP headers is the same
  211                          * (first two 16-bit values in the respective
  212                          * headers), so we can just copy them.
  213                          */
  214                         m_copydata(m, hlen, sizeof(u_int16_t),
  215                             (caddr_t) &(ddst->sen_ip6_sport));
  216                         m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t),
  217                             (caddr_t) &(ddst->sen_ip6_dport));
  218                         break;
  219 
  220                 default:
  221                         ddst->sen_ip6_sport = 0;
  222                         ddst->sen_ip6_dport = 0;
  223                 }
  224 
  225                 break;
  226 #endif /* INET6 */
  227 
  228         default:
  229                 *error = EAFNOSUPPORT;
  230                 return NULL;
  231         }
  232 
  233         /* Actual SPD lookup. */
  234         rtalloc((struct route *) re);
  235         if (re->re_rt == NULL) {
  236                 /*
  237                  * Return whatever the socket requirements are, there are no
  238                  * system-wide policies.
  239                  */
  240                 *error = 0;
  241                 return ipsp_spd_inp(m, af, hlen, error, direction,
  242                     tdbp, inp, NULL);
  243         }
  244 
  245         /* Sanity check. */
  246         if ((re->re_rt->rt_gateway == NULL) ||
  247             (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type !=
  248                 SENT_IPSP)) {
  249                 RTFREE(re->re_rt);
  250                 *error = EHOSTUNREACH;
  251                 DPRINTF(("ip_spd_lookup: no gateway in SPD entry!"));
  252                 return NULL;
  253         }
  254 
  255         ipo = ((struct sockaddr_encap *) (re->re_rt->rt_gateway))->sen_ipsp;
  256         RTFREE(re->re_rt);
  257         if (ipo == NULL) {
  258                 *error = EHOSTUNREACH;
  259                 DPRINTF(("ip_spd_lookup: no policy attached to SPD entry!"));
  260                 return NULL;
  261         }
  262 
  263         switch (ipo->ipo_type) {
  264         case IPSP_PERMIT:
  265                 *error = 0;
  266                 return ipsp_spd_inp(m, af, hlen, error, direction, tdbp,
  267                     inp, ipo);
  268 
  269         case IPSP_DENY:
  270                 *error = EHOSTUNREACH;
  271                 return NULL;
  272 
  273         case IPSP_IPSEC_USE:
  274         case IPSP_IPSEC_ACQUIRE:
  275         case IPSP_IPSEC_REQUIRE:
  276         case IPSP_IPSEC_DONTACQ:
  277                 /* Nothing more needed here. */
  278                 break;
  279 
  280         default:
  281                 *error = EINVAL;
  282                 return NULL;
  283         }
  284 
  285         /* Check for non-specific destination in the policy. */
  286         switch (ipo->ipo_dst.sa.sa_family) {
  287 #ifdef INET
  288         case AF_INET:
  289                 if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) ||
  290                     (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST))
  291                         dignore = 1;
  292                 break;
  293 #endif /* INET */
  294 
  295 #ifdef INET6
  296         case AF_INET6:
  297                 if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) ||
  298                     (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128,
  299                         sizeof(in6mask128)) == 0))
  300                         dignore = 1;
  301                 break;
  302 #endif /* INET6 */
  303         }
  304 
  305         /* Likewise for source. */
  306         switch (ipo->ipo_src.sa.sa_family) {
  307 #ifdef INET
  308         case AF_INET:
  309                 if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY)
  310                         signore = 1;
  311                 break;
  312 #endif /* INET */
  313 
  314 #ifdef INET6
  315         case AF_INET6:
  316                 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr))
  317                         signore = 1;
  318                 break;
  319 #endif /* INET6 */
  320         }
  321 
  322         /* Do we have a cached entry ? If so, check if it's still valid. */
  323         if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID)) {
  324                 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
  325                     ipo_tdb_next);
  326                 ipo->ipo_tdb = NULL;
  327         }
  328 
  329         /* Outgoing packet policy check. */
  330         if (direction == IPSP_DIRECTION_OUT) {
  331                 /*
  332                  * If the packet is destined for the policy-specified
  333                  * gateway/endhost, and the socket has the BYPASS
  334                  * option set, skip IPsec processing.
  335                  */
  336                 if ((inp != NULL) &&
  337                     (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) &&
  338                     (inp->inp_seclevel[SL_ESP_NETWORK] ==
  339                         IPSEC_LEVEL_BYPASS) &&
  340                     (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) {
  341                         /* Direct match. */
  342                         if (dignore ||
  343                             !bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) {
  344                                 *error = 0;
  345                                 return NULL;
  346                         }
  347                 }
  348 
  349                 /* Check that the cached TDB (if present), is appropriate. */
  350                 if (ipo->ipo_tdb) {
  351                         if ((ipo->ipo_last_searched <= ipsec_last_added) ||
  352                             (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) ||
  353                             bcmp(dignore ? &sdst : &ipo->ipo_dst,
  354                                 &ipo->ipo_tdb->tdb_dst,
  355                                 ipo->ipo_tdb->tdb_dst.sa.sa_len))
  356                                 goto nomatchout;
  357 
  358                         if (!ipsp_aux_match(ipo->ipo_tdb,
  359                             ipo->ipo_srcid, ipo->ipo_dstid,
  360                             ipo->ipo_local_cred, NULL,
  361                             &ipo->ipo_addr, &ipo->ipo_mask))
  362                                 goto nomatchout;
  363 
  364                         /* Cached entry is good. */
  365                         *error = 0;
  366                         return ipsp_spd_inp(m, af, hlen, error, direction,
  367                             tdbp, inp, ipo);
  368 
  369   nomatchout:
  370                         /* Cached TDB was not good. */
  371                         TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
  372                             ipo_tdb_next);
  373                         ipo->ipo_tdb = NULL;
  374                         ipo->ipo_last_searched = 0;
  375                 }
  376 
  377                 /*
  378                  * If no SA has been added since the last time we did a
  379                  * lookup, there's no point searching for one. However, if the
  380                  * destination gateway is left unspecified (or is all-1's),
  381                  * always lookup since this is a generic-match rule
  382                  * (otherwise, we can have situations where SAs to some
  383                  * destinations exist but are not used, possibly leading to an
  384                  * explosion in the number of acquired SAs).
  385                  */
  386                 if (ipo->ipo_last_searched <= ipsec_last_added) {
  387                         /* "Touch" the entry. */
  388                         if (dignore == 0)
  389                                 ipo->ipo_last_searched = time_second;
  390 
  391                         /* Find an appropriate SA from the existing ones. */
  392                         ipo->ipo_tdb =
  393                             gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst,
  394                                 ipo->ipo_sproto, ipo->ipo_srcid,
  395                                 ipo->ipo_dstid, ipo->ipo_local_cred, m, af,
  396                                 &ipo->ipo_addr, &ipo->ipo_mask);
  397                         if (ipo->ipo_tdb) {
  398                                 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
  399                                     ipo, ipo_tdb_next);
  400                                 *error = 0;
  401                                 return ipsp_spd_inp(m, af, hlen, error,
  402                                     direction, tdbp, inp, ipo);
  403                         }
  404                 }
  405 
  406                 /* So, we don't have an SA -- just a policy. */
  407                 switch (ipo->ipo_type) {
  408                 case IPSP_IPSEC_REQUIRE:
  409                         /* Acquire SA through key management. */
  410                         if (ipsp_acquire_sa(ipo,
  411                             dignore ? &sdst : &ipo->ipo_dst,
  412                             signore ? NULL : &ipo->ipo_src, ddst, m) != 0) {
  413                                 *error = EACCES;
  414                                 return NULL;
  415                         }
  416 
  417                         /* FALLTHROUGH */
  418                 case IPSP_IPSEC_DONTACQ:
  419                         *error = -EINVAL; /* Silently drop packet. */
  420                         return NULL;
  421 
  422                 case IPSP_IPSEC_ACQUIRE:
  423                         /* Acquire SA through key management. */
  424                         ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst,
  425                             signore ? NULL : &ipo->ipo_src, ddst, NULL);
  426 
  427                         /* FALLTHROUGH */
  428                 case IPSP_IPSEC_USE:
  429                         *error = 0;
  430                         return ipsp_spd_inp(m, af, hlen, error, direction,
  431                             tdbp, inp, ipo);
  432                 }
  433         } else { /* IPSP_DIRECTION_IN */
  434                 if (tdbp != NULL) {
  435                         /* Direct match in the cache. */
  436                         if (ipo->ipo_tdb == tdbp) {
  437                                 *error = 0;
  438                                 return ipsp_spd_inp(m, af, hlen, error,
  439                                     direction, tdbp, inp, ipo);
  440                         }
  441 
  442                         if (bcmp(dignore ? &ssrc : &ipo->ipo_dst,
  443                             &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) ||
  444                             (ipo->ipo_sproto != tdbp->tdb_sproto))
  445                                 goto nomatchin;
  446 
  447                         /* Match source ID. */
  448                         if (ipo->ipo_srcid) {
  449                                 if (tdbp->tdb_dstid == NULL ||
  450                                     !ipsp_ref_match(ipo->ipo_srcid,
  451                                         tdbp->tdb_dstid))
  452                                         goto nomatchin;
  453                         }
  454 
  455                         /* Match destination ID. */
  456                         if (ipo->ipo_dstid) {
  457                                 if (tdbp->tdb_srcid == NULL ||
  458                                     !ipsp_ref_match(ipo->ipo_dstid,
  459                                         tdbp->tdb_srcid))
  460                                         goto nomatchin;
  461                         }
  462 
  463                         /* Add it to the cache. */
  464                         if (ipo->ipo_tdb)
  465                                 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head,
  466                                     ipo, ipo_tdb_next);
  467                         ipo->ipo_tdb = tdbp;
  468                         TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo,
  469                             ipo_tdb_next);
  470                         *error = 0;
  471                         return ipsp_spd_inp(m, af, hlen, error, direction,
  472                             tdbp, inp, ipo);
  473 
  474   nomatchin: /* Nothing needed here, falling through */
  475         ;
  476                 }
  477 
  478                 /* Check whether cached entry applies. */
  479                 if (ipo->ipo_tdb) {
  480                         /*
  481                          * We only need to check that the correct
  482                          * security protocol and security gateway are
  483                          * set; credentials/IDs will be the same,
  484                          * since the cached entry is linked on this
  485                          * policy.
  486                          */
  487                         if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto &&
  488                             !bcmp(&ipo->ipo_tdb->tdb_src,
  489                                 dignore ? &ssrc : &ipo->ipo_dst,
  490                                 ipo->ipo_tdb->tdb_src.sa.sa_len))
  491                                 goto skipinputsearch;
  492 
  493                         /* Not applicable, unlink. */
  494                         TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
  495                             ipo_tdb_next);
  496                         ipo->ipo_last_searched = 0;
  497                         ipo->ipo_tdb = NULL;
  498                 }
  499 
  500                 /* Find whether there exists an appropriate SA. */
  501                 if (ipo->ipo_last_searched <= ipsec_last_added) {
  502                         if (dignore == 0)
  503                                 ipo->ipo_last_searched = time_second;
  504 
  505                         ipo->ipo_tdb =
  506                             gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst,
  507                                 ipo->ipo_sproto, ipo->ipo_srcid,
  508                                 ipo->ipo_dstid, m, af, &ipo->ipo_addr,
  509                                 &ipo->ipo_mask);
  510                         if (ipo->ipo_tdb)
  511                                 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head,
  512                                     ipo, ipo_tdb_next);
  513                 }
  514   skipinputsearch:
  515 
  516                 switch (ipo->ipo_type) {
  517                 case IPSP_IPSEC_REQUIRE:
  518                         /* If appropriate SA exists, don't acquire another. */
  519                         if (ipo->ipo_tdb) {
  520                                 *error = -EINVAL;
  521                                 return NULL;
  522                         }
  523 
  524                         /* Acquire SA through key management. */
  525                         if ((*error = ipsp_acquire_sa(ipo,
  526                             dignore ? &ssrc : &ipo->ipo_dst,
  527                             signore ? NULL : &ipo->ipo_src, ddst, m)) != 0)
  528                                 return NULL;
  529 
  530                         /* FALLTHROUGH */
  531                 case IPSP_IPSEC_DONTACQ:
  532                         /* Drop packet. */
  533                         *error = -EINVAL;
  534                         return NULL;
  535 
  536                 case IPSP_IPSEC_ACQUIRE:
  537                         /* If appropriate SA exists, don't acquire another. */
  538                         if (ipo->ipo_tdb) {
  539                                 *error = 0;
  540                                 return ipsp_spd_inp(m, af, hlen, error,
  541                                     direction, tdbp, inp, ipo);
  542                         }
  543 
  544                         /* Acquire SA through key management. */
  545                         ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst,
  546                             signore ? NULL : &ipo->ipo_src, ddst, NULL);
  547 
  548                         /* FALLTHROUGH */
  549                 case IPSP_IPSEC_USE:
  550                         *error = 0;
  551                         return ipsp_spd_inp(m, af, hlen, error, direction,
  552                             tdbp, inp, ipo);
  553                 }
  554         }
  555 
  556         /* Shouldn't ever get this far. */
  557         *error = EINVAL;
  558         return NULL;
  559 }
  560 
  561 /*
  562  * Delete a policy from the SPD.
  563  */
  564 int
  565 ipsec_delete_policy(struct ipsec_policy *ipo)
  566 {
  567         struct ipsec_acquire *ipa;
  568         int err = 0;
  569 
  570         if (--ipo->ipo_ref_count > 0)
  571                 return 0;
  572 
  573         /* Delete from SPD. */
  574         if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
  575                 err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr,
  576                     (struct sockaddr *) 0,
  577                     (struct sockaddr *) &ipo->ipo_mask,
  578                     0, (struct rtentry **) 0, 0);       /* XXX other tables? */
  579 
  580         if (ipo->ipo_tdb != NULL)
  581                 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
  582                     ipo_tdb_next);
  583 
  584         while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL)
  585                 ipsp_delete_acquire(ipa);
  586 
  587         TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list);
  588 
  589         if (ipo->ipo_srcid)
  590                 ipsp_reffree(ipo->ipo_srcid);
  591         if (ipo->ipo_dstid)
  592                 ipsp_reffree(ipo->ipo_dstid);
  593         if (ipo->ipo_local_cred)
  594                 ipsp_reffree(ipo->ipo_local_cred);
  595         if (ipo->ipo_local_auth)
  596                 ipsp_reffree(ipo->ipo_local_auth);
  597 
  598         pool_put(&ipsec_policy_pool, ipo);
  599 
  600         if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
  601                 ipsec_in_use--;
  602 
  603         return err;
  604 }
  605 
  606 /*
  607  * Add a policy to the SPD.
  608  */
  609 struct ipsec_policy *
  610 ipsec_add_policy(struct inpcb *inp, int af, int direction)
  611 {
  612         struct ipsec_policy *ipon;
  613 
  614         if (ipsec_policy_pool_initialized == 0) {
  615                 ipsec_policy_pool_initialized = 1;
  616                 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy),
  617                     0, 0, 0, "ipsec policy", NULL);
  618         }
  619 
  620         ipon = pool_get(&ipsec_policy_pool, 0);
  621         if (ipon == NULL)
  622                 return NULL;
  623 
  624         bzero(ipon, sizeof(struct ipsec_policy));
  625 
  626         ipon->ipo_ref_count = 1;
  627         ipon->ipo_flags |= IPSP_POLICY_SOCKET;
  628 
  629         ipon->ipo_type = IPSP_IPSEC_REQUIRE; /* XXX */
  630 
  631         /* XXX
  632          * We should actually be creating a linked list of
  633          * policies (for tunnel/transport and ESP/AH), as needed.
  634          */
  635         ipon->ipo_sproto = IPPROTO_ESP;
  636 
  637         TAILQ_INIT(&ipon->ipo_acquires);
  638         TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
  639 
  640         ipsec_update_policy(inp, ipon, af, direction);
  641 
  642         return ipon;
  643 }
  644 
  645 /*
  646  * Update a PCB-attached policy.
  647  */
  648 void
  649 ipsec_update_policy(struct inpcb *inp, struct ipsec_policy *ipon, int af,
  650     int direction)
  651 {
  652         ipon->ipo_addr.sen_len = ipon->ipo_mask.sen_len = SENT_LEN;
  653         ipon->ipo_addr.sen_family = ipon->ipo_mask.sen_family = PF_KEY;
  654         ipon->ipo_src.sa.sa_family = ipon->ipo_dst.sa.sa_family = af;
  655 
  656         switch (af) {
  657         case AF_INET:
  658 #ifdef INET
  659                 ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP4;
  660                 ipon->ipo_addr.sen_ip_src = inp->inp_laddr;
  661                 ipon->ipo_addr.sen_ip_dst = inp->inp_faddr;
  662                 ipon->ipo_addr.sen_sport = inp->inp_lport;
  663                 ipon->ipo_addr.sen_dport = inp->inp_fport;
  664                 ipon->ipo_addr.sen_proto =
  665                     inp->inp_socket->so_proto->pr_protocol;
  666                 ipon->ipo_addr.sen_direction = direction;
  667 
  668                 ipon->ipo_mask.sen_ip_src.s_addr = 0xffffffff;
  669                 ipon->ipo_mask.sen_ip_dst.s_addr = 0xffffffff;
  670                 ipon->ipo_mask.sen_sport = ipon->ipo_mask.sen_dport = 0xffff;
  671                 ipon->ipo_mask.sen_proto = 0xff;
  672                 ipon->ipo_mask.sen_direction = direction;
  673 
  674                 ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in);
  675                 ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in);
  676                 ipon->ipo_src.sin.sin_addr = inp->inp_laddr;
  677                 ipon->ipo_dst.sin.sin_addr = inp->inp_faddr;
  678 #endif /* INET */
  679                 break;
  680 
  681         case AF_INET6:
  682 #ifdef INET6
  683                 ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP6;
  684                 ipon->ipo_addr.sen_ip6_src = inp->inp_laddr6;
  685                 ipon->ipo_addr.sen_ip6_dst = inp->inp_faddr6;
  686                 ipon->ipo_addr.sen_ip6_sport = inp->inp_lport;
  687                 ipon->ipo_addr.sen_ip6_dport = inp->inp_fport;
  688                 ipon->ipo_addr.sen_ip6_proto =
  689                     inp->inp_socket->so_proto->pr_protocol;
  690                 ipon->ipo_addr.sen_ip6_direction = direction;
  691 
  692                 ipon->ipo_mask.sen_ip6_src = in6mask128;
  693                 ipon->ipo_mask.sen_ip6_dst = in6mask128;
  694                 ipon->ipo_mask.sen_ip6_sport = 0xffff;
  695                 ipon->ipo_mask.sen_ip6_dport = 0xffff;
  696                 ipon->ipo_mask.sen_ip6_proto = 0xff;
  697                 ipon->ipo_mask.sen_ip6_direction = direction;
  698 
  699                 ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in6);
  700                 ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in6);
  701                 ipon->ipo_src.sin6.sin6_addr = inp->inp_laddr6;
  702                 ipon->ipo_dst.sin6.sin6_addr = inp->inp_faddr6;
  703 #endif /* INET6 */
  704                 break;
  705         }
  706 }
  707 
  708 /*
  709  * Delete a pending IPsec acquire record.
  710  */
  711 void
  712 ipsp_delete_acquire(void *v)
  713 {
  714         struct ipsec_acquire *ipa = v;
  715 
  716         timeout_del(&ipa->ipa_timeout);
  717         TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next);
  718         if (ipa->ipa_policy != NULL)
  719                 TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa,
  720                     ipa_ipo_next);
  721         pool_put(&ipsec_acquire_pool, ipa);
  722 }
  723 
  724 /*
  725  * Find out if there's an ACQUIRE pending.
  726  * XXX Need a better structure.
  727  */
  728 struct ipsec_acquire *
  729 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw)
  730 {
  731         struct ipsec_acquire *ipa;
  732 
  733         TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) {
  734                 if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len))
  735                         return ipa;
  736         }
  737 
  738         return NULL;
  739 }
  740 
  741 /*
  742  * Signal key management that we need an SA.
  743  * XXX For outgoing policies, we could try to hold on to the mbuf.
  744  */
  745 int
  746 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw,
  747     union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m)
  748 {
  749         struct ipsec_acquire *ipa;
  750 
  751         /*
  752          * If this is a socket policy, it has to have authentication
  753          * information accompanying it --- can't tell key mgmt. to
  754          * "find" it for us. This avoids abusing key mgmt. to authenticate
  755          * on an application's behalf, even if the application doesn't
  756          * have/know (and shouldn't) the appropriate authentication
  757          * material (passphrase, private key, etc.)
  758          */
  759         if (ipo->ipo_flags & IPSP_POLICY_SOCKET &&
  760             ipo->ipo_local_auth == NULL)
  761                 return EINVAL;
  762 
  763         /* Check whether request has been made already. */
  764         if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL)
  765                 return 0;
  766 
  767         /* Add request in cache and proceed. */
  768         if (ipsec_acquire_pool_initialized == 0) {
  769                 ipsec_acquire_pool_initialized = 1;
  770                 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire),
  771                     0, 0, 0, "ipsec acquire", NULL);
  772         }
  773 
  774         ipa = pool_get(&ipsec_acquire_pool, 0);
  775         if (ipa == NULL)
  776                 return ENOMEM;
  777 
  778         bzero(ipa, sizeof(struct ipsec_acquire));
  779         bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union));
  780 
  781         timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa);
  782 
  783         ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN;
  784         ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY;
  785 
  786         /* Just copy the right information. */
  787         switch (ipo->ipo_addr.sen_type) {
  788 #ifdef INET
  789         case SENT_IP4:
  790                 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4;
  791                 ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction;
  792                 ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction;
  793 
  794                 if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY ||
  795                     ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY ||
  796                     ipsp_is_unspecified(ipo->ipo_dst)) {
  797                         ipa->ipa_info.sen_ip_src = ddst->sen_ip_src;
  798                         ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST;
  799                 } else {
  800                         ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src;
  801                         ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src;
  802                 }
  803 
  804                 if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY ||
  805                     ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY ||
  806                     ipsp_is_unspecified(ipo->ipo_dst)) {
  807                         ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst;
  808                         ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST;
  809                 } else {
  810                         ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst;
  811                         ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst;
  812                 }
  813 
  814                 ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto;
  815                 ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto;
  816 
  817                 if (ipo->ipo_addr.sen_proto) {
  818                         ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport;
  819                         ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport;
  820 
  821                         ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport;
  822                         ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport;
  823                 }
  824                 break;
  825 #endif /* INET */
  826 
  827 #ifdef INET6
  828         case SENT_IP6:
  829                 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6;
  830                 ipa->ipa_info.sen_ip6_direction =
  831                     ipo->ipo_addr.sen_ip6_direction;
  832                 ipa->ipa_mask.sen_ip6_direction =
  833                     ipo->ipo_mask.sen_ip6_direction;
  834 
  835                 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) ||
  836                     IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) ||
  837                     ipsp_is_unspecified(ipo->ipo_dst)) {
  838                         ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src;
  839                         ipa->ipa_mask.sen_ip6_src = in6mask128;
  840                 } else {
  841                         ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src;
  842                         ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src;
  843                 }
  844 
  845                 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) ||
  846                     IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) ||
  847                     ipsp_is_unspecified(ipo->ipo_dst)) {
  848                         ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst;
  849                         ipa->ipa_mask.sen_ip6_dst = in6mask128;
  850                 } else {
  851                         ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst;
  852                         ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst;
  853                 }
  854 
  855                 ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto;
  856                 ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto;
  857 
  858                 if (ipo->ipo_mask.sen_ip6_proto) {
  859                         ipa->ipa_info.sen_ip6_sport =
  860                             ipo->ipo_addr.sen_ip6_sport;
  861                         ipa->ipa_mask.sen_ip6_sport =
  862                             ipo->ipo_mask.sen_ip6_sport;
  863                         ipa->ipa_info.sen_ip6_dport =
  864                             ipo->ipo_addr.sen_ip6_dport;
  865                         ipa->ipa_mask.sen_ip6_dport =
  866                             ipo->ipo_mask.sen_ip6_dport;
  867                 }
  868                 break;
  869 #endif /* INET6 */
  870 
  871         default:
  872                 pool_put(&ipsec_acquire_pool, ipa);
  873                 return 0;
  874         }
  875 
  876         timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz);
  877 
  878         TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next);
  879         TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next);
  880         ipa->ipa_policy = ipo;
  881 
  882         /* PF_KEYv2 notification message. */
  883         return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst);
  884 }
  885 
  886 /*
  887  * Deal with PCB security requirements.
  888  */
  889 struct tdb *
  890 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
  891     struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo)
  892 {
  893         struct ipsec_policy sipon;
  894         struct tdb_ident *tdbi;
  895         struct m_tag *mtag;
  896         struct tdb *tdb = NULL;
  897 
  898         /* Sanity check. */
  899         if (inp == NULL)
  900                 goto justreturn;
  901 
  902         /* Verify that we need to check for socket policy. */
  903         if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS ||
  904             inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_NONE) &&
  905             (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS ||
  906             inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_NONE) &&
  907             (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS ||
  908             inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_NONE))
  909                 goto justreturn;
  910 
  911         switch (direction) {
  912         case IPSP_DIRECTION_IN:
  913                 /*
  914                  * Some further checking: if the socket has specified
  915                  * that it will accept unencrypted traffic, don't
  916                  * bother checking any further -- just accept the packet.
  917                  */
  918                 if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_AVAIL ||
  919                     inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_USE) &&
  920                     (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_AVAIL ||
  921                     inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_USE) &&
  922                     (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL ||
  923                     inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_USE))
  924                         goto justreturn;
  925 
  926                 /* Initialize socket policy if unset. */
  927                 if (inp->inp_ipo == NULL) {
  928                         inp->inp_ipo = ipsec_add_policy(inp, af,
  929                             IPSP_DIRECTION_OUT);
  930                         if (inp->inp_ipo == NULL) {
  931                                 *error = ENOBUFS;
  932                                 return NULL;
  933                         }
  934                 }
  935 
  936                 /*
  937                  * So we *must* have protected traffic. Let's see what
  938                  * we have received then.
  939                  */
  940                 if (inp->inp_tdb_in != NULL) {
  941                         if (inp->inp_tdb_in == tdbp)
  942                                 goto justreturn; /* We received packet under a
  943                                                   * previously-accepted TDB. */
  944 
  945                         /*
  946                          * We should be receiving protected traffic, and
  947                          * have an SA in place, but packet was received
  948                          * unprotected. Simply discard.
  949                          */
  950                         if (tdbp == NULL) {
  951                                 *error = -EINVAL;
  952                                 return NULL;
  953                         }
  954 
  955                         /* Update, since we may need all the relevant info. */
  956                         ipsec_update_policy(inp, inp->inp_ipo, af,
  957                             IPSP_DIRECTION_OUT);
  958 
  959                         /*
  960                          * Check that the TDB the packet was received under
  961                          * is acceptable under the socket policy. If so,
  962                          * accept the packet; otherwise, discard.
  963                          */
  964                         if (tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
  965                             !bcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
  966                                 SA_LEN(&tdbp->tdb_src.sa)) &&
  967                             ipsp_aux_match(tdbp,
  968                                 inp->inp_ipo->ipo_srcid, 
  969                                 inp->inp_ipo->ipo_dstid,
  970                                 NULL, NULL,
  971                                 &inp->inp_ipo->ipo_addr,
  972                                 &inp->inp_ipo->ipo_mask))
  973                                 goto justreturn;
  974                         else {
  975                                 *error = -EINVAL;
  976                                 return NULL;
  977                         }
  978                 } else {
  979                         /* Update, since we may need all the relevant info. */
  980                         ipsec_update_policy(inp, inp->inp_ipo, af,
  981                             IPSP_DIRECTION_OUT);
  982 
  983                         /*
  984                          * If the packet was received under an SA, see if
  985                          * it's acceptable under socket policy. If it is,
  986                          * accept the packet.
  987                          */
  988                         if (tdbp != NULL &&
  989                             tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
  990                             !bcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
  991                                 SA_LEN(&tdbp->tdb_src.sa)) &&
  992                             ipsp_aux_match(tdbp,
  993                                 inp->inp_ipo->ipo_srcid,
  994                                 inp->inp_ipo->ipo_dstid,
  995                                 NULL, NULL,
  996                                 &inp->inp_ipo->ipo_addr,
  997                                 &inp->inp_ipo->ipo_mask))
  998                                 goto justreturn;
  999 
 1000                         /*
 1001                          * If the packet was not received under an SA, or
 1002                          * if the SA it was received under is not acceptable,
 1003                          * see if we already have an acceptable SA
 1004                          * established. If we do, discard packet.
 1005                          */
 1006                         if (inp->inp_ipo->ipo_last_searched <=
 1007                             ipsec_last_added) {
 1008                                 inp->inp_ipo->ipo_last_searched = time_second;
 1009 
 1010                                 /* Do we have an SA already established ? */
 1011                                 if (gettdbbysrc(&inp->inp_ipo->ipo_dst,
 1012                                     inp->inp_ipo->ipo_sproto,
 1013                                     inp->inp_ipo->ipo_srcid,
 1014                                     inp->inp_ipo->ipo_dstid, m, af,
 1015                                     &inp->inp_ipo->ipo_addr,
 1016                                     &inp->inp_ipo->ipo_mask) != NULL) {
 1017                                         *error = -EINVAL;
 1018                                         return NULL;
 1019                                 }
 1020                                 /* Fall through */
 1021                         }
 1022 
 1023                         /*
 1024                          * If we don't have an appropriate SA, acquire one
 1025                          * and discard the packet.
 1026                          */
 1027                         ipsp_acquire_sa(inp->inp_ipo, &inp->inp_ipo->ipo_dst,
 1028                             &inp->inp_ipo->ipo_src, &inp->inp_ipo->ipo_addr, m);
 1029                         *error = -EINVAL;
 1030                         return NULL;
 1031                 }
 1032 
 1033                 break;
 1034 
 1035         case IPSP_DIRECTION_OUT:
 1036                 /* Do we have a cached entry ? */
 1037                 if (inp->inp_tdb_out != NULL) {
 1038                         /*
 1039                          * If we also have to apply a different TDB as
 1040                          * a result of a system-wide policy, add a tag
 1041                          * to the packet.
 1042                          */
 1043                         if (ipo != NULL && m != NULL &&
 1044                             ipo->ipo_tdb != NULL &&
 1045                             ipo->ipo_tdb != inp->inp_tdb_out) {
 1046                                 tdb = inp->inp_tdb_out;
 1047                                 goto tagandreturn;
 1048                         } else
 1049                                 return inp->inp_tdb_out;
 1050                 }
 1051 
 1052                 /*
 1053                  * We need to either find an SA with the appropriate
 1054                  * characteristics and link it to the PCB, or acquire
 1055                  * one.
 1056                  */
 1057                 /* XXX Only support one policy/protocol for now. */
 1058                 if (inp->inp_ipo != NULL) {
 1059                         if (inp->inp_ipo->ipo_last_searched <=
 1060                             ipsec_last_added) {
 1061                                 inp->inp_ipo->ipo_last_searched = time_second;
 1062 
 1063                                 /* Update, just in case. */
 1064                                 ipsec_update_policy(inp, inp->inp_ipo, af,
 1065                                     IPSP_DIRECTION_OUT);
 1066 
 1067                                 tdb = gettdbbyaddr(&inp->inp_ipo->ipo_dst,
 1068                                     inp->inp_ipo->ipo_sproto,
 1069                                     inp->inp_ipo->ipo_srcid,
 1070                                     inp->inp_ipo->ipo_dstid,
 1071                                     inp->inp_ipo->ipo_local_cred, m, af,
 1072                                     &inp->inp_ipo->ipo_addr,
 1073                                     &inp->inp_ipo->ipo_mask);
 1074                         }
 1075                 } else {
 1076                         /*
 1077                          * Construct a pseudo-policy, with just the necessary
 1078                          * fields.
 1079                          */
 1080                         ipsec_update_policy(inp, &sipon, af,
 1081                             IPSP_DIRECTION_OUT);
 1082 
 1083                         tdb = gettdbbyaddr(&sipon.ipo_dst, IPPROTO_ESP, NULL,
 1084                             NULL, NULL, m, af, &sipon.ipo_addr,
 1085                             &sipon.ipo_mask);
 1086                 }
 1087 
 1088                 /* If we found an appropriate SA... */
 1089                 if (tdb != NULL) {
 1090                         tdb_add_inp(tdb, inp, 0); /* Latch onto PCB. */
 1091 
 1092                         if (ipo != NULL && ipo->ipo_tdb != NULL &&
 1093                             ipo->ipo_tdb != inp->inp_tdb_out && m != NULL)
 1094                                 goto tagandreturn;
 1095                         else
 1096                                 return tdb;
 1097                 } else {
 1098                         /* Do we need to acquire one ? */
 1099                         switch (inp->inp_seclevel[SL_ESP_TRANS]) {
 1100                         case IPSEC_LEVEL_BYPASS:
 1101                         case IPSEC_LEVEL_AVAIL:
 1102                                 /* No need to do anything. */
 1103                                 goto justreturn;
 1104                         case IPSEC_LEVEL_USE:
 1105                         case IPSEC_LEVEL_REQUIRE:
 1106                         case IPSEC_LEVEL_UNIQUE:
 1107                                 /* Initialize socket policy if unset. */
 1108                                 if (inp->inp_ipo == NULL) {
 1109                                         inp->inp_ipo = ipsec_add_policy(inp, af, IPSP_DIRECTION_OUT);
 1110                                         if (inp->inp_ipo == NULL) {
 1111                                                 *error = ENOBUFS;
 1112                                                 return NULL;
 1113                                         }
 1114                                 }
 1115 
 1116                                 /* Acquire a new SA. */
 1117                                 if ((*error = ipsp_acquire_sa(inp->inp_ipo,
 1118                                     &inp->inp_ipo->ipo_dst,
 1119                                     &inp->inp_ipo->ipo_src,
 1120                                     &inp->inp_ipo->ipo_addr, m)) == 0)
 1121                                         *error = -EINVAL;
 1122 
 1123                                 return NULL;
 1124                         default:
 1125                                 DPRINTF(("ipsp_spd_inp: unknown sock security"
 1126                                     " level %d",
 1127                                     inp->inp_seclevel[SL_ESP_TRANS]));
 1128                                 *error = -EINVAL;
 1129                                 return NULL;
 1130                         }
 1131                 }
 1132                 break;
 1133 
 1134         default:  /* Should never happen. */
 1135                 *error = -EINVAL;
 1136                 return NULL;
 1137         }
 1138 
 1139  tagandreturn:
 1140         if (tdb == NULL)
 1141                 goto justreturn;
 1142 
 1143         mtag = m_tag_get(PACKET_TAG_IPSEC_PENDING_TDB,
 1144             sizeof (struct tdb_ident), M_NOWAIT);
 1145         if (mtag == NULL) {
 1146                 *error = ENOMEM;
 1147                 return NULL;
 1148         }
 1149 
 1150         tdbi = (struct tdb_ident *)(mtag + 1);
 1151         tdbi->spi = ipo->ipo_tdb->tdb_spi;
 1152         tdbi->proto = ipo->ipo_tdb->tdb_sproto;
 1153         bcopy(&ipo->ipo_tdb->tdb_dst, &tdbi->dst,
 1154             ipo->ipo_tdb->tdb_dst.sa.sa_len);
 1155         m_tag_prepend(m, mtag);
 1156         return tdb;
 1157 
 1158  justreturn:
 1159         if (ipo != NULL)
 1160                 return ipo->ipo_tdb;
 1161         else
 1162                 return NULL;
 1163 }
 1164 
 1165 /*
 1166  * Find a pending ACQUIRE record based on its sequence number.
 1167  * XXX Need to use a better data structure.
 1168  */
 1169 struct ipsec_acquire *
 1170 ipsec_get_acquire(u_int32_t seq)
 1171 {
 1172         struct ipsec_acquire *ipa;
 1173 
 1174         TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_next)
 1175                 if (ipa->ipa_seq == seq)
 1176                         return ipa;
 1177 
 1178         return NULL;
 1179 }

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