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/netinet/ipsec_input.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: ipsec_input.c,v 1.203 2022/02/22 01:35:40 guenther Exp $      */
    2 /*
    3  * The authors of this code are John Ioannidis (ji@tla.org),
    4  * Angelos D. Keromytis (kermit@csd.uch.gr) and
    5  * Niels Provos (provos@physnet.uni-hamburg.de).
    6  *
    7  * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
    8  * in November 1995.
    9  *
   10  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
   11  * by Angelos D. Keromytis.
   12  *
   13  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
   14  * and Niels Provos.
   15  *
   16  * Additional features in 1999 by Angelos D. Keromytis.
   17  *
   18  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
   19  * Angelos D. Keromytis and Niels Provos.
   20  * Copyright (c) 2001, Angelos D. Keromytis.
   21  *
   22  * Permission to use, copy, and modify this software with or without fee
   23  * is hereby granted, provided that this entire notice is included in
   24  * all copies of any software which is or includes a copy or
   25  * modification of this software.
   26  * You may use this code under the GNU public license if you so wish. Please
   27  * contribute changes back to the authors under this freer than GPL license
   28  * so that we may further the use of strong encryption without limitations to
   29  * all.
   30  *
   31  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
   32  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
   33  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
   34  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
   35  * PURPOSE.
   36  */
   37 
   38 #include "pf.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/protosw.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/socket.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/kernel.h>
   47 #include <sys/timeout.h>
   48 
   49 #include <net/if.h>
   50 #include <net/if_var.h>
   51 #include <net/netisr.h>
   52 #include <net/bpf.h>
   53 #include <net/route.h>
   54 
   55 #include <netinet/in.h>
   56 #include <netinet/ip.h>
   57 #include <netinet/ip_var.h>
   58 #include <netinet/ip_icmp.h>
   59 #include <netinet/tcp.h>
   60 #include <netinet/udp.h>
   61 
   62 #if NPF > 0
   63 #include <net/pfvar.h>
   64 #endif
   65 
   66 #ifdef INET6
   67 #include <netinet6/in6_var.h>
   68 #include <netinet/ip6.h>
   69 #include <netinet6/ip6_var.h>
   70 #endif /* INET6 */
   71 
   72 #include <netinet/ip_ipsp.h>
   73 #include <netinet/ip_esp.h>
   74 #include <netinet/ip_ah.h>
   75 #include <netinet/ip_ipcomp.h>
   76 
   77 #include <net/if_enc.h>
   78 
   79 #include <crypto/cryptodev.h>
   80 #include <crypto/xform.h>
   81 
   82 #include "bpfilter.h"
   83 
   84 void ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int);
   85 
   86 #ifdef ENCDEBUG
   87 #define DPRINTF(fmt, args...)                                           \
   88         do {                                                            \
   89                 if (encdebug)                                           \
   90                         printf("%s: " fmt "\n", __func__, ## args);     \
   91         } while (0)
   92 #else
   93 #define DPRINTF(fmt, args...)                                           \
   94         do { } while (0)
   95 #endif
   96 
   97 /* sysctl variables */
   98 int encdebug = 0;
   99 int ipsec_keep_invalid = IPSEC_DEFAULT_EMBRYONIC_SA_TIMEOUT;
  100 int ipsec_require_pfs = IPSEC_DEFAULT_PFS;
  101 int ipsec_soft_allocations = IPSEC_DEFAULT_SOFT_ALLOCATIONS;
  102 int ipsec_exp_allocations = IPSEC_DEFAULT_EXP_ALLOCATIONS;
  103 int ipsec_soft_bytes = IPSEC_DEFAULT_SOFT_BYTES;
  104 int ipsec_exp_bytes = IPSEC_DEFAULT_EXP_BYTES;
  105 int ipsec_soft_timeout = IPSEC_DEFAULT_SOFT_TIMEOUT;
  106 int ipsec_exp_timeout = IPSEC_DEFAULT_EXP_TIMEOUT;
  107 int ipsec_soft_first_use = IPSEC_DEFAULT_SOFT_FIRST_USE;
  108 int ipsec_exp_first_use = IPSEC_DEFAULT_EXP_FIRST_USE;
  109 int ipsec_expire_acquire = IPSEC_DEFAULT_EXPIRE_ACQUIRE;
  110 
  111 int esp_enable = 1;
  112 int ah_enable = 1;
  113 int ipcomp_enable = 0;
  114 
  115 const struct sysctl_bounded_args espctl_vars[] = {
  116         {ESPCTL_ENABLE, &esp_enable, 0, 1},
  117         {ESPCTL_UDPENCAP_ENABLE, &udpencap_enable, 0, 1},
  118         {ESPCTL_UDPENCAP_PORT, &udpencap_port, 0, 65535},
  119 };
  120 const struct sysctl_bounded_args ahctl_vars[] = {
  121         {AHCTL_ENABLE, &ah_enable, 0, 1},
  122 };
  123 const struct sysctl_bounded_args ipcompctl_vars[] = {
  124         {IPCOMPCTL_ENABLE, &ipcomp_enable, 0, 1},
  125 };
  126 
  127 struct cpumem *espcounters;
  128 struct cpumem *ahcounters;
  129 struct cpumem *ipcompcounters;
  130 struct cpumem *ipseccounters;
  131 
  132 char ipsec_def_enc[20];
  133 char ipsec_def_auth[20];
  134 char ipsec_def_comp[20];
  135 
  136 const struct sysctl_bounded_args ipsecctl_vars[] = {
  137         { IPSEC_ENCDEBUG, &encdebug, 0, 1 },
  138         { IPSEC_EXPIRE_ACQUIRE, &ipsec_expire_acquire, 0, INT_MAX },
  139         { IPSEC_EMBRYONIC_SA_TIMEOUT, &ipsec_keep_invalid, 0, INT_MAX },
  140         { IPSEC_REQUIRE_PFS, &ipsec_require_pfs, 0, 1 },
  141         { IPSEC_SOFT_ALLOCATIONS, &ipsec_soft_allocations, 0, INT_MAX },
  142         { IPSEC_ALLOCATIONS, &ipsec_exp_allocations, 0, INT_MAX },
  143         { IPSEC_SOFT_BYTES, &ipsec_soft_bytes, 0, INT_MAX },
  144         { IPSEC_BYTES, &ipsec_exp_bytes, 0, INT_MAX },
  145         { IPSEC_TIMEOUT, &ipsec_exp_timeout, 0, INT_MAX },
  146         { IPSEC_SOFT_TIMEOUT, &ipsec_soft_timeout,0, INT_MAX },
  147         { IPSEC_SOFT_FIRSTUSE, &ipsec_soft_first_use, 0, INT_MAX },
  148         { IPSEC_FIRSTUSE, &ipsec_exp_first_use, 0, INT_MAX },
  149 };
  150 
  151 int esp_sysctl_espstat(void *, size_t *, void *);
  152 int ah_sysctl_ahstat(void *, size_t *, void *);
  153 int ipcomp_sysctl_ipcompstat(void *, size_t *, void *);
  154 int ipsec_sysctl_ipsecstat(void *, size_t *, void *);
  155 
  156 void
  157 ipsec_init(void)
  158 {
  159         espcounters = counters_alloc(esps_ncounters);
  160         ahcounters = counters_alloc(ahs_ncounters);
  161         ipcompcounters = counters_alloc(ipcomps_ncounters);
  162         ipseccounters = counters_alloc(ipsec_ncounters);
  163 
  164         strlcpy(ipsec_def_enc, IPSEC_DEFAULT_DEF_ENC, sizeof(ipsec_def_enc));
  165         strlcpy(ipsec_def_auth, IPSEC_DEFAULT_DEF_AUTH, sizeof(ipsec_def_auth));
  166         strlcpy(ipsec_def_comp, IPSEC_DEFAULT_DEF_COMP, sizeof(ipsec_def_comp));
  167 
  168         ipsp_init();
  169 }
  170 
  171 /*
  172  * ipsec_common_input() gets called when we receive an IPsec-protected packet
  173  * in IPv4 or IPv6. All it does is find the right TDB and call the appropriate
  174  * transform. The callback takes care of further processing (like ingress
  175  * filtering).
  176  */
  177 int
  178 ipsec_common_input(struct mbuf **mp, int skip, int protoff, int af, int sproto,
  179     int udpencap)
  180 {
  181 #define IPSEC_ISTAT(x,y,z) do {                 \
  182         if (sproto == IPPROTO_ESP)              \
  183                 espstat_inc(x);                 \
  184         else if (sproto == IPPROTO_AH)          \
  185                 ahstat_inc(y);                  \
  186         else                                    \
  187                 ipcompstat_inc(z);              \
  188 } while (0)
  189 
  190         struct mbuf *m = *mp;
  191         union sockaddr_union dst_address;
  192         struct tdb *tdbp = NULL;
  193         u_int32_t spi;
  194         u_int16_t cpi;
  195         int prot;
  196 #ifdef ENCDEBUG
  197         char buf[INET6_ADDRSTRLEN];
  198 #endif
  199 
  200         NET_ASSERT_LOCKED();
  201 
  202         ipsecstat_pkt(ipsec_ipackets, ipsec_ibytes, m->m_pkthdr.len);
  203         IPSEC_ISTAT(esps_input, ahs_input, ipcomps_input);
  204 
  205         if ((sproto == IPPROTO_IPCOMP) && (m->m_flags & M_COMP)) {
  206                 DPRINTF("repeated decompression");
  207                 ipcompstat_inc(ipcomps_pdrops);
  208                 goto drop;
  209         }
  210 
  211         if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) {
  212                 DPRINTF("packet too small");
  213                 IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
  214                 goto drop;
  215         }
  216 
  217         /* Retrieve the SPI from the relevant IPsec header */
  218         switch (sproto) {
  219         case IPPROTO_ESP:
  220                 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
  221                 break;
  222         case IPPROTO_AH:
  223                 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
  224                     (caddr_t) &spi);
  225                 break;
  226         case IPPROTO_IPCOMP:
  227                 m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t),
  228                     (caddr_t) &cpi);
  229                 spi = ntohl(htons(cpi));
  230                 break;
  231         default:
  232                 panic("%s: unknown/unsupported security protocol %d",
  233                     __func__, sproto);
  234         }
  235 
  236         /*
  237          * Find tunnel control block and (indirectly) call the appropriate
  238          * kernel crypto routine. The resulting mbuf chain is a valid
  239          * IP packet ready to go through input processing.
  240          */
  241 
  242         memset(&dst_address, 0, sizeof(dst_address));
  243         dst_address.sa.sa_family = af;
  244 
  245         switch (af) {
  246         case AF_INET:
  247                 dst_address.sin.sin_len = sizeof(struct sockaddr_in);
  248                 m_copydata(m, offsetof(struct ip, ip_dst),
  249                     sizeof(struct in_addr),
  250                     (caddr_t) &(dst_address.sin.sin_addr));
  251                 break;
  252 
  253 #ifdef INET6
  254         case AF_INET6:
  255                 dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6);
  256                 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst),
  257                     sizeof(struct in6_addr),
  258                     (caddr_t) &(dst_address.sin6.sin6_addr));
  259                 in6_recoverscope(&dst_address.sin6,
  260                     &dst_address.sin6.sin6_addr);
  261                 break;
  262 #endif /* INET6 */
  263 
  264         default:
  265                 DPRINTF("unsupported protocol family %d", af);
  266                 IPSEC_ISTAT(esps_nopf, ahs_nopf, ipcomps_nopf);
  267                 goto drop;
  268         }
  269 
  270         tdbp = gettdb(rtable_l2(m->m_pkthdr.ph_rtableid),
  271             spi, &dst_address, sproto);
  272         if (tdbp == NULL) {
  273                 DPRINTF("could not find SA for packet to %s, spi %08x",
  274                     ipsp_address(&dst_address, buf, sizeof(buf)), ntohl(spi));
  275                 IPSEC_ISTAT(esps_notdb, ahs_notdb, ipcomps_notdb);
  276                 goto drop;
  277         }
  278 
  279         if (tdbp->tdb_flags & TDBF_INVALID) {
  280                 DPRINTF("attempted to use invalid SA %s/%08x/%u",
  281                     ipsp_address(&dst_address, buf, sizeof(buf)),
  282                     ntohl(spi), tdbp->tdb_sproto);
  283                 IPSEC_ISTAT(esps_invalid, ahs_invalid, ipcomps_invalid);
  284                 goto drop;
  285         }
  286 
  287         if (udpencap && !(tdbp->tdb_flags & TDBF_UDPENCAP)) {
  288                 DPRINTF("attempted to use non-udpencap SA %s/%08x/%u",
  289                     ipsp_address(&dst_address, buf, sizeof(buf)),
  290                     ntohl(spi), tdbp->tdb_sproto);
  291                 espstat_inc(esps_udpinval);
  292                 goto drop;
  293         }
  294 
  295         if (!udpencap && (tdbp->tdb_flags & TDBF_UDPENCAP)) {
  296                 DPRINTF("attempted to use udpencap SA %s/%08x/%u",
  297                     ipsp_address(&dst_address, buf, sizeof(buf)),
  298                     ntohl(spi), tdbp->tdb_sproto);
  299                 espstat_inc(esps_udpneeded);
  300                 goto drop;
  301         }
  302 
  303         if (tdbp->tdb_xform == NULL) {
  304                 DPRINTF("attempted to use uninitialized SA %s/%08x/%u",
  305                     ipsp_address(&dst_address, buf, sizeof(buf)),
  306                     ntohl(spi), tdbp->tdb_sproto);
  307                 IPSEC_ISTAT(esps_noxform, ahs_noxform, ipcomps_noxform);
  308                 goto drop;
  309         }
  310 
  311         KERNEL_LOCK();
  312         /* Register first use, setup expiration timer. */
  313         if (tdbp->tdb_first_use == 0) {
  314                 tdbp->tdb_first_use = gettime();
  315                 if (tdbp->tdb_flags & TDBF_FIRSTUSE) {
  316                         if (timeout_add_sec(&tdbp->tdb_first_tmo,
  317                             tdbp->tdb_exp_first_use))
  318                                 tdb_ref(tdbp);
  319                 }
  320                 if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE) {
  321                         if (timeout_add_sec(&tdbp->tdb_sfirst_tmo,
  322                             tdbp->tdb_soft_first_use))
  323                                 tdb_ref(tdbp);
  324                 }
  325         }
  326 
  327         tdbstat_pkt(tdbp, tdb_ipackets, tdb_ibytes, m->m_pkthdr.len);
  328 
  329         /*
  330          * Call appropriate transform and return -- callback takes care of
  331          * everything else.
  332          */
  333         prot = (*(tdbp->tdb_xform->xf_input))(mp, tdbp, skip, protoff);
  334         if (prot == IPPROTO_DONE) {
  335                 ipsecstat_inc(ipsec_idrops);
  336                 tdbstat_inc(tdbp, tdb_idrops);
  337         }
  338         tdb_unref(tdbp);
  339         KERNEL_UNLOCK();
  340         return prot;
  341 
  342  drop:
  343         m_freemp(mp);
  344         ipsecstat_inc(ipsec_idrops);
  345         if (tdbp != NULL)
  346                 tdbstat_inc(tdbp, tdb_idrops);
  347         tdb_unref(tdbp);
  348         return IPPROTO_DONE;
  349 }
  350 
  351 /*
  352  * IPsec input callback, called by the transform callback. Takes care of
  353  * filtering and other sanity checks on the processed packet.
  354  */
  355 int
  356 ipsec_common_input_cb(struct mbuf **mp, struct tdb *tdbp, int skip, int protoff)
  357 {
  358         struct mbuf *m = *mp;
  359         int af, sproto;
  360         u_int8_t prot;
  361 #if NBPFILTER > 0
  362         struct ifnet *encif;
  363 #endif
  364         struct ip *ip;
  365 #ifdef INET6
  366         struct ip6_hdr *ip6;
  367 #endif /* INET6 */
  368         struct m_tag *mtag;
  369         struct tdb_ident *tdbi;
  370 #ifdef ENCDEBUG
  371         char buf[INET6_ADDRSTRLEN];
  372 #endif
  373 
  374         af = tdbp->tdb_dst.sa.sa_family;
  375         sproto = tdbp->tdb_sproto;
  376 
  377         tdbp->tdb_last_used = gettime();
  378 
  379         /* Fix IPv4 header */
  380         if (af == AF_INET) {
  381                 if (m->m_len < skip &&
  382                     (m = *mp = m_pullup(m, skip)) == NULL) {
  383                         DPRINTF("processing failed for SA %s/%08x",
  384                             ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)),
  385                             ntohl(tdbp->tdb_spi));
  386                         IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
  387                         goto baddone;
  388                 }
  389 
  390                 ip = mtod(m, struct ip *);
  391                 ip->ip_len = htons(m->m_pkthdr.len);
  392                 ip->ip_sum = 0;
  393                 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
  394                 prot = ip->ip_p;
  395         }
  396 
  397 #ifdef INET6
  398         /* Fix IPv6 header */
  399         if (af == AF_INET6) {
  400                 if (m->m_len < sizeof(struct ip6_hdr) &&
  401                     (m = *mp = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
  402 
  403                         DPRINTF("processing failed for SA %s/%08x",
  404                             ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)),
  405                             ntohl(tdbp->tdb_spi));
  406                         IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
  407                         goto baddone;
  408                 }
  409 
  410                 ip6 = mtod(m, struct ip6_hdr *);
  411                 ip6->ip6_plen = htons(m->m_pkthdr.len - skip);
  412 
  413                 /* Save protocol */
  414                 m_copydata(m, protoff, 1, (caddr_t) &prot);
  415         }
  416 #endif /* INET6 */
  417 
  418         /*
  419          * Fix TCP/UDP checksum of UDP encapsulated transport mode ESP packet.
  420          * (RFC3948 3.1.2)
  421          */
  422         if ((af == AF_INET || af == AF_INET6) &&
  423             (tdbp->tdb_flags & TDBF_UDPENCAP) &&
  424             (tdbp->tdb_flags & TDBF_TUNNELING) == 0) {
  425                 u_int16_t cksum;
  426 
  427                 switch (prot) {
  428                 case IPPROTO_UDP:
  429                         if (m->m_pkthdr.len < skip + sizeof(struct udphdr)) {
  430                                 IPSEC_ISTAT(esps_hdrops, ahs_hdrops,
  431                                     ipcomps_hdrops);
  432                                 goto baddone;
  433                         }
  434                         cksum = 0;
  435                         m_copyback(m, skip + offsetof(struct udphdr, uh_sum),
  436                             sizeof(cksum), &cksum, M_NOWAIT);
  437 #ifdef INET6
  438                         if (af == AF_INET6) {
  439                                 cksum = in6_cksum(m, IPPROTO_UDP, skip,
  440                                     m->m_pkthdr.len - skip);
  441                                 m_copyback(m, skip + offsetof(struct udphdr,
  442                                     uh_sum), sizeof(cksum), &cksum, M_NOWAIT);
  443                         }
  444 #endif
  445                         break;
  446                 case IPPROTO_TCP:
  447                         if (m->m_pkthdr.len < skip + sizeof(struct tcphdr)) {
  448                                 IPSEC_ISTAT(esps_hdrops, ahs_hdrops,
  449                                     ipcomps_hdrops);
  450                                 goto baddone;
  451                         }
  452                         cksum = 0;
  453                         m_copyback(m, skip + offsetof(struct tcphdr, th_sum),
  454                             sizeof(cksum), &cksum, M_NOWAIT);
  455                         if (af == AF_INET)
  456                                 cksum = in4_cksum(m, IPPROTO_TCP, skip,
  457                                     m->m_pkthdr.len - skip);
  458 #ifdef INET6
  459                         else if (af == AF_INET6)
  460                                 cksum = in6_cksum(m, IPPROTO_TCP, skip,
  461                                     m->m_pkthdr.len - skip);
  462 #endif
  463                         m_copyback(m, skip + offsetof(struct tcphdr, th_sum),
  464                             sizeof(cksum), &cksum, M_NOWAIT);
  465                         break;
  466                 }
  467         }
  468 
  469         /*
  470          * Record what we've done to the packet (under what SA it was
  471          * processed).
  472          */
  473         if (tdbp->tdb_sproto != IPPROTO_IPCOMP) {
  474                 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE,
  475                     sizeof(struct tdb_ident), M_NOWAIT);
  476                 if (mtag == NULL) {
  477                         DPRINTF("failed to get tag");
  478                         IPSEC_ISTAT(esps_hdrops, ahs_hdrops, ipcomps_hdrops);
  479                         goto baddone;
  480                 }
  481 
  482                 tdbi = (struct tdb_ident *)(mtag + 1);
  483                 tdbi->dst = tdbp->tdb_dst;
  484                 tdbi->proto = tdbp->tdb_sproto;
  485                 tdbi->spi = tdbp->tdb_spi;
  486                 tdbi->rdomain = tdbp->tdb_rdomain;
  487 
  488                 m_tag_prepend(m, mtag);
  489         }
  490 
  491         switch (sproto) {
  492         case IPPROTO_ESP:
  493                 /* Packet is confidential ? */
  494                 if (tdbp->tdb_encalgxform)
  495                         m->m_flags |= M_CONF;
  496 
  497                 /* Check if we had authenticated ESP. */
  498                 if (tdbp->tdb_authalgxform)
  499                         m->m_flags |= M_AUTH;
  500                 break;
  501         case IPPROTO_AH:
  502                 m->m_flags |= M_AUTH;
  503                 break;
  504         case IPPROTO_IPCOMP:
  505                 m->m_flags |= M_COMP;
  506                 break;
  507         default:
  508                 panic("%s: unknown/unsupported security protocol %d",
  509                     __func__, sproto);
  510         }
  511 
  512 #if NPF > 0
  513         /* Add pf tag if requested. */
  514         pf_tag_packet(m, tdbp->tdb_tag, -1);
  515         pf_pkt_addr_changed(m);
  516 #endif
  517         if (tdbp->tdb_rdomain != tdbp->tdb_rdomain_post)
  518                 m->m_pkthdr.ph_rtableid = tdbp->tdb_rdomain_post;
  519 
  520         if (tdbp->tdb_flags & TDBF_TUNNELING)
  521                 m->m_flags |= M_TUNNEL;
  522 
  523         ipsecstat_add(ipsec_idecompbytes, m->m_pkthdr.len);
  524         tdbstat_add(tdbp, tdb_idecompbytes, m->m_pkthdr.len);
  525 
  526 #if NBPFILTER > 0
  527         encif = enc_getif(tdbp->tdb_rdomain_post, tdbp->tdb_tap);
  528         if (encif != NULL) {
  529                 encif->if_ipackets++;
  530                 encif->if_ibytes += m->m_pkthdr.len;
  531 
  532                 if (sproto != IPPROTO_IPCOMP) {
  533                         /* XXX This conflicts with the scoped nature of IPv6 */
  534                         m->m_pkthdr.ph_ifidx = encif->if_index;
  535                 }
  536                 if (encif->if_bpf) {
  537                         struct enchdr hdr;
  538 
  539                         hdr.af = af;
  540                         hdr.spi = tdbp->tdb_spi;
  541                         hdr.flags = m->m_flags & (M_AUTH|M_CONF);
  542 
  543                         bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
  544                             ENC_HDRLEN, m, BPF_DIRECTION_IN);
  545                 }
  546         }
  547 #endif
  548 
  549 #if NPF > 0
  550         /*
  551          * The ip_deliver() shortcut avoids running through ip_input() with the
  552          * same IP header twice.  Packets in transport mode have to be be
  553          * passed to pf explicitly.  In tunnel mode the inner IP header will
  554          * run through ip_input() and pf anyway.
  555          */
  556         if ((tdbp->tdb_flags & TDBF_TUNNELING) == 0) {
  557                 struct ifnet *ifp;
  558 
  559                 /* This is the enc0 interface unless for ipcomp. */
  560                 if ((ifp = if_get(m->m_pkthdr.ph_ifidx)) == NULL) {
  561                         goto baddone;
  562                 }
  563                 if (pf_test(af, PF_IN, ifp, mp) != PF_PASS) {
  564                         if_put(ifp);
  565                         goto baddone;
  566                 }
  567                 m = *mp;
  568                 if_put(ifp);
  569                 if (m == NULL)
  570                         return IPPROTO_DONE;
  571         }
  572 #endif
  573         /* Return to the appropriate protocol handler in deliver loop. */
  574         return prot;
  575 
  576  baddone:
  577         m_freemp(mp);
  578         return IPPROTO_DONE;
  579 #undef IPSEC_ISTAT
  580 }
  581 
  582 int
  583 ipsec_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  584     size_t newlen)
  585 {
  586         int error;
  587 
  588         switch (name[0]) {
  589         case IPCTL_IPSEC_ENC_ALGORITHM:
  590                 NET_LOCK();
  591                 error = sysctl_tstring(oldp, oldlenp, newp, newlen,
  592                     ipsec_def_enc, sizeof(ipsec_def_enc));
  593                 NET_UNLOCK();
  594                 return (error);
  595         case IPCTL_IPSEC_AUTH_ALGORITHM:
  596                 NET_LOCK();
  597                 error = sysctl_tstring(oldp, oldlenp, newp, newlen,
  598                     ipsec_def_auth, sizeof(ipsec_def_auth));
  599                 NET_UNLOCK();
  600                 return (error);
  601         case IPCTL_IPSEC_IPCOMP_ALGORITHM:
  602                 NET_LOCK();
  603                 error = sysctl_tstring(oldp, oldlenp, newp, newlen,
  604                     ipsec_def_comp, sizeof(ipsec_def_comp));
  605                 NET_UNLOCK();
  606                 return (error);
  607         case IPCTL_IPSEC_STATS:
  608                 return (ipsec_sysctl_ipsecstat(oldp, oldlenp, newp));
  609         default:
  610                 NET_LOCK();
  611                 error = sysctl_bounded_arr(ipsecctl_vars, nitems(ipsecctl_vars),
  612                     name, namelen, oldp, oldlenp, newp, newlen);
  613                 NET_UNLOCK();
  614                 return (error);
  615         }
  616 }
  617 
  618 int
  619 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  620     size_t newlen)
  621 {
  622         int error;
  623 
  624         /* All sysctl names at this level are terminal. */
  625         if (namelen != 1)
  626                 return (ENOTDIR);
  627 
  628         switch (name[0]) {
  629         case ESPCTL_STATS:
  630                 return (esp_sysctl_espstat(oldp, oldlenp, newp));
  631         default:
  632                 NET_LOCK();
  633                 error = sysctl_bounded_arr(espctl_vars, nitems(espctl_vars),
  634                     name, namelen, oldp, oldlenp, newp, newlen);
  635                 NET_UNLOCK();
  636                 return (error);
  637         }
  638 }
  639 
  640 int
  641 esp_sysctl_espstat(void *oldp, size_t *oldlenp, void *newp)
  642 {
  643         struct espstat espstat;
  644 
  645         CTASSERT(sizeof(espstat) == (esps_ncounters * sizeof(uint64_t)));
  646         memset(&espstat, 0, sizeof espstat);
  647         counters_read(espcounters, (uint64_t *)&espstat, esps_ncounters);
  648         return (sysctl_rdstruct(oldp, oldlenp, newp, &espstat,
  649             sizeof(espstat)));
  650 }
  651 
  652 int
  653 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  654     size_t newlen)
  655 {
  656         int error;
  657 
  658         /* All sysctl names at this level are terminal. */
  659         if (namelen != 1)
  660                 return (ENOTDIR);
  661 
  662         switch (name[0]) {
  663         case AHCTL_STATS:
  664                 return ah_sysctl_ahstat(oldp, oldlenp, newp);
  665         default:
  666                 NET_LOCK();
  667                 error = sysctl_bounded_arr(ahctl_vars, nitems(ahctl_vars), name,
  668                     namelen, oldp, oldlenp, newp, newlen);
  669                 NET_UNLOCK();
  670                 return (error);
  671         }
  672 }
  673 
  674 int
  675 ah_sysctl_ahstat(void *oldp, size_t *oldlenp, void *newp)
  676 {
  677         struct ahstat ahstat;
  678 
  679         CTASSERT(sizeof(ahstat) == (ahs_ncounters * sizeof(uint64_t)));
  680         memset(&ahstat, 0, sizeof ahstat);
  681         counters_read(ahcounters, (uint64_t *)&ahstat, ahs_ncounters);
  682         return (sysctl_rdstruct(oldp, oldlenp, newp, &ahstat, sizeof(ahstat)));
  683 }
  684 
  685 int
  686 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  687     size_t newlen)
  688 {
  689         int error;
  690 
  691         /* All sysctl names at this level are terminal. */
  692         if (namelen != 1)
  693                 return (ENOTDIR);
  694 
  695         switch (name[0]) {
  696         case IPCOMPCTL_STATS:
  697                 return ipcomp_sysctl_ipcompstat(oldp, oldlenp, newp);
  698         default:
  699                 NET_LOCK();
  700                 error = sysctl_bounded_arr(ipcompctl_vars,
  701                     nitems(ipcompctl_vars), name, namelen, oldp, oldlenp,
  702                     newp, newlen);
  703                 NET_UNLOCK();
  704                 return (error);
  705         }
  706 }
  707 
  708 int
  709 ipcomp_sysctl_ipcompstat(void *oldp, size_t *oldlenp, void *newp)
  710 {
  711         struct ipcompstat ipcompstat;
  712 
  713         CTASSERT(sizeof(ipcompstat) == (ipcomps_ncounters * sizeof(uint64_t)));
  714         memset(&ipcompstat, 0, sizeof ipcompstat);
  715         counters_read(ipcompcounters, (uint64_t *)&ipcompstat,
  716             ipcomps_ncounters);
  717         return (sysctl_rdstruct(oldp, oldlenp, newp, &ipcompstat,
  718             sizeof(ipcompstat)));
  719 }
  720 
  721 int
  722 ipsec_sysctl_ipsecstat(void *oldp, size_t *oldlenp, void *newp)
  723 {
  724         struct ipsecstat ipsecstat;
  725 
  726         CTASSERT(sizeof(ipsecstat) == (ipsec_ncounters * sizeof(uint64_t)));
  727         memset(&ipsecstat, 0, sizeof ipsecstat);
  728         counters_read(ipseccounters, (uint64_t *)&ipsecstat, ipsec_ncounters);
  729         return (sysctl_rdstruct(oldp, oldlenp, newp, &ipsecstat,
  730             sizeof(ipsecstat)));
  731 }
  732 
  733 int
  734 ipsec_input_disabled(struct mbuf **mp, int *offp, int proto, int af)
  735 {
  736         switch (af) {
  737         case AF_INET:
  738                 return rip_input(mp, offp, proto, af);
  739 #ifdef INET6
  740         case AF_INET6:
  741                 return rip6_input(mp, offp, proto, af);
  742 #endif
  743         default:
  744                 unhandled_af(af);
  745         }
  746 }
  747 
  748 int
  749 ah46_input(struct mbuf **mp, int *offp, int proto, int af)
  750 {
  751         int protoff;
  752 
  753         if (
  754 #if NPF > 0
  755             ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
  756 #endif
  757             !ah_enable)
  758                 return ipsec_input_disabled(mp, offp, proto, af);
  759 
  760         protoff = ipsec_protoff(*mp, *offp, af);
  761         if (protoff < 0) {
  762                 DPRINTF("bad packet header chain");
  763                 ahstat_inc(ahs_hdrops);
  764                 m_freemp(mp);
  765                 return IPPROTO_DONE;
  766         }
  767 
  768         return ipsec_common_input(mp, *offp, protoff, af, proto, 0);
  769 }
  770 
  771 void
  772 ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
  773 {
  774         if (sa->sa_family != AF_INET ||
  775             sa->sa_len != sizeof(struct sockaddr_in))
  776                 return;
  777 
  778         ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_AH);
  779 }
  780 
  781 int
  782 esp46_input(struct mbuf **mp, int *offp, int proto, int af)
  783 {
  784         int protoff;
  785 
  786         if (
  787 #if NPF > 0
  788             ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
  789 #endif
  790             !esp_enable)
  791                 return ipsec_input_disabled(mp, offp, proto, af);
  792 
  793         protoff = ipsec_protoff(*mp, *offp, af);
  794         if (protoff < 0) {
  795                 DPRINTF("bad packet header chain");
  796                 espstat_inc(esps_hdrops);
  797                 m_freemp(mp);
  798                 return IPPROTO_DONE;
  799         }
  800 
  801         return ipsec_common_input(mp, *offp, protoff, af, proto, 0);
  802 }
  803 
  804 /* IPv4 IPCOMP wrapper */
  805 int
  806 ipcomp46_input(struct mbuf **mp, int *offp, int proto, int af)
  807 {
  808         int protoff;
  809 
  810         if (
  811 #if NPF > 0
  812             ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
  813 #endif
  814             !ipcomp_enable)
  815                 return ipsec_input_disabled(mp, offp, proto, af);
  816 
  817         protoff = ipsec_protoff(*mp, *offp, af);
  818         if (protoff < 0) {
  819                 DPRINTF("bad packet header chain");
  820                 ipcompstat_inc(ipcomps_hdrops);
  821                 m_freemp(mp);
  822                 return IPPROTO_DONE;
  823         }
  824 
  825         return ipsec_common_input(mp, *offp, protoff, af, proto, 0);
  826 }
  827 
  828 void
  829 ipsec_set_mtu(struct tdb *tdbp, u_int32_t mtu)
  830 {
  831         ssize_t adjust;
  832 
  833         NET_ASSERT_LOCKED();
  834 
  835         /* Walk the chain backwards to the first tdb */
  836         for (; tdbp != NULL; tdbp = tdbp->tdb_inext) {
  837                 if (tdbp->tdb_flags & TDBF_INVALID ||
  838                     (adjust = ipsec_hdrsz(tdbp)) == -1)
  839                         return;
  840 
  841                 mtu -= adjust;
  842 
  843                 /* Store adjusted MTU in tdb */
  844                 tdbp->tdb_mtu = mtu;
  845                 tdbp->tdb_mtutimeout = gettime() + ip_mtudisc_timeout;
  846                 DPRINTF("spi %08x mtu %d adjust %ld",
  847                     ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, adjust);
  848         }
  849 }
  850 
  851 void
  852 ipsec_common_ctlinput(u_int rdomain, int cmd, struct sockaddr *sa,
  853     void *v, int proto)
  854 {
  855         struct ip *ip = v;
  856 
  857         if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) {
  858                 struct tdb *tdbp;
  859                 struct sockaddr_in dst;
  860                 struct icmp *icp;
  861                 int hlen = ip->ip_hl << 2;
  862                 u_int32_t spi, mtu;
  863 
  864                 /* Find the right MTU. */
  865                 icp = (struct icmp *)((caddr_t) ip -
  866                     offsetof(struct icmp, icmp_ip));
  867                 mtu = ntohs(icp->icmp_nextmtu);
  868 
  869                 /*
  870                  * Ignore the packet, if we do not receive a MTU
  871                  * or the MTU is too small to be acceptable.
  872                  */
  873                 if (mtu < 296)
  874                         return;
  875 
  876                 memset(&dst, 0, sizeof(struct sockaddr_in));
  877                 dst.sin_family = AF_INET;
  878                 dst.sin_len = sizeof(struct sockaddr_in);
  879                 dst.sin_addr.s_addr = ip->ip_dst.s_addr;
  880 
  881                 memcpy(&spi, (caddr_t)ip + hlen, sizeof(u_int32_t));
  882 
  883                 tdbp = gettdb_rev(rdomain, spi, (union sockaddr_union *)&dst,
  884                     proto);
  885                 ipsec_set_mtu(tdbp, mtu);
  886                 tdb_unref(tdbp);
  887         }
  888 }
  889 
  890 void
  891 udpencap_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
  892 {
  893         struct ip *ip = v;
  894         struct tdb *tdbp, *first;
  895         struct icmp *icp;
  896         u_int32_t mtu;
  897         struct sockaddr_in dst, src;
  898         union sockaddr_union *su_dst, *su_src;
  899 
  900         NET_ASSERT_LOCKED();
  901 
  902         icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip));
  903         mtu = ntohs(icp->icmp_nextmtu);
  904 
  905         /*
  906          * Ignore the packet, if we do not receive a MTU
  907          * or the MTU is too small to be acceptable.
  908          */
  909         if (mtu < 296)
  910                 return;
  911 
  912         memset(&dst, 0, sizeof(dst));
  913         dst.sin_family = AF_INET;
  914         dst.sin_len = sizeof(struct sockaddr_in);
  915         dst.sin_addr.s_addr = ip->ip_dst.s_addr;
  916         su_dst = (union sockaddr_union *)&dst;
  917         memset(&src, 0, sizeof(src));
  918         src.sin_family = AF_INET;
  919         src.sin_len = sizeof(struct sockaddr_in);
  920         src.sin_addr.s_addr = ip->ip_src.s_addr;
  921         su_src = (union sockaddr_union *)&src;
  922 
  923         first = gettdbbysrcdst_rev(rdomain, 0, su_src, su_dst, IPPROTO_ESP);
  924 
  925         mtx_enter(&tdb_sadb_mtx);
  926         for (tdbp = first; tdbp != NULL; tdbp = tdbp->tdb_snext) {
  927                 if (tdbp->tdb_sproto == IPPROTO_ESP &&
  928                     ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP)) ==
  929                     TDBF_UDPENCAP) &&
  930                     !memcmp(&tdbp->tdb_dst, &dst, su_dst->sa.sa_len) &&
  931                     !memcmp(&tdbp->tdb_src, &src, su_src->sa.sa_len))
  932                         ipsec_set_mtu(tdbp, mtu);
  933         }
  934         mtx_leave(&tdb_sadb_mtx);
  935         tdb_unref(first);
  936 }
  937 
  938 void
  939 esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
  940 {
  941         if (sa->sa_family != AF_INET ||
  942             sa->sa_len != sizeof(struct sockaddr_in))
  943                 return;
  944 
  945         ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_ESP);
  946 }
  947 
  948 /* Find the offset of the next protocol field in the previous header. */
  949 int
  950 ipsec_protoff(struct mbuf *m, int off, int af)
  951 {
  952 #ifdef INET6
  953         struct ip6_ext ip6e;
  954         int protoff, nxt, l;
  955 #endif /* INET6 */
  956 
  957         switch (af) {
  958         case AF_INET:
  959                 return offsetof(struct ip, ip_p);
  960 #ifdef INET6
  961         case AF_INET6:
  962                 break;
  963 #endif /* INET6 */
  964         default:
  965                 unhandled_af(af);
  966         }
  967 
  968 #ifdef INET6
  969         if (off < sizeof(struct ip6_hdr))
  970                 return -1;
  971 
  972         if (off == sizeof(struct ip6_hdr))
  973                 return offsetof(struct ip6_hdr, ip6_nxt);
  974 
  975         /* Chase down the header chain... */
  976         protoff = sizeof(struct ip6_hdr);
  977         nxt = (mtod(m, struct ip6_hdr *))->ip6_nxt;
  978         l = 0;
  979 
  980         do {
  981                 protoff += l;
  982                 m_copydata(m, protoff, sizeof(ip6e),
  983                     (caddr_t) &ip6e);
  984 
  985                 if (nxt == IPPROTO_AH)
  986                         l = (ip6e.ip6e_len + 2) << 2;
  987                 else
  988                         l = (ip6e.ip6e_len + 1) << 3;
  989 #ifdef DIAGNOSTIC
  990                 if (l <= 0)
  991                         panic("%s: l went zero or negative", __func__);
  992 #endif
  993 
  994                 nxt = ip6e.ip6e_nxt;
  995         } while (protoff + l < off);
  996 
  997         /* Malformed packet check */
  998         if (protoff + l != off)
  999                 return -1;
 1000 
 1001         protoff += offsetof(struct ip6_ext, ip6e_nxt);
 1002         return protoff;
 1003 #endif /* INET6 */
 1004 }
 1005 
 1006 int
 1007 ipsec_forward_check(struct mbuf *m, int hlen, int af)
 1008 {
 1009         struct tdb *tdb;
 1010         struct tdb_ident *tdbi;
 1011         struct m_tag *mtag;
 1012         int error = 0;
 1013 
 1014         /*
 1015          * IPsec policy check for forwarded packets. Look at
 1016          * inner-most IPsec SA used.
 1017          */
 1018         mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
 1019         if (mtag != NULL) {
 1020                 tdbi = (struct tdb_ident *)(mtag + 1);
 1021                 tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst, tdbi->proto);
 1022         } else
 1023                 tdb = NULL;
 1024         error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_IN,
 1025             tdb, NULL, NULL, NULL);
 1026         tdb_unref(tdb);
 1027 
 1028         return error;
 1029 }
 1030 
 1031 int
 1032 ipsec_local_check(struct mbuf *m, int hlen, int proto, int af)
 1033 {
 1034         struct tdb *tdb;
 1035         struct tdb_ident *tdbi;
 1036         struct m_tag *mtag;
 1037         int error = 0;
 1038 
 1039         /*
 1040          * If it's a protected packet for us, skip the policy check.
 1041          * That's because we really only care about the properties of
 1042          * the protected packet, and not the intermediate versions.
 1043          * While this is not the most paranoid setting, it allows
 1044          * some flexibility in handling nested tunnels (in setting up
 1045          * the policies).
 1046          */
 1047         if ((proto == IPPROTO_ESP) || (proto == IPPROTO_AH) ||
 1048             (proto == IPPROTO_IPCOMP))
 1049                 return 0;
 1050 
 1051         /*
 1052          * If the protected packet was tunneled, then we need to
 1053          * verify the protected packet's information, not the
 1054          * external headers. Thus, skip the policy lookup for the
 1055          * external packet, and keep the IPsec information linked on
 1056          * the packet header (the encapsulation routines know how
 1057          * to deal with that).
 1058          */
 1059         if ((proto == IPPROTO_IPV4) || (proto == IPPROTO_IPV6))
 1060                 return 0;
 1061 
 1062         /*
 1063          * When processing IPv6 header chains, do not look at the
 1064          * outer header.  The inner protocol is relevant and will
 1065          * be checked by the local delivery loop later.
 1066          */
 1067         if ((af == AF_INET6) && ((proto == IPPROTO_DSTOPTS) ||
 1068             (proto == IPPROTO_ROUTING) || (proto == IPPROTO_FRAGMENT)))
 1069                 return 0;
 1070 
 1071         /*
 1072          * If the protected packet is TCP or UDP, we'll do the
 1073          * policy check in the respective input routine, so we can
 1074          * check for bypass sockets.
 1075          */
 1076         if ((proto == IPPROTO_TCP) || (proto == IPPROTO_UDP))
 1077                 return 0;
 1078 
 1079         /*
 1080          * IPsec policy check for local-delivery packets. Look at the
 1081          * inner-most SA that protected the packet. This is in fact
 1082          * a bit too restrictive (it could end up causing packets to
 1083          * be dropped that semantically follow the policy, e.g., in
 1084          * certain SA-bundle configurations); but the alternative is
 1085          * very complicated (and requires keeping track of what
 1086          * kinds of tunneling headers have been seen in-between the
 1087          * IPsec headers), and I don't think we lose much functionality
 1088          * that's needed in the real world (who uses bundles anyway ?).
 1089          */
 1090         mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
 1091         if (mtag) {
 1092                 tdbi = (struct tdb_ident *)(mtag + 1);
 1093                 tdb = gettdb(tdbi->rdomain, tdbi->spi, &tdbi->dst,
 1094                     tdbi->proto);
 1095         } else
 1096                 tdb = NULL;
 1097         error = ipsp_spd_lookup(m, af, hlen, IPSP_DIRECTION_IN,
 1098             tdb, NULL, NULL, NULL);
 1099         tdb_unref(tdb);
 1100 
 1101         return error;
 1102 }

Cache object: 7a5f67a2d80d77de8710c01ef4407dc6


[ 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.