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