Only add the IPcomp header if crypto reported success and we have a lower
payload size. Before we had always added the header, no matter if we actually send out compressed data or not. With this, after the opencrypto/deflate changes, IPcomp starts to work apart from edge cases. Leave it disabled by default until those are fixed as well. PR: kern/123587 MFC after: 5 days
This commit is contained in:
parent
66ad43d7a0
commit
89a2398493
@ -330,13 +330,10 @@ ipcomp_output(
|
||||
{
|
||||
struct secasvar *sav;
|
||||
struct comp_algo *ipcompx;
|
||||
int error, ralen, hlen, maxpacketsize, roff;
|
||||
u_int8_t prot;
|
||||
int error, ralen, maxpacketsize;
|
||||
struct cryptodesc *crdc;
|
||||
struct cryptop *crp;
|
||||
struct tdb_crypto *tc;
|
||||
struct mbuf *mo;
|
||||
struct ipcomp *ipcomp;
|
||||
|
||||
sav = isr->sav;
|
||||
IPSEC_ASSERT(sav != NULL, ("null SA"));
|
||||
@ -355,8 +352,6 @@ ipcomp_output(
|
||||
}
|
||||
|
||||
ralen = m->m_pkthdr.len - skip; /* Raw payload length before comp. */
|
||||
hlen = IPCOMP_HLENGTH;
|
||||
|
||||
V_ipcompstat.ipcomps_output++;
|
||||
|
||||
/* Check for maximum packet size violations. */
|
||||
@ -381,13 +376,13 @@ ipcomp_output(
|
||||
error = EPFNOSUPPORT;
|
||||
goto bad;
|
||||
}
|
||||
if (skip + hlen + ralen > maxpacketsize) {
|
||||
if (ralen + skip + IPCOMP_HLENGTH > maxpacketsize) {
|
||||
V_ipcompstat.ipcomps_toobig++;
|
||||
DPRINTF(("%s: packet in IPCA %s/%08lx got too big "
|
||||
"(len %u, max len %u)\n", __func__,
|
||||
ipsec_address(&sav->sah->saidx.dst),
|
||||
(u_long) ntohl(sav->spi),
|
||||
skip + hlen + ralen, maxpacketsize));
|
||||
ralen + skip + IPCOMP_HLENGTH, maxpacketsize));
|
||||
error = EMSGSIZE;
|
||||
goto bad;
|
||||
}
|
||||
@ -405,40 +400,7 @@ ipcomp_output(
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Inject IPCOMP header */
|
||||
mo = m_makespace(m, skip, hlen, &roff);
|
||||
if (mo == NULL) {
|
||||
V_ipcompstat.ipcomps_wrap++;
|
||||
DPRINTF(("%s: IPCOMP header inject failed for IPCA %s/%08lx\n",
|
||||
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||
(u_long) ntohl(sav->spi)));
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
ipcomp = (struct ipcomp *)(mtod(mo, caddr_t) + roff);
|
||||
|
||||
/* Initialize the IPCOMP header */
|
||||
/* XXX alignment always correct? */
|
||||
switch (sav->sah->saidx.dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
ipcomp->comp_nxt = mtod(m, struct ip *)->ip_p;
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
ipcomp->comp_nxt = mtod(m, struct ip6_hdr *)->ip6_nxt;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
ipcomp->comp_flags = 0;
|
||||
ipcomp->comp_cpi = htons((u_int16_t) ntohl(sav->spi));
|
||||
|
||||
/* Fix Next Protocol in IPv4/IPv6 header */
|
||||
prot = IPPROTO_IPCOMP;
|
||||
m_copyback(m, protoff, sizeof(u_int8_t), (u_char *) &prot);
|
||||
|
||||
/* Ok now, we can pass to the crypto processing */
|
||||
/* Ok now, we can pass to the crypto processing. */
|
||||
|
||||
/* Get crypto descriptors */
|
||||
crp = crypto_getreq(1);
|
||||
@ -451,10 +413,10 @@ ipcomp_output(
|
||||
crdc = crp->crp_desc;
|
||||
|
||||
/* Compression descriptor */
|
||||
crdc->crd_skip = skip + hlen;
|
||||
crdc->crd_len = m->m_pkthdr.len - (skip + hlen);
|
||||
crdc->crd_skip = skip;
|
||||
crdc->crd_len = ralen;
|
||||
crdc->crd_flags = CRD_F_COMP;
|
||||
crdc->crd_inject = skip + hlen;
|
||||
crdc->crd_inject = skip;
|
||||
|
||||
/* Compression operation */
|
||||
crdc->crd_alg = ipcompx->type;
|
||||
@ -474,7 +436,8 @@ ipcomp_output(
|
||||
tc->tc_spi = sav->spi;
|
||||
tc->tc_dst = sav->sah->saidx.dst;
|
||||
tc->tc_proto = sav->sah->saidx.proto;
|
||||
tc->tc_skip = skip + hlen;
|
||||
tc->tc_protoff = protoff;
|
||||
tc->tc_skip = skip;
|
||||
|
||||
/* Crypto operation descriptor */
|
||||
crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
|
||||
@ -501,13 +464,12 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
struct ipsecrequest *isr;
|
||||
struct secasvar *sav;
|
||||
struct mbuf *m;
|
||||
int error, skip, rlen;
|
||||
int error, skip;
|
||||
|
||||
tc = (struct tdb_crypto *) crp->crp_opaque;
|
||||
IPSEC_ASSERT(tc != NULL, ("null opaque data area!"));
|
||||
m = (struct mbuf *) crp->crp_buf;
|
||||
skip = tc->tc_skip;
|
||||
rlen = crp->crp_ilen - skip;
|
||||
|
||||
isr = tc->tc_isr;
|
||||
IPSECREQUEST_LOCK(isr);
|
||||
@ -529,8 +491,7 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
if (crp->crp_etype == EAGAIN) {
|
||||
KEY_FREESAV(&sav);
|
||||
IPSECREQUEST_UNLOCK(isr);
|
||||
error = crypto_dispatch(crp);
|
||||
return error;
|
||||
return crypto_dispatch(crp);
|
||||
}
|
||||
V_ipcompstat.ipcomps_noxform++;
|
||||
DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
|
||||
@ -546,7 +507,46 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
}
|
||||
V_ipcompstat.ipcomps_hist[sav->alg_comp]++;
|
||||
|
||||
if (rlen > crp->crp_olen) {
|
||||
if (crp->crp_ilen - skip > crp->crp_olen) {
|
||||
struct mbuf *mo;
|
||||
struct ipcomp *ipcomp;
|
||||
int roff;
|
||||
uint8_t prot;
|
||||
|
||||
/* Compression helped, inject IPCOMP header. */
|
||||
mo = m_makespace(m, skip, IPCOMP_HLENGTH, &roff);
|
||||
if (mo == NULL) {
|
||||
V_ipcompstat.ipcomps_wrap++;
|
||||
DPRINTF(("%s: IPCOMP header inject failed for IPCA %s/%08lx\n",
|
||||
__func__, ipsec_address(&sav->sah->saidx.dst),
|
||||
(u_long) ntohl(sav->spi)));
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
ipcomp = (struct ipcomp *)(mtod(mo, caddr_t) + roff);
|
||||
|
||||
/* Initialize the IPCOMP header */
|
||||
/* XXX alignment always correct? */
|
||||
switch (sav->sah->saidx.dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
ipcomp->comp_nxt = mtod(m, struct ip *)->ip_p;
|
||||
break;
|
||||
#endif /* INET */
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
ipcomp->comp_nxt = mtod(m, struct ip6_hdr *)->ip6_nxt;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
ipcomp->comp_flags = 0;
|
||||
ipcomp->comp_cpi = htons((u_int16_t) ntohl(sav->spi));
|
||||
|
||||
/* Fix Next Protocol in IPv4/IPv6 header */
|
||||
prot = IPPROTO_IPCOMP;
|
||||
m_copyback(m, tc->tc_protoff, sizeof(u_int8_t),
|
||||
(u_char *)&prot);
|
||||
|
||||
/* Adjust the length in the IP header */
|
||||
switch (sav->sah->saidx.dst.sa.sa_family) {
|
||||
#ifdef INET
|
||||
@ -573,6 +573,8 @@ ipcomp_output_cb(struct cryptop *crp)
|
||||
} else {
|
||||
/* compression was useless, we have lost time */
|
||||
/* XXX add statistic */
|
||||
/* XXX remember state to not compress the next couple
|
||||
* of packets, RFC 3173, 2.2. Non-Expansion Policy */
|
||||
}
|
||||
|
||||
/* Release the crypto descriptor */
|
||||
|
Loading…
x
Reference in New Issue
Block a user