root/netinet/ipsec_output.c

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

DEFINITIONS

This source file includes following definitions.
  1. ipsp_process_packet
  2. ipsp_process_done
  3. ipsec_hdrsz
  4. ipsec_adjust_mtu

    1 /*      $OpenBSD: ipsec_output.c,v 1.39 2007/06/01 00:52:38 henning 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 "pf.h"
   24 
   25 #include <sys/param.h>
   26 #include <sys/systm.h>
   27 #include <sys/mbuf.h>
   28 #include <sys/socket.h>
   29 #include <sys/kernel.h>
   30 
   31 #include <net/if.h>
   32 #include <net/route.h>
   33 
   34 #if NPF > 0
   35 #include <net/pfvar.h>
   36 #endif
   37 
   38 #ifdef INET
   39 #include <netinet/in.h>
   40 #include <netinet/in_systm.h>
   41 #include <netinet/ip.h>
   42 #include <netinet/in_pcb.h>
   43 #include <netinet/ip_var.h>
   44 #endif /* INET */
   45 
   46 #ifdef INET6
   47 #ifndef INET
   48 #include <netinet/in.h>
   49 #endif
   50 #include <netinet6/in6_var.h>
   51 #endif /* INET6 */
   52 
   53 #include <netinet/udp.h>
   54 #include <netinet/ip_ipsp.h>
   55 #include <netinet/ip_ah.h>
   56 #include <netinet/ip_esp.h>
   57 #include <netinet/ip_ipcomp.h>
   58 #include <crypto/xform.h>
   59 
   60 #ifdef ENCDEBUG
   61 #define DPRINTF(x)      if (encdebug) printf x
   62 #else
   63 #define DPRINTF(x)
   64 #endif
   65 
   66 int     udpencap_enable = 1;    /* enabled by default */
   67 int     udpencap_port = 4500;   /* triggers decapsulation */
   68 
   69 /*
   70  * Loop over a tdb chain, taking into consideration protocol tunneling. The
   71  * fourth argument is set if the first encapsulation header is already in
   72  * place.
   73  */
   74 int
   75 ipsp_process_packet(struct mbuf *m, struct tdb *tdb, int af, int tunalready)
   76 {
   77         struct timeval tv;
   78         int i, off, error;
   79         struct mbuf *mp;
   80 #ifdef INET6
   81         struct ip6_ext ip6e;
   82         int nxt;
   83         int dstopt = 0;
   84 #endif
   85 
   86 #ifdef INET
   87         int setdf = 0;
   88         struct ip *ip;
   89 #endif /* INET */
   90 #ifdef INET6
   91         struct ip6_hdr *ip6;
   92 #endif /* INET6 */
   93 
   94         /* Check that the transform is allowed by the administrator. */
   95         if ((tdb->tdb_sproto == IPPROTO_ESP && !esp_enable) ||
   96             (tdb->tdb_sproto == IPPROTO_AH && !ah_enable) ||
   97             (tdb->tdb_sproto == IPPROTO_IPCOMP && !ipcomp_enable)) {
   98                 DPRINTF(("ipsp_process_packet(): IPsec outbound packet "
   99                     "dropped due to policy (check your sysctls)\n"));
  100                 m_freem(m);
  101                 return EHOSTUNREACH;
  102         }
  103 
  104         /* Sanity check. */
  105         if (!tdb->tdb_xform) {
  106                 DPRINTF(("ipsp_process_packet(): uninitialized TDB\n"));
  107                 m_freem(m);
  108                 return EHOSTUNREACH;
  109         }
  110 
  111         /* Check if the SPI is invalid. */
  112         if (tdb->tdb_flags & TDBF_INVALID) {
  113                 DPRINTF(("ipsp_process_packet(): attempt to use invalid "
  114                     "SA %s/%08x/%u\n", ipsp_address(tdb->tdb_dst),
  115                     ntohl(tdb->tdb_spi), tdb->tdb_sproto));
  116                 m_freem(m);
  117                 return ENXIO;
  118         }
  119 
  120         /* Check that the network protocol is supported */
  121         switch (tdb->tdb_dst.sa.sa_family) {
  122 #ifdef INET
  123         case AF_INET:
  124                 break;
  125 #endif /* INET */
  126 
  127 #ifdef INET6
  128         case AF_INET6:
  129                 break;
  130 #endif /* INET6 */
  131 
  132         default:
  133                 DPRINTF(("ipsp_process_packet(): attempt to use "
  134                     "SA %s/%08x/%u for protocol family %d\n",
  135                     ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi),
  136                     tdb->tdb_sproto, tdb->tdb_dst.sa.sa_family));
  137                 m_freem(m);
  138                 return ENXIO;
  139         }
  140 
  141         /*
  142          * Register first use if applicable, setup relevant expiration timer.
  143          */
  144         if (tdb->tdb_first_use == 0) {
  145                 tdb->tdb_first_use = time_second;
  146 
  147                 tv.tv_usec = 0;
  148 
  149                 tv.tv_sec = tdb->tdb_first_use + tdb->tdb_exp_first_use;
  150                 if (tdb->tdb_flags & TDBF_FIRSTUSE)
  151                         timeout_add(&tdb->tdb_first_tmo,
  152                             hzto(&tv));
  153 
  154                 tv.tv_sec = tdb->tdb_first_use + tdb->tdb_soft_first_use;
  155                 if (tdb->tdb_flags & TDBF_SOFT_FIRSTUSE)
  156                         timeout_add(&tdb->tdb_sfirst_tmo,
  157                             hzto(&tv));
  158         }
  159 
  160         /*
  161          * Check for tunneling if we don't have the first header in place.
  162          * When doing Ethernet-over-IP, we are handed an already-encapsulated
  163          * frame, so we don't need to re-encapsulate.
  164          */
  165         if (tunalready == 0) {
  166                 /*
  167                  * If the target protocol family is different, we know we'll be
  168                  * doing tunneling.
  169                  */
  170                 if (af == tdb->tdb_dst.sa.sa_family) {
  171 #ifdef INET
  172                         if (af == AF_INET)
  173                                 i = sizeof(struct ip);
  174 #endif /* INET */
  175 
  176 #ifdef INET6
  177                         if (af == AF_INET6)
  178                                 i = sizeof(struct ip6_hdr);
  179 #endif /* INET6 */
  180 
  181                         /* Bring the network header in the first mbuf. */
  182                         if (m->m_len < i) {
  183                                 if ((m = m_pullup(m, i)) == NULL)
  184                                         return ENOBUFS;
  185                         }
  186 
  187 #ifdef INET
  188                         ip = mtod(m, struct ip *);
  189 
  190                         /*
  191                          * This is not a bridge packet, remember if we
  192                          * had IP_DF.
  193                          */
  194                         setdf = ip->ip_off & htons(IP_DF);
  195 #endif /* INET */
  196 
  197 #ifdef INET6
  198                         ip6 = mtod(m, struct ip6_hdr *);
  199 #endif /* INET6 */
  200                 }
  201 
  202                 /* Do the appropriate encapsulation, if necessary. */
  203                 if ((tdb->tdb_dst.sa.sa_family != af) || /* PF mismatch */
  204                     (tdb->tdb_flags & TDBF_TUNNELING) || /* Tunneling needed */
  205                     (tdb->tdb_xform->xf_type == XF_IP4) || /* ditto */
  206 #ifdef INET
  207                     ((tdb->tdb_dst.sa.sa_family == AF_INET) &&
  208                         (tdb->tdb_dst.sin.sin_addr.s_addr != INADDR_ANY) &&
  209                         (tdb->tdb_dst.sin.sin_addr.s_addr != ip->ip_dst.s_addr)) ||
  210 #endif /* INET */
  211 #ifdef INET6
  212                     ((tdb->tdb_dst.sa.sa_family == AF_INET6) &&
  213                         (!IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr)) &&
  214                         (!IN6_ARE_ADDR_EQUAL(&tdb->tdb_dst.sin6.sin6_addr,
  215                             &ip6->ip6_dst))) ||
  216 #endif /* INET6 */
  217                     0) {
  218 #ifdef INET
  219                         /* Fix IPv4 header checksum and length. */
  220                         if (af == AF_INET) {
  221                                 if (m->m_len < sizeof(struct ip))
  222                                         if ((m = m_pullup(m,
  223                                             sizeof(struct ip))) == NULL)
  224                                                 return ENOBUFS;
  225 
  226                                 ip = mtod(m, struct ip *);
  227                                 ip->ip_len = htons(m->m_pkthdr.len);
  228                                 ip->ip_sum = 0;
  229                                 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
  230                         }
  231 #endif /* INET */
  232 
  233 #ifdef INET6
  234                         /* Fix IPv6 header payload length. */
  235                         if (af == AF_INET6) {
  236                                 if (m->m_len < sizeof(struct ip6_hdr))
  237                                         if ((m = m_pullup(m,
  238                                             sizeof(struct ip6_hdr))) == NULL)
  239                                                 return ENOBUFS;
  240 
  241                                 if (m->m_pkthdr.len - sizeof(*ip6) >
  242                                     IPV6_MAXPACKET) {
  243                                         /* No jumbogram support. */
  244                                         m_freem(m);
  245                                         return ENXIO;   /*?*/
  246                                 }
  247                                 ip6 = mtod(m, struct ip6_hdr *);
  248                                 ip6->ip6_plen = htons(m->m_pkthdr.len
  249                                     - sizeof(*ip6));
  250                         }
  251 #endif /* INET6 */
  252 
  253                         /* Encapsulate -- the last two arguments are unused. */
  254                         error = ipip_output(m, tdb, &mp, 0, 0);
  255                         if ((mp == NULL) && (!error))
  256                                 error = EFAULT;
  257                         if (error) {
  258                                 if (mp) {
  259                                         m_freem(mp);
  260                                         mp = NULL;
  261                                 }
  262                                 return error;
  263                         }
  264 
  265                         m = mp;
  266                         mp = NULL;
  267 
  268 #ifdef INET
  269                         if (tdb->tdb_dst.sa.sa_family == AF_INET && setdf) {
  270                                 if (m->m_len < sizeof(struct ip))
  271                                         if ((m = m_pullup(m,
  272                                             sizeof(struct ip))) == NULL)
  273                                                 return ENOBUFS;
  274 
  275                                 ip = mtod(m, struct ip *);
  276                                 ip->ip_off |= htons(IP_DF);
  277                         }
  278 #endif
  279 
  280                         /* Remember that we appended a tunnel header. */
  281                         tdb->tdb_flags |= TDBF_USEDTUNNEL;
  282                 }
  283 
  284                 /* We may be done with this TDB */
  285                 if (tdb->tdb_xform->xf_type == XF_IP4)
  286                         return ipsp_process_done(m, tdb);
  287         } else {
  288                 /*
  289                  * If this is just an IP-IP TDB and we're told there's
  290                  * already an encapsulation header, move on.
  291                  */
  292                 if (tdb->tdb_xform->xf_type == XF_IP4)
  293                         return ipsp_process_done(m, tdb);
  294         }
  295 
  296         /* Extract some information off the headers. */
  297         switch (tdb->tdb_dst.sa.sa_family) {
  298 #ifdef INET
  299         case AF_INET:
  300                 ip = mtod(m, struct ip *);
  301                 i = ip->ip_hl << 2;
  302                 off = offsetof(struct ip, ip_p);
  303                 break;
  304 #endif /* INET */
  305 
  306 #ifdef INET6
  307         case AF_INET6:
  308                 ip6 = mtod(m, struct ip6_hdr *);
  309                 i = sizeof(struct ip6_hdr);
  310                 off = offsetof(struct ip6_hdr, ip6_nxt);
  311                 nxt = ip6->ip6_nxt;
  312                 /*
  313                  * chase mbuf chain to find the appropriate place to
  314                  * put AH/ESP/IPcomp header.
  315                  *      IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
  316                  */
  317                 do {
  318                         switch (nxt) {
  319                         case IPPROTO_AH:
  320                         case IPPROTO_ESP:
  321                         case IPPROTO_IPCOMP:
  322                                 /*
  323                                  * we should not skip security header added
  324                                  * beforehand.
  325                                  */
  326                                 goto exitip6loop;
  327 
  328                         case IPPROTO_HOPOPTS:
  329                         case IPPROTO_DSTOPTS:
  330                         case IPPROTO_ROUTING:
  331                                 /*
  332                                  * if we see 2nd destination option header,
  333                                  * we should stop there.
  334                                  */
  335                                 if (nxt == IPPROTO_DSTOPTS && dstopt)
  336                                         goto exitip6loop;
  337 
  338                                 if (nxt == IPPROTO_DSTOPTS) {
  339                                         /*
  340                                          * seen 1st or 2nd destination option.
  341                                          * next time we see one, it must be 2nd.
  342                                          */
  343                                         dstopt = 1;
  344                                 } else if (nxt == IPPROTO_ROUTING) {
  345                                         /*
  346                                          * if we see destionation option next
  347                                          * time, it must be dest2.
  348                                          */
  349                                         dstopt = 2;
  350                                 }
  351 
  352                                 /* skip this header */
  353                                 m_copydata(m, i, sizeof(ip6e), (caddr_t)&ip6e);
  354                                 nxt = ip6e.ip6e_nxt;
  355                                 off = i + offsetof(struct ip6_ext, ip6e_nxt);
  356                                 /*
  357                                  * we will never see nxt == IPPROTO_AH
  358                                  * so it is safe to omit AH case.
  359                                  */
  360                                 i += (ip6e.ip6e_len + 1) << 3;
  361                                 break;
  362                         default:
  363                                 goto exitip6loop;
  364                         }
  365                 } while (i < m->m_pkthdr.len);
  366         exitip6loop:;
  367                 break;
  368 #endif /* INET6 */
  369         }
  370 
  371         /* Non expansion policy for IPCOMP */
  372         if (tdb->tdb_sproto == IPPROTO_IPCOMP) {
  373                 if ((m->m_pkthdr.len - i) < tdb->tdb_compalgxform->minlen) {
  374                         extern struct ipcompstat ipcompstat;
  375 
  376                         /* No need to compress, leave the packet untouched */
  377                         ipcompstat.ipcomps_minlen++;
  378                         return ipsp_process_done(m, tdb);
  379                 }
  380         }
  381 
  382         /* Invoke the IPsec transform. */
  383         return (*(tdb->tdb_xform->xf_output))(m, tdb, NULL, i, off);
  384 }
  385 
  386 /*
  387  * Called by the IPsec output transform callbacks, to transmit the packet
  388  * or do further processing, as necessary.
  389  */
  390 int
  391 ipsp_process_done(struct mbuf *m, struct tdb *tdb)
  392 {
  393 #ifdef INET
  394         struct ip *ip;
  395 #endif /* INET */
  396 
  397 #ifdef INET6
  398         struct ip6_hdr *ip6;
  399 #endif /* INET6 */
  400 
  401         struct tdb_ident *tdbi;
  402         struct m_tag *mtag;
  403 
  404         tdb->tdb_last_used = time_second;
  405 
  406         if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) {
  407                 struct mbuf *mi;
  408                 struct udphdr *uh;
  409 
  410                 if (!udpencap_enable || !udpencap_port) {
  411                         m_freem(m);
  412                         return ENXIO;
  413                 }
  414                 mi = m_inject(m, sizeof(struct ip), sizeof(struct udphdr),
  415                     M_DONTWAIT);
  416                 if (mi == NULL) {
  417                         m_freem(m);
  418                         return ENOMEM;
  419                 }
  420                 uh = mtod(mi, struct udphdr *);
  421                 uh->uh_sport = uh->uh_dport = htons(udpencap_port);
  422                 if (tdb->tdb_udpencap_port)
  423                         uh->uh_dport = tdb->tdb_udpencap_port;
  424 
  425                 uh->uh_ulen = htons(m->m_pkthdr.len - sizeof(struct ip));
  426                 uh->uh_sum = 0;
  427                 espstat.esps_udpencout++;
  428         }
  429 
  430         switch (tdb->tdb_dst.sa.sa_family) {
  431 #ifdef INET
  432         case AF_INET:
  433                 /* Fix the header length, for AH processing. */
  434                 ip = mtod(m, struct ip *);
  435                 ip->ip_len = htons(m->m_pkthdr.len);
  436                 if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0)
  437                         ip->ip_p = IPPROTO_UDP;
  438                 break;
  439 #endif /* INET */
  440 
  441 #ifdef INET6
  442         case AF_INET6:
  443                 /* Fix the header length, for AH processing. */
  444                 if (m->m_pkthdr.len < sizeof(*ip6)) {
  445                         m_freem(m);
  446                         return ENXIO;
  447                 }
  448                 if (m->m_pkthdr.len - sizeof(*ip6) > IPV6_MAXPACKET) {
  449                         /* No jumbogram support. */
  450                         m_freem(m);
  451                         return ENXIO;
  452                 }
  453                 ip6 = mtod(m, struct ip6_hdr *);
  454                 ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
  455                 if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0)
  456                         ip6->ip6_nxt = IPPROTO_UDP;
  457                 break;
  458 #endif /* INET6 */
  459 
  460         default:
  461                 m_freem(m);
  462                 DPRINTF(("ipsp_process_done(): unknown protocol family (%d)\n",
  463                     tdb->tdb_dst.sa.sa_family));
  464                 return ENXIO;
  465         }
  466 
  467         /*
  468          * Add a record of what we've done or what needs to be done to the
  469          * packet.
  470          */
  471         if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
  472                 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_DONE,
  473                     sizeof(struct tdb_ident),
  474                     M_NOWAIT);
  475         else
  476                 mtag = m_tag_get(PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED,
  477                     sizeof(struct tdb_ident), M_NOWAIT);
  478 
  479         if (mtag == NULL) {
  480                 m_freem(m);
  481                 DPRINTF(("ipsp_process_done(): could not allocate packet "
  482                     "tag\n"));
  483                 return ENOMEM;
  484         }
  485 
  486         tdbi = (struct tdb_ident *)(mtag + 1);
  487         bcopy(&tdb->tdb_dst, &tdbi->dst, sizeof(union sockaddr_union));
  488         tdbi->proto = tdb->tdb_sproto;
  489         tdbi->spi = tdb->tdb_spi;
  490 
  491         m_tag_prepend(m, mtag);
  492 
  493         /* If there's another (bundled) TDB to apply, do so. */
  494         if (tdb->tdb_onext)
  495                 return ipsp_process_packet(m, tdb->tdb_onext,
  496                     tdb->tdb_dst.sa.sa_family, 0);
  497 
  498 #if NPF > 0
  499         /* Add pf tag if requested. */
  500         if (pf_tag_packet(m, tdb->tdb_tag, -1))
  501                 DPRINTF(("failed to tag ipsec packet\n"));
  502 #endif
  503 
  504         /*
  505          * We're done with IPsec processing, transmit the packet using the
  506          * appropriate network protocol (IP or IPv6). SPD lookup will be
  507          * performed again there.
  508          */
  509         switch (tdb->tdb_dst.sa.sa_family) {
  510 #ifdef INET
  511         case AF_INET:
  512                 return ip_output(m, (void *)NULL, (void *)NULL, IP_RAWOUTPUT, (void *)NULL, (void *)NULL);
  513 #endif /* INET */
  514 
  515 #ifdef INET6
  516         case AF_INET6:
  517                 /*
  518                  * We don't need massage, IPv6 header fields are always in
  519                  * net endian.
  520                  */
  521                 return ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
  522 #endif /* INET6 */
  523         }
  524         return EINVAL; /* Not reached. */
  525 }
  526 
  527 ssize_t
  528 ipsec_hdrsz(struct tdb *tdbp)
  529 {
  530         ssize_t adjust;
  531 
  532         switch (tdbp->tdb_sproto) {
  533         case IPPROTO_IPIP:
  534                 adjust = 0;
  535                 break;
  536 
  537         case IPPROTO_ESP:
  538                 if (tdbp->tdb_encalgxform == NULL)
  539                         return (-1);
  540 
  541                 /* Header length */
  542                 if (tdbp->tdb_flags & TDBF_NOREPLAY)
  543                         adjust = sizeof(u_int32_t) + tdbp->tdb_ivlen;
  544                 else
  545                         adjust = 2 * sizeof(u_int32_t) + tdbp->tdb_ivlen;
  546                 if (tdbp->tdb_flags & TDBF_UDPENCAP)
  547                         adjust += sizeof(struct udphdr);
  548                 /* Authenticator */
  549                 if (tdbp->tdb_authalgxform != NULL)
  550                         adjust += AH_HMAC_HASHLEN;
  551                 /* Padding */
  552                 adjust += tdbp->tdb_encalgxform->blocksize;
  553                 break;
  554 
  555         case IPPROTO_AH:
  556                 if (tdbp->tdb_authalgxform == NULL)
  557                         return (-1);
  558 
  559                 if (!(tdbp->tdb_flags & TDBF_NOREPLAY))
  560                         adjust = AH_FLENGTH + sizeof(u_int32_t);
  561                 else
  562                         adjust = AH_FLENGTH;
  563                 adjust += tdbp->tdb_authalgxform->authsize;
  564                 break;
  565 
  566         default:
  567                 return (-1);
  568         }
  569 
  570         if (!(tdbp->tdb_flags & TDBF_TUNNELING) &&
  571             !(tdbp->tdb_flags & TDBF_USEDTUNNEL))
  572                 return (adjust);
  573 
  574         switch (tdbp->tdb_dst.sa.sa_family) {
  575 #ifdef INET
  576         case AF_INET:
  577                 adjust += sizeof(struct ip);
  578                 break;
  579 #endif /* INET */
  580 #ifdef INET6
  581         case AF_INET6:
  582                 adjust += sizeof(struct ip6_hdr);
  583                 break;
  584 #endif /* INET6 */
  585         }
  586 
  587         return (adjust);
  588 }
  589 
  590 void
  591 ipsec_adjust_mtu(struct mbuf *m, u_int32_t mtu)
  592 {
  593         struct tdb_ident *tdbi;
  594         struct tdb *tdbp;
  595         struct m_tag *mtag;
  596         ssize_t adjust;
  597         int s;
  598 
  599         s = spltdb();
  600 
  601         for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL); mtag;
  602              mtag = m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, mtag)) {
  603                 tdbi = (struct tdb_ident *)(mtag + 1);
  604                 tdbp = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
  605                 if (tdbp == NULL)
  606                         break;
  607 
  608                 if ((adjust = ipsec_hdrsz(tdbp)) == -1)
  609                         break;
  610 
  611                 mtu -= adjust;
  612                 tdbp->tdb_mtu = mtu;
  613                 tdbp->tdb_mtutimeout = time_second + ip_mtudisc_timeout;
  614                 DPRINTF(("ipsec_adjust_mtu: "
  615                     "spi %08x mtu %d adjust %d mbuf %p\n",
  616                     ntohl(tdbp->tdb_spi), tdbp->tdb_mtu,
  617                     adjust, m));
  618         }
  619 
  620         splx(s);
  621 }

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