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