1 /* $NetBSD: xform_ipcomp.c,v 1.60 2018/03/10 17:48:32 maxv Exp $ */ 2 /* $FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 3 /* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */ 4 5 /* 6 * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org) 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.60 2018/03/10 17:48:32 maxv Exp $"); 34 35 /* IP payload compression protocol (IPComp), see RFC 2393 */ 36 #if defined(_KERNEL_OPT) 37 #include "opt_inet.h" 38 #endif 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/mbuf.h> 43 #include <sys/socket.h> 44 #include <sys/kernel.h> 45 #include <sys/protosw.h> 46 #include <sys/sysctl.h> 47 #include <sys/pool.h> 48 #include <sys/pserialize.h> 49 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/ip.h> 53 #include <netinet/ip_var.h> 54 55 #include <net/route.h> 56 #include <netipsec/ipsec.h> 57 #include <netipsec/ipsec_private.h> 58 #include <netipsec/xform.h> 59 60 #ifdef INET6 61 #include <netinet/ip6.h> 62 #include <netipsec/ipsec6.h> 63 #endif 64 65 #include <netipsec/ipcomp.h> 66 #include <netipsec/ipcomp_var.h> 67 68 #include <netipsec/key.h> 69 #include <netipsec/key_debug.h> 70 71 #include <opencrypto/cryptodev.h> 72 #include <opencrypto/deflate.h> 73 #include <opencrypto/xform.h> 74 75 percpu_t *ipcompstat_percpu; 76 77 int ipcomp_enable = 1; 78 79 static int ipcomp_input_cb(struct cryptop *crp); 80 static int ipcomp_output_cb(struct cryptop *crp); 81 82 const uint8_t ipcomp_stats[256] = { SADB_CALG_STATS_INIT }; 83 84 static pool_cache_t ipcomp_tdb_crypto_pool_cache; 85 86 const struct comp_algo * 87 ipcomp_algorithm_lookup(int alg) 88 { 89 switch (alg) { 90 case SADB_X_CALG_DEFLATE: 91 return &comp_algo_deflate_nogrow; 92 } 93 return NULL; 94 } 95 96 /* 97 * ipcomp_init() is called when an CPI is being set up. 98 */ 99 static int 100 ipcomp_init(struct secasvar *sav, const struct xformsw *xsp) 101 { 102 const struct comp_algo *tcomp; 103 struct cryptoini cric; 104 int ses; 105 106 /* NB: algorithm really comes in alg_enc and not alg_comp! */ 107 tcomp = ipcomp_algorithm_lookup(sav->alg_enc); 108 if (tcomp == NULL) { 109 DPRINTF(("%s: unsupported compression algorithm %d\n", 110 __func__, sav->alg_comp)); 111 return EINVAL; 112 } 113 sav->alg_comp = sav->alg_enc; /* set for doing histogram */ 114 sav->tdb_xform = xsp; 115 sav->tdb_compalgxform = tcomp; 116 117 /* Initialize crypto session */ 118 memset(&cric, 0, sizeof(cric)); 119 cric.cri_alg = sav->tdb_compalgxform->type; 120 121 ses = crypto_newsession(&sav->tdb_cryptoid, &cric, crypto_support); 122 return ses; 123 } 124 125 /* 126 * ipcomp_zeroize() used when IPCA is deleted 127 */ 128 static int 129 ipcomp_zeroize(struct secasvar *sav) 130 { 131 int err; 132 133 err = crypto_freesession(sav->tdb_cryptoid); 134 sav->tdb_cryptoid = 0; 135 return err; 136 } 137 138 /* 139 * ipcomp_input() gets called to uncompress an input packet 140 */ 141 static int 142 ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) 143 { 144 struct tdb_crypto *tc; 145 struct cryptodesc *crdc; 146 struct cryptop *crp; 147 int error, hlen = IPCOMP_HLENGTH, stat = IPCOMP_STAT_CRYPTO; 148 149 IPSEC_SPLASSERT_SOFTNET(__func__); 150 151 /* Get crypto descriptors */ 152 crp = crypto_getreq(1); 153 if (crp == NULL) { 154 DPRINTF(("%s: no crypto descriptors\n", __func__)); 155 error = ENOBUFS; 156 goto error_m; 157 } 158 /* Get IPsec-specific opaque pointer */ 159 tc = pool_cache_get(ipcomp_tdb_crypto_pool_cache, PR_NOWAIT); 160 if (tc == NULL) { 161 DPRINTF(("%s: cannot allocate tdb_crypto\n", __func__)); 162 error = ENOBUFS; 163 goto error_crp; 164 } 165 166 error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT); 167 if (error) { 168 DPRINTF(("%s: m_makewritable failed\n", __func__)); 169 goto error_tc; 170 } 171 172 { 173 int s = pserialize_read_enter(); 174 175 /* 176 * Take another reference to the SA for opencrypto callback. 177 */ 178 if (__predict_false(sav->state == SADB_SASTATE_DEAD)) { 179 pserialize_read_exit(s); 180 stat = IPCOMP_STAT_NOTDB; 181 error = ENOENT; 182 goto error_tc; 183 } 184 KEY_SA_REF(sav); 185 pserialize_read_exit(s); 186 } 187 188 crdc = crp->crp_desc; 189 190 crdc->crd_skip = skip + hlen; 191 crdc->crd_len = m->m_pkthdr.len - (skip + hlen); 192 crdc->crd_inject = 0; /* unused */ 193 194 /* Decompression operation */ 195 crdc->crd_alg = sav->tdb_compalgxform->type; 196 197 /* Crypto operation descriptor */ 198 crp->crp_ilen = m->m_pkthdr.len - (skip + hlen); 199 crp->crp_olen = MCLBYTES; /* hint to decompression code */ 200 crp->crp_flags = CRYPTO_F_IMBUF; 201 crp->crp_buf = m; 202 crp->crp_callback = ipcomp_input_cb; 203 crp->crp_sid = sav->tdb_cryptoid; 204 crp->crp_opaque = tc; 205 206 /* These are passed as-is to the callback */ 207 tc->tc_spi = sav->spi; 208 tc->tc_dst = sav->sah->saidx.dst; 209 tc->tc_proto = sav->sah->saidx.proto; 210 tc->tc_protoff = protoff; 211 tc->tc_skip = skip; 212 tc->tc_sav = sav; 213 214 return crypto_dispatch(crp); 215 216 error_tc: 217 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 218 error_crp: 219 crypto_freereq(crp); 220 error_m: 221 m_freem(m); 222 IPCOMP_STATINC(stat); 223 return error; 224 } 225 226 #ifdef INET6 227 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) do { \ 228 if (saidx->dst.sa.sa_family == AF_INET6) { \ 229 error = ipsec6_common_input_cb(m, sav, skip, protoff); \ 230 } else { \ 231 error = ipsec4_common_input_cb(m, sav, skip, protoff); \ 232 } \ 233 } while (0) 234 #else 235 #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) \ 236 (error = ipsec4_common_input_cb(m, sav, skip, protoff)) 237 #endif 238 239 /* 240 * IPComp input callback from the crypto driver. 241 */ 242 static int 243 ipcomp_input_cb(struct cryptop *crp) 244 { 245 char buf[IPSEC_ADDRSTRLEN]; 246 struct tdb_crypto *tc; 247 int skip, protoff; 248 struct mbuf *m; 249 struct secasvar *sav; 250 struct secasindex *saidx __diagused; 251 int hlen = IPCOMP_HLENGTH, error, clen; 252 uint8_t nproto; 253 struct ipcomp *ipc; 254 uint16_t dport; 255 uint16_t sport; 256 IPSEC_DECLARE_LOCK_VARIABLE; 257 258 KASSERT(crp->crp_opaque != NULL); 259 tc = crp->crp_opaque; 260 skip = tc->tc_skip; 261 protoff = tc->tc_protoff; 262 m = crp->crp_buf; 263 264 /* find the source port for NAT-T */ 265 nat_t_ports_get(m, &dport, &sport); 266 267 IPSEC_ACQUIRE_GLOBAL_LOCKS(); 268 269 sav = tc->tc_sav; 270 saidx = &sav->sah->saidx; 271 KASSERTMSG(saidx->dst.sa.sa_family == AF_INET || 272 saidx->dst.sa.sa_family == AF_INET6, 273 "unexpected protocol family %u", saidx->dst.sa.sa_family); 274 275 /* Check for crypto errors */ 276 if (crp->crp_etype) { 277 /* Reset the session ID */ 278 if (sav->tdb_cryptoid != 0) 279 sav->tdb_cryptoid = crp->crp_sid; 280 281 if (crp->crp_etype == EAGAIN) { 282 KEY_SA_UNREF(&sav); 283 IPSEC_RELEASE_GLOBAL_LOCKS(); 284 return crypto_dispatch(crp); 285 } 286 287 IPCOMP_STATINC(IPCOMP_STAT_NOXFORM); 288 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype)); 289 error = crp->crp_etype; 290 goto bad; 291 } 292 293 IPCOMP_STATINC(IPCOMP_STAT_HIST + ipcomp_stats[sav->alg_comp]); 294 295 /* Update the counters */ 296 IPCOMP_STATADD(IPCOMP_STAT_IBYTES, m->m_pkthdr.len - skip - hlen); 297 298 /* Length of data after processing */ 299 clen = crp->crp_olen; 300 301 /* Release the crypto descriptors */ 302 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 303 tc = NULL; 304 crypto_freereq(crp); 305 crp = NULL; 306 307 /* In case it's not done already, adjust the size of the mbuf chain */ 308 m->m_pkthdr.len = clen + hlen + skip; 309 310 if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == 0) { 311 IPCOMP_STATINC(IPCOMP_STAT_HDROPS); 312 DPRINTF(("%s: m_pullup failed\n", __func__)); 313 error = EINVAL; 314 goto bad; 315 } 316 317 /* Keep the next protocol field */ 318 ipc = (struct ipcomp *)(mtod(m, uint8_t *) + skip); 319 nproto = ipc->comp_nxt; 320 switch (nproto) { 321 case IPPROTO_IPCOMP: 322 case IPPROTO_AH: 323 case IPPROTO_ESP: 324 IPCOMP_STATINC(IPCOMP_STAT_HDROPS); 325 DPRINTF(("%s: nested ipcomp, IPCA %s/%08lx\n", __func__, 326 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 327 (u_long) ntohl(sav->spi))); 328 error = EINVAL; 329 goto bad; 330 default: 331 break; 332 } 333 334 /* Remove the IPCOMP header */ 335 error = m_striphdr(m, skip, hlen); 336 if (error) { 337 IPCOMP_STATINC(IPCOMP_STAT_HDROPS); 338 DPRINTF(("%s: bad mbuf chain, IPCA %s/%08lx\n", __func__, 339 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 340 (u_long) ntohl(sav->spi))); 341 goto bad; 342 } 343 344 /* Restore the Next Protocol field */ 345 m_copyback(m, protoff, sizeof(uint8_t), (uint8_t *)&nproto); 346 347 IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff); 348 349 KEY_SA_UNREF(&sav); 350 IPSEC_RELEASE_GLOBAL_LOCKS(); 351 return error; 352 353 bad: 354 if (sav) 355 KEY_SA_UNREF(&sav); 356 IPSEC_RELEASE_GLOBAL_LOCKS(); 357 if (m) 358 m_freem(m); 359 if (tc != NULL) 360 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 361 if (crp) 362 crypto_freereq(crp); 363 return error; 364 } 365 366 /* 367 * IPComp output routine, called by ipsec[46]_process_packet() 368 */ 369 static int 370 ipcomp_output(struct mbuf *m, const struct ipsecrequest *isr, 371 struct secasvar *sav, struct mbuf **mp, int skip, int protoff) 372 { 373 char buf[IPSEC_ADDRSTRLEN]; 374 const struct comp_algo *ipcompx; 375 int error, ralen, hlen, maxpacketsize; 376 struct cryptodesc *crdc; 377 struct cryptop *crp; 378 struct tdb_crypto *tc; 379 380 IPSEC_SPLASSERT_SOFTNET(__func__); 381 KASSERT(sav != NULL); 382 KASSERT(sav->tdb_compalgxform != NULL); 383 ipcompx = sav->tdb_compalgxform; 384 385 /* Raw payload length before comp. */ 386 ralen = m->m_pkthdr.len - skip; 387 388 /* Don't process the packet if it is too short */ 389 if (ralen < ipcompx->minlen) { 390 IPCOMP_STATINC(IPCOMP_STAT_MINLEN); 391 return ipsec_process_done(m, isr, sav); 392 } 393 394 hlen = IPCOMP_HLENGTH; 395 396 IPCOMP_STATINC(IPCOMP_STAT_OUTPUT); 397 398 /* Check for maximum packet size violations. */ 399 switch (sav->sah->saidx.dst.sa.sa_family) { 400 #ifdef INET 401 case AF_INET: 402 maxpacketsize = IP_MAXPACKET; 403 break; 404 #endif 405 #ifdef INET6 406 case AF_INET6: 407 maxpacketsize = IPV6_MAXPACKET; 408 break; 409 #endif 410 default: 411 IPCOMP_STATINC(IPCOMP_STAT_NOPF); 412 DPRINTF(("%s: unknown/unsupported protocol family %d" 413 ", IPCA %s/%08lx\n", __func__, 414 sav->sah->saidx.dst.sa.sa_family, 415 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 416 (u_long) ntohl(sav->spi))); 417 error = EPFNOSUPPORT; 418 goto bad; 419 } 420 if (skip + hlen + ralen > maxpacketsize) { 421 IPCOMP_STATINC(IPCOMP_STAT_TOOBIG); 422 DPRINTF(("%s: packet in IPCA %s/%08lx got too big " 423 "(len %u, max len %u)\n", __func__, 424 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 425 (u_long) ntohl(sav->spi), 426 skip + hlen + ralen, maxpacketsize)); 427 error = EMSGSIZE; 428 goto bad; 429 } 430 431 /* Update the counters */ 432 IPCOMP_STATADD(IPCOMP_STAT_OBYTES, m->m_pkthdr.len - skip); 433 434 m = m_clone(m); 435 if (m == NULL) { 436 IPCOMP_STATINC(IPCOMP_STAT_HDROPS); 437 DPRINTF(("%s: cannot clone mbuf chain, IPCA %s/%08lx\n", 438 __func__, 439 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 440 (u_long) ntohl(sav->spi))); 441 error = ENOBUFS; 442 goto bad; 443 } 444 445 /* Ok now, we can pass to the crypto processing */ 446 447 /* Get crypto descriptors */ 448 crp = crypto_getreq(1); 449 if (crp == NULL) { 450 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO); 451 DPRINTF(("%s: failed to acquire crypto descriptor\n", 452 __func__)); 453 error = ENOBUFS; 454 goto bad; 455 } 456 crdc = crp->crp_desc; 457 458 /* Compression descriptor */ 459 crdc->crd_skip = skip; 460 crdc->crd_len = m->m_pkthdr.len - skip; 461 crdc->crd_flags = CRD_F_COMP; 462 crdc->crd_inject = skip; 463 464 /* Compression operation */ 465 crdc->crd_alg = ipcompx->type; 466 467 /* IPsec-specific opaque crypto info */ 468 tc = pool_cache_get(ipcomp_tdb_crypto_pool_cache, PR_NOWAIT); 469 if (tc == NULL) { 470 IPCOMP_STATINC(IPCOMP_STAT_CRYPTO); 471 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 472 crypto_freereq(crp); 473 error = ENOBUFS; 474 goto bad; 475 } 476 477 { 478 int s = pserialize_read_enter(); 479 480 /* 481 * Take another reference to the SP and the SA for opencrypto callback. 482 */ 483 if (__predict_false(isr->sp->state == IPSEC_SPSTATE_DEAD || 484 sav->state == SADB_SASTATE_DEAD)) { 485 pserialize_read_exit(s); 486 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 487 crypto_freereq(crp); 488 IPCOMP_STATINC(IPCOMP_STAT_NOTDB); 489 error = ENOENT; 490 goto bad; 491 } 492 KEY_SP_REF(isr->sp); 493 KEY_SA_REF(sav); 494 pserialize_read_exit(s); 495 } 496 497 tc->tc_isr = isr; 498 tc->tc_spi = sav->spi; 499 tc->tc_dst = sav->sah->saidx.dst; 500 tc->tc_proto = sav->sah->saidx.proto; 501 tc->tc_skip = skip; 502 tc->tc_protoff = protoff; 503 tc->tc_sav = sav; 504 505 /* Crypto operation descriptor */ 506 crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ 507 crp->crp_flags = CRYPTO_F_IMBUF; 508 crp->crp_buf = m; 509 crp->crp_callback = ipcomp_output_cb; 510 crp->crp_opaque = tc; 511 crp->crp_sid = sav->tdb_cryptoid; 512 513 return crypto_dispatch(crp); 514 515 bad: 516 if (m) 517 m_freem(m); 518 return error; 519 } 520 521 /* 522 * IPComp output callback from the crypto driver. 523 */ 524 static int 525 ipcomp_output_cb(struct cryptop *crp) 526 { 527 char buf[IPSEC_ADDRSTRLEN]; 528 struct tdb_crypto *tc; 529 const struct ipsecrequest *isr; 530 struct secasvar *sav; 531 struct mbuf *m, *mo; 532 int error, skip, rlen, roff; 533 uint8_t prot; 534 uint16_t cpi; 535 struct ipcomp * ipcomp; 536 IPSEC_DECLARE_LOCK_VARIABLE; 537 538 KASSERT(crp->crp_opaque != NULL); 539 tc = crp->crp_opaque; 540 m = crp->crp_buf; 541 skip = tc->tc_skip; 542 rlen = crp->crp_ilen - skip; 543 544 IPSEC_ACQUIRE_GLOBAL_LOCKS(); 545 546 isr = tc->tc_isr; 547 sav = tc->tc_sav; 548 549 /* Check for crypto errors */ 550 if (crp->crp_etype) { 551 /* Reset session ID */ 552 if (sav->tdb_cryptoid != 0) 553 sav->tdb_cryptoid = crp->crp_sid; 554 555 if (crp->crp_etype == EAGAIN) { 556 IPSEC_RELEASE_GLOBAL_LOCKS(); 557 return crypto_dispatch(crp); 558 } 559 IPCOMP_STATINC(IPCOMP_STAT_NOXFORM); 560 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype)); 561 error = crp->crp_etype; 562 goto bad; 563 } 564 565 IPCOMP_STATINC(IPCOMP_STAT_HIST + ipcomp_stats[sav->alg_comp]); 566 567 if (rlen > crp->crp_olen) { 568 /* Inject IPCOMP header */ 569 mo = m_makespace(m, skip, IPCOMP_HLENGTH, &roff); 570 if (mo == NULL) { 571 IPCOMP_STATINC(IPCOMP_STAT_WRAP); 572 DPRINTF(("%s: failed to inject IPCOMP header for " 573 "IPCA %s/%08lx\n", __func__, 574 ipsec_address(&sav->sah->saidx.dst, buf, 575 sizeof(buf)), (u_long) ntohl(sav->spi))); 576 error = ENOBUFS; 577 goto bad; 578 } 579 ipcomp = (struct ipcomp *)(mtod(mo, char *) + roff); 580 581 /* Initialize the IPCOMP header */ 582 /* XXX alignment always correct? */ 583 switch (sav->sah->saidx.dst.sa.sa_family) { 584 #ifdef INET 585 case AF_INET: 586 ipcomp->comp_nxt = mtod(m, struct ip *)->ip_p; 587 break; 588 #endif 589 #ifdef INET6 590 case AF_INET6: 591 ipcomp->comp_nxt = mtod(m, struct ip6_hdr *)->ip6_nxt; 592 break; 593 #endif 594 } 595 ipcomp->comp_flags = 0; 596 597 if ((sav->flags & SADB_X_EXT_RAWCPI) == 0) 598 cpi = sav->alg_enc; 599 else 600 cpi = ntohl(sav->spi) & 0xffff; 601 ipcomp->comp_cpi = htons(cpi); 602 603 /* Fix Next Protocol in IPv4/IPv6 header */ 604 prot = IPPROTO_IPCOMP; 605 m_copyback(m, tc->tc_protoff, sizeof(uint8_t), (u_char *)&prot); 606 607 /* Adjust the length in the IP header */ 608 switch (sav->sah->saidx.dst.sa.sa_family) { 609 #ifdef INET 610 case AF_INET: 611 mtod(m, struct ip *)->ip_len = htons(m->m_pkthdr.len); 612 break; 613 #endif 614 #ifdef INET6 615 case AF_INET6: 616 mtod(m, struct ip6_hdr *)->ip6_plen = 617 htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 618 break; 619 #endif 620 default: 621 IPCOMP_STATINC(IPCOMP_STAT_NOPF); 622 DPRINTF(("ipcomp_output: unknown/unsupported protocol " 623 "family %d, IPCA %s/%08lx\n", 624 sav->sah->saidx.dst.sa.sa_family, 625 ipsec_address(&sav->sah->saidx.dst, buf, 626 sizeof(buf)), (u_long) ntohl(sav->spi))); 627 error = EPFNOSUPPORT; 628 goto bad; 629 } 630 } else { 631 /* compression was useless, we have lost time */ 632 IPCOMP_STATINC(IPCOMP_STAT_USELESS); 633 DPRINTF(("ipcomp_output_cb: compression was useless: initial" 634 "size was %d and compressed size is %d\n", rlen, 635 crp->crp_olen)); 636 } 637 638 /* Release the crypto descriptor */ 639 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 640 crypto_freereq(crp); 641 642 /* NB: m is reclaimed by ipsec_process_done. */ 643 error = ipsec_process_done(m, isr, sav); 644 KEY_SA_UNREF(&sav); 645 KEY_SP_UNREF(&isr->sp); 646 IPSEC_RELEASE_GLOBAL_LOCKS(); 647 return error; 648 649 bad: 650 if (sav) 651 KEY_SA_UNREF(&sav); 652 KEY_SP_UNREF(&isr->sp); 653 IPSEC_RELEASE_GLOBAL_LOCKS(); 654 if (m) 655 m_freem(m); 656 pool_cache_put(ipcomp_tdb_crypto_pool_cache, tc); 657 crypto_freereq(crp); 658 return error; 659 } 660 661 static struct xformsw ipcomp_xformsw = { 662 .xf_type = XF_IPCOMP, 663 .xf_flags = XFT_COMP, 664 .xf_name = "IPcomp", 665 .xf_init = ipcomp_init, 666 .xf_zeroize = ipcomp_zeroize, 667 .xf_input = ipcomp_input, 668 .xf_output = ipcomp_output, 669 .xf_next = NULL, 670 }; 671 672 void 673 ipcomp_attach(void) 674 { 675 ipcompstat_percpu = percpu_alloc(sizeof(uint64_t) * IPCOMP_NSTATS); 676 ipcomp_tdb_crypto_pool_cache = pool_cache_init(sizeof(struct tdb_crypto), 677 coherency_unit, 0, 0, "ipcomp_tdb_crypto", NULL, IPL_SOFTNET, 678 NULL, NULL, NULL); 679 xform_register(&ipcomp_xformsw); 680 } 681