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