* IPComp output routine, called by ipsec[46]_perform_request() */
| 392 | * IPComp output routine, called by ipsec[46]_perform_request() |
| 393 | */ |
| 394 | static int |
| 395 | ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav, |
| 396 | u_int idx, int skip, int protoff) |
| 397 | { |
| 398 | IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); |
| 399 | const struct comp_algo *ipcompx; |
| 400 | struct cryptop *crp; |
| 401 | struct xform_data *xd; |
| 402 | crypto_session_t cryptoid; |
| 403 | int error, ralen, maxpacketsize; |
| 404 | |
| 405 | IPSEC_ASSERT(sav != NULL, ("null SA")); |
| 406 | ipcompx = sav->tdb_compalgxform; |
| 407 | IPSEC_ASSERT(ipcompx != NULL, ("null compression xform")); |
| 408 | |
| 409 | /* |
| 410 | * Do not touch the packet in case our payload to compress |
| 411 | * is lower than the minimal threshold of the compression |
| 412 | * alogrithm. We will just send out the data uncompressed. |
| 413 | * See RFC 3173, 2.2. Non-Expansion Policy. |
| 414 | */ |
| 415 | if (m->m_pkthdr.len <= ipcompx->minlen) { |
| 416 | IPCOMPSTAT_INC(ipcomps_threshold); |
| 417 | return ipsec_process_done(m, sp, sav, idx); |
| 418 | } |
| 419 | |
| 420 | ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */ |
| 421 | IPCOMPSTAT_INC(ipcomps_output); |
| 422 | |
| 423 | /* Check for maximum packet size violations. */ |
| 424 | switch (sav->sah->saidx.dst.sa.sa_family) { |
| 425 | #ifdef INET |
| 426 | case AF_INET: |
| 427 | maxpacketsize = IP_MAXPACKET; |
| 428 | break; |
| 429 | #endif /* INET */ |
| 430 | #ifdef INET6 |
| 431 | case AF_INET6: |
| 432 | maxpacketsize = IPV6_MAXPACKET; |
| 433 | break; |
| 434 | #endif /* INET6 */ |
| 435 | default: |
| 436 | IPCOMPSTAT_INC(ipcomps_nopf); |
| 437 | DPRINTF(("%s: unknown/unsupported protocol family %d, " |
| 438 | "IPCA %s/%08lx\n", __func__, |
| 439 | sav->sah->saidx.dst.sa.sa_family, |
| 440 | ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), |
| 441 | (u_long) ntohl(sav->spi))); |
| 442 | error = EPFNOSUPPORT; |
| 443 | goto bad; |
| 444 | } |
| 445 | if (ralen + skip + IPCOMP_HLENGTH > maxpacketsize) { |
| 446 | IPCOMPSTAT_INC(ipcomps_toobig); |
| 447 | DPRINTF(("%s: packet in IPCA %s/%08lx got too big " |
| 448 | "(len %u, max len %u)\n", __func__, |
| 449 | ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), |
| 450 | (u_long) ntohl(sav->spi), |
| 451 | ralen + skip + IPCOMP_HLENGTH, maxpacketsize)); |
nothing calls this directly
no test coverage detected