Annotation of sys/netinet/ip_ipcomp.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ip_ipcomp.c,v 1.20 2006/03/25 22:41:48 djm Exp $ */
2:
3: /*
4: * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org)
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
29:
30: /* IP payload compression protocol (IPComp), see RFC 2393 */
31:
32: #include <sys/param.h>
33: #include <sys/systm.h>
34: #include <sys/mbuf.h>
35: #include <sys/socket.h>
36:
37: #include <net/if.h>
38: #include <net/bpf.h>
39:
40: #include <dev/rndvar.h>
41:
42: #ifdef INET
43: #include <netinet/in.h>
44: #include <netinet/in_systm.h>
45: #include <netinet/ip.h>
46: #endif /* INET */
47:
48: #ifdef INET6
49: #ifndef INET
50: #include <netinet/in.h>
51: #endif
52: #include <netinet/ip6.h>
53: #endif /* INET6 */
54:
55: #include <netinet/ip_ipsp.h>
56: #include <netinet/ip_ipcomp.h>
57: #include <net/pfkeyv2.h>
58: #include <net/if_enc.h>
59:
60: #include <crypto/cryptodev.h>
61: #include <crypto/deflate.h>
62: #include <crypto/xform.h>
63:
64: #include "bpfilter.h"
65:
66: #ifdef ENCDEBUG
67: #define DPRINTF(x) if (encdebug) printf x
68: #else
69: #define DPRINTF(x)
70: #endif
71:
72: struct ipcompstat ipcompstat;
73:
74: /*
75: * ipcomp_attach() is called from the transformation code
76: */
77: int
78: ipcomp_attach(void)
79: {
80: return 0;
81: }
82:
83: /*
84: * ipcomp_init() is called when an CPI is being set up.
85: */
86: int
87: ipcomp_init(tdbp, xsp, ii)
88: struct tdb *tdbp;
89: struct xformsw *xsp;
90: struct ipsecinit *ii;
91: {
92: struct comp_algo *tcomp = NULL;
93: struct cryptoini cric;
94:
95: switch (ii->ii_compalg) {
96: case SADB_X_CALG_DEFLATE:
97: tcomp = &comp_algo_deflate;
98: break;
99: case SADB_X_CALG_LZS:
100: tcomp = &comp_algo_lzs;
101: break;
102:
103: default:
104: DPRINTF(("ipcomp_init(): unsupported compression algorithm %d specified\n",
105: ii->ii_compalg));
106: return EINVAL;
107: }
108:
109: tdbp->tdb_compalgxform = tcomp;
110:
111: DPRINTF(("ipcomp_init(): initialized TDB with ipcomp algorithm %s\n",
112: tcomp->name));
113:
114: tdbp->tdb_xform = xsp;
115: tdbp->tdb_bitmap = 0;
116:
117: /* Initialize crypto session */
118: bzero(&cric, sizeof(cric));
119: cric.cri_alg = tdbp->tdb_compalgxform->type;
120:
121: return crypto_newsession(&tdbp->tdb_cryptoid, &cric, 0);
122: }
123:
124: /*
125: * ipcomp_zeroize() used when IPCA is deleted
126: */
127: int
128: ipcomp_zeroize(tdbp)
129: struct tdb *tdbp;
130: {
131: int err;
132:
133: err = crypto_freesession(tdbp->tdb_cryptoid);
134: tdbp->tdb_cryptoid = 0;
135: return err;
136: }
137:
138: /*
139: * ipcomp_input() gets called to uncompress an input packet
140: */
141: int
142: ipcomp_input(m, tdb, skip, protoff)
143: struct mbuf *m;
144: struct tdb *tdb;
145: int skip;
146: int protoff;
147: {
148: struct comp_algo *ipcompx = (struct comp_algo *) tdb->tdb_compalgxform;
149: struct tdb_crypto *tc;
150: int hlen;
151:
152: struct cryptodesc *crdc = NULL;
153: struct cryptop *crp;
154:
155: hlen = IPCOMP_HLENGTH;
156:
157: /* Get crypto descriptors */
158: crp = crypto_getreq(1);
159: if (crp == NULL) {
160: m_freem(m);
161: DPRINTF(("ipcomp_input(): failed to acquire crypto descriptors\n"));
162: ipcompstat.ipcomps_crypto++;
163: return ENOBUFS;
164: }
165: /* Get IPsec-specific opaque pointer */
166: MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
167: M_XDATA, M_NOWAIT);
168: if (tc == NULL) {
169: m_freem(m);
170: crypto_freereq(crp);
171: DPRINTF(("ipcomp_input(): failed to allocate tdb_crypto\n"));
172: ipcompstat.ipcomps_crypto++;
173: return ENOBUFS;
174: }
175: bzero(tc, sizeof(struct tdb_crypto));
176: crdc = crp->crp_desc;
177:
178: crdc->crd_skip = skip + hlen;
179: crdc->crd_len = m->m_pkthdr.len - (skip + hlen);
180: crdc->crd_inject = skip;
181:
182: tc->tc_ptr = 0;
183:
184: /* Decompression operation */
185: crdc->crd_alg = ipcompx->type;
186:
187: /* Crypto operation descriptor */
188: crp->crp_ilen = m->m_pkthdr.len - (skip + hlen);
189: crp->crp_flags = CRYPTO_F_IMBUF;
190: crp->crp_buf = (caddr_t) m;
191: crp->crp_callback = (int (*) (struct cryptop *)) ipcomp_input_cb;
192: crp->crp_sid = tdb->tdb_cryptoid;
193: crp->crp_opaque = (caddr_t) tc;
194:
195: /* These are passed as-is to the callback */
196: tc->tc_skip = skip;
197: tc->tc_protoff = protoff;
198: tc->tc_spi = tdb->tdb_spi;
199: tc->tc_proto = IPPROTO_IPCOMP;
200: bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
201:
202: return crypto_dispatch(crp);
203: }
204:
205: /*
206: * IPComp input callback, called directly by the crypto driver
207: */
208: int
209: ipcomp_input_cb(op)
210: void *op;
211: {
212: int error, s, skip, protoff, roff, hlen = IPCOMP_HLENGTH, clen;
213: u_int8_t nproto;
214: struct mbuf *m, *m1, *mo;
215: struct cryptodesc *crd;
216: struct comp_algo *ipcompx;
217: struct tdb_crypto *tc;
218: struct cryptop *crp;
219: struct tdb *tdb;
220: struct ipcomp *ipcomp;
221: caddr_t addr;
222:
223: crp = (struct cryptop *) op;
224: crd = crp->crp_desc;
225:
226: tc = (struct tdb_crypto *) crp->crp_opaque;
227: skip = tc->tc_skip;
228: protoff = tc->tc_protoff;
229:
230: m = (struct mbuf *) crp->crp_buf;
231: if (m == NULL) {
232: /* Shouldn't happen... */
233: FREE(tc, M_XDATA);
234: crypto_freereq(crp);
235: ipcompstat.ipcomps_crypto++;
236: DPRINTF(("ipcomp_input_cb(): bogus returned buffer from crypto\n"));
237: return (EINVAL);
238: }
239:
240: s = spltdb();
241:
242: tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
243: if (tdb == NULL) {
244: FREE(tc, M_XDATA);
245: ipcompstat.ipcomps_notdb++;
246: DPRINTF(("ipcomp_input_cb(): TDB expired while in crypto"));
247: error = EPERM;
248: goto baddone;
249: }
250: ipcompx = (struct comp_algo *) tdb->tdb_compalgxform;
251:
252: /* update the counters */
253: tdb->tdb_cur_bytes += m->m_pkthdr.len - (skip + hlen);
254: ipcompstat.ipcomps_ibytes += m->m_pkthdr.len - (skip + hlen);
255:
256: /* Hard expiration */
257: if ((tdb->tdb_flags & TDBF_BYTES) &&
258: (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
259: FREE(tc, M_XDATA);
260: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
261: tdb_delete(tdb);
262: error = ENXIO;
263: goto baddone;
264: }
265: /* Notify on soft expiration */
266: if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
267: (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
268: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
269: tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
270: }
271:
272: /* Check for crypto errors */
273: if (crp->crp_etype) {
274: if (crp->crp_etype == EAGAIN) {
275: /* Reset the session ID */
276: if (tdb->tdb_cryptoid != 0)
277: tdb->tdb_cryptoid = crp->crp_sid;
278: splx(s);
279: return crypto_dispatch(crp);
280: }
281: FREE(tc, M_XDATA);
282: ipcompstat.ipcomps_noxform++;
283: DPRINTF(("ipcomp_input_cb(): crypto error %d\n",
284: crp->crp_etype));
285: error = crp->crp_etype;
286: goto baddone;
287: }
288: FREE(tc, M_XDATA);
289:
290: /* Length of data after processing */
291: clen = crp->crp_olen;
292:
293: /* In case it's not done already, adjust the size of the mbuf chain */
294: m->m_pkthdr.len = clen + hlen + skip;
295:
296: if ((m->m_len < skip + hlen) && (m = m_pullup(m, skip + hlen)) == 0) {
297: error = ENOBUFS;
298: goto baddone;
299: }
300:
301: /* Find the beginning of the IPCOMP header */
302: m1 = m_getptr(m, skip, &roff);
303: if (m1 == NULL) {
304: ipcompstat.ipcomps_hdrops++;
305: DPRINTF(("ipcomp_input_cb(): bad mbuf chain, IPCA %s/%08x\n",
306: ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
307: error = EINVAL;
308: goto baddone;
309: }
310: /* Keep the next protocol field */
311: addr = (caddr_t) mtod(m, struct ip *) + skip;
312: ipcomp = (struct ipcomp *) addr;
313: nproto = ipcomp->ipcomp_nh;
314:
315: /* Remove the IPCOMP header from the mbuf */
316: if (roff == 0) {
317: /* The IPCOMP header is at the beginning of m1 */
318: m_adj(m1, hlen);
319: if (!(m1->m_flags & M_PKTHDR))
320: m->m_pkthdr.len -= hlen;
321: } else if (roff + hlen >= m1->m_len) {
322: if (roff + hlen > m1->m_len) {
323: /* Adjust the next mbuf by the remainder */
324: m_adj(m1->m_next, roff + hlen - m1->m_len);
325:
326: /*
327: * The second mbuf is guaranteed not to have a
328: * pkthdr...
329: */
330: m->m_pkthdr.len -= (roff + hlen - m1->m_len);
331: }
332: /* Now, let's unlink the mbuf chain for a second... */
333: mo = m1->m_next;
334: m1->m_next = NULL;
335:
336: /* ...and trim the end of the first part of the chain...sick */
337: m_adj(m1, -(m1->m_len - roff));
338: if (!(m1->m_flags & M_PKTHDR))
339: m->m_pkthdr.len -= (m1->m_len - roff);
340:
341: /* Finally, let's relink */
342: m1->m_next = mo;
343: } else {
344: bcopy(mtod(m1, u_char *) + roff + hlen,
345: mtod(m1, u_char *) + roff,
346: m1->m_len - (roff + hlen));
347: m1->m_len -= hlen;
348: m->m_pkthdr.len -= hlen;
349: }
350:
351: /* Release the crypto descriptors */
352: crypto_freereq(crp);
353:
354: /* Restore the Next Protocol field */
355: m_copyback(m, protoff, sizeof(u_int8_t), &nproto);
356:
357: /* Back to generic IPsec input processing */
358: error = ipsec_common_input_cb(m, tdb, skip, protoff, NULL);
359: splx(s);
360: return error;
361:
362: baddone:
363: splx(s);
364:
365: if (m)
366: m_freem(m);
367:
368: crypto_freereq(crp);
369:
370: return error;
371: }
372:
373: /*
374: * IPComp output routine, called by ipsp_process_packet()
375: */
376: int
377: ipcomp_output(m, tdb, mp, skip, protoff)
378: struct mbuf *m;
379: struct tdb *tdb;
380: struct mbuf **mp;
381: int skip;
382: int protoff;
383: {
384: struct comp_algo *ipcompx = (struct comp_algo *) tdb->tdb_compalgxform;
385: int hlen;
386: struct cryptodesc *crdc = NULL;
387: struct cryptop *crp;
388: struct tdb_crypto *tc;
389: struct mbuf *mi, *mo;
390: #if NBPFILTER > 0
391: struct ifnet *ifn = &(encif[0].sc_if);
392:
393: if (ifn->if_bpf) {
394: struct enchdr hdr;
395:
396: bzero(&hdr, sizeof(hdr));
397:
398: hdr.af = tdb->tdb_dst.sa.sa_family;
399: hdr.spi = tdb->tdb_spi;
400:
401: bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, ENC_HDRLEN, m,
402: BPF_DIRECTION_OUT);
403: }
404: #endif
405: hlen = IPCOMP_HLENGTH;
406:
407: ipcompstat.ipcomps_output++;
408:
409: switch (tdb->tdb_dst.sa.sa_family) {
410: #ifdef INET
411: case AF_INET:
412: /* Check for IPv4 maximum packet size violations */
413: /*
414: * Since compression is going to reduce the size, no need to
415: * worry
416: */
417: if (m->m_pkthdr.len + hlen > IP_MAXPACKET) {
418: DPRINTF(("ipcomp_output(): packet in IPCA %s/%08x got too big\n",
419: ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
420: m_freem(m);
421: ipcompstat.ipcomps_toobig++;
422: return EMSGSIZE;
423: }
424: break;
425: #endif /* INET */
426:
427: #ifdef INET6
428: case AF_INET6:
429: /* Check for IPv6 maximum packet size violations */
430: if (m->m_pkthdr.len + hlen > IPV6_MAXPACKET) {
431: DPRINTF(("ipcomp_output(): packet in IPCA %s/%08x got too big\n",
432: ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
433: m_freem(m);
434: ipcompstat.ipcomps_toobig++;
435: return EMSGSIZE;
436: }
437: #endif /* INET6 */
438:
439: default:
440: DPRINTF(("ipcomp_output(): unknown/unsupported protocol family %d, IPCA %s/%08x\n",
441: tdb->tdb_dst.sa.sa_family, ipsp_address(tdb->tdb_dst),
442: ntohl(tdb->tdb_spi)));
443: m_freem(m);
444: ipcompstat.ipcomps_nopf++;
445: return EPFNOSUPPORT;
446: }
447:
448: /* Update the counters */
449:
450: tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
451: ipcompstat.ipcomps_obytes += m->m_pkthdr.len - skip;
452:
453: /* Hard byte expiration */
454: if ((tdb->tdb_flags & TDBF_BYTES) &&
455: (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
456: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
457: tdb_delete(tdb);
458: m_freem(m);
459: return EINVAL;
460: }
461: /* Soft byte expiration */
462: if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
463: (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
464: pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
465: tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
466: }
467: /*
468: * Loop through mbuf chain; if we find a readonly mbuf,
469: * replace the rest of the chain.
470: */
471: mo = NULL;
472: mi = m;
473: while (mi != NULL && !M_READONLY(mi)) {
474: mo = mi;
475: mi = mi->m_next;
476: }
477:
478: if (mi != NULL) {
479: /* Replace the rest of the mbuf chain. */
480: struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
481:
482: if (n == NULL) {
483: DPRINTF(("ipcomp_output(): bad mbuf chain, IPCA %s/%08x\n",
484: ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
485: ipcompstat.ipcomps_hdrops++;
486: m_freem(m);
487: return ENOBUFS;
488: }
489: if (mo != NULL)
490: mo->m_next = n;
491: else
492: m = n;
493:
494: m_freem(mi);
495: }
496: /* Ok now, we can pass to the crypto processing */
497:
498: /* Get crypto descriptors */
499: crp = crypto_getreq(1);
500: if (crp == NULL) {
501: m_freem(m);
502: DPRINTF(("ipcomp_output(): failed to acquire crypto descriptors\n"));
503: ipcompstat.ipcomps_crypto++;
504: return ENOBUFS;
505: }
506: crdc = crp->crp_desc;
507:
508: /* Compression descriptor */
509: crdc->crd_skip = skip;
510: crdc->crd_len = m->m_pkthdr.len - skip;
511: crdc->crd_flags = CRD_F_COMP;
512: crdc->crd_inject = skip;
513:
514: /* Compression operation */
515: crdc->crd_alg = ipcompx->type;
516:
517: /* IPsec-specific opaque crypto info */
518: MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
519: M_XDATA, M_NOWAIT);
520: if (tc == NULL) {
521: m_freem(m);
522: crypto_freereq(crp);
523: DPRINTF(("ipcomp_output(): failed to allocate tdb_crypto\n"));
524: ipcompstat.ipcomps_crypto++;
525: return ENOBUFS;
526: }
527: bzero(tc, sizeof(struct tdb_crypto));
528:
529: tc->tc_spi = tdb->tdb_spi;
530: tc->tc_proto = tdb->tdb_sproto;
531: tc->tc_skip = skip;
532: bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
533:
534: /* Crypto operation descriptor */
535: crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
536: crp->crp_flags = CRYPTO_F_IMBUF;
537: crp->crp_buf = (caddr_t) m;
538: crp->crp_callback = (int (*) (struct cryptop *)) ipcomp_output_cb;
539: crp->crp_opaque = (caddr_t) tc;
540: crp->crp_sid = tdb->tdb_cryptoid;
541:
542: return crypto_dispatch(crp);
543: }
544:
545: /*
546: * IPComp output callback, called directly from the crypto driver
547: */
548: int
549: ipcomp_output_cb(cp)
550: void *cp;
551: {
552: struct cryptop *crp = (struct cryptop *) cp;
553: struct tdb_crypto *tc;
554: struct tdb *tdb;
555: struct mbuf *m, *mo;
556: int error, s, skip, rlen;
557: u_int16_t cpi;
558: #ifdef INET
559: struct ip *ip;
560: #endif
561: #ifdef INET6
562: struct ip6_hdr *ip6;
563: #endif
564: struct ipcomp *ipcomp;
565:
566: tc = (struct tdb_crypto *) crp->crp_opaque;
567: skip = tc->tc_skip;
568: rlen = crp->crp_ilen - skip;
569:
570: m = (struct mbuf *) crp->crp_buf;
571: if (m == NULL) {
572: /* Shouldn't happen... */
573: FREE(tc, M_XDATA);
574: crypto_freereq(crp);
575: ipcompstat.ipcomps_crypto++;
576: DPRINTF(("ipcomp_output_cb(): bogus returned buffer from "
577: "crypto\n"));
578: return (EINVAL);
579: }
580:
581: s = spltdb();
582:
583: tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
584: if (tdb == NULL) {
585: FREE(tc, M_XDATA);
586: ipcompstat.ipcomps_notdb++;
587: DPRINTF(("ipcomp_output_cb(): TDB expired while in crypto\n"));
588: error = EPERM;
589: goto baddone;
590: }
591:
592: /* Check for crypto errors. */
593: if (crp->crp_etype) {
594: if (crp->crp_etype == EAGAIN) {
595: /* Reset the session ID */
596: if (tdb->tdb_cryptoid != 0)
597: tdb->tdb_cryptoid = crp->crp_sid;
598: splx(s);
599: return crypto_dispatch(crp);
600: }
601: FREE(tc, M_XDATA);
602: ipcompstat.ipcomps_noxform++;
603: DPRINTF(("ipcomp_output_cb(): crypto error %d\n",
604: crp->crp_etype));
605: error = crp->crp_etype;
606: goto baddone;
607: }
608: FREE(tc, M_XDATA);
609:
610: /* Check sizes. */
611: if (rlen < crp->crp_olen) {
612: /* Compression was useless, we have lost time. */
613: crypto_freereq(crp);
614: error = ipsp_process_done(m, tdb);
615: splx(s);
616: return error;
617: }
618:
619: /* Inject IPCOMP header */
620: mo = m_inject(m, skip, IPCOMP_HLENGTH, M_DONTWAIT);
621: if (mo == NULL) {
622: DPRINTF(("ipcomp_output_cb(): failed to inject IPCOMP header "
623: "for IPCA %s/%08x\n",
624: ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
625: ipcompstat.ipcomps_wrap++;
626: error = ENOBUFS;
627: goto baddone;
628: }
629:
630: /* Initialize the IPCOMP header */
631: ipcomp = mtod(mo, struct ipcomp *);
632: bzero(ipcomp, sizeof(struct ipcomp));
633: cpi = (u_int16_t) ntohl(tdb->tdb_spi);
634: ipcomp->ipcomp_cpi = htons(cpi);
635:
636: /* m_pullup before ? */
637: switch (tdb->tdb_dst.sa.sa_family) {
638: #ifdef INET
639: case AF_INET:
640: ip = mtod(m, struct ip *);
641: ipcomp->ipcomp_nh = ip->ip_p;
642: ip->ip_p = IPPROTO_IPCOMP;
643: break;
644: #endif /* INET */
645: #ifdef INET6
646: case AF_INET6:
647: ip6 = mtod(m, struct ip6_hdr *);
648: ipcomp->ipcomp_nh = ip6->ip6_nxt;
649: ip6->ip6_nxt = IPPROTO_IPCOMP;
650: break;
651: #endif
652: default:
653: DPRINTF(("ipcomp_output_cb(): unsupported protocol family %d, "
654: "IPCA %s/%08x\n",
655: tdb->tdb_dst.sa.sa_family, ipsp_address(tdb->tdb_dst),
656: ntohl(tdb->tdb_spi)));
657: ipcompstat.ipcomps_nopf++;
658: error = EPFNOSUPPORT;
659: goto baddone;
660: break;
661: }
662:
663: /* Release the crypto descriptor. */
664: crypto_freereq(crp);
665:
666: error = ipsp_process_done(m, tdb);
667: splx(s);
668: return error;
669:
670: baddone:
671: splx(s);
672:
673: if (m)
674: m_freem(m);
675:
676: crypto_freereq(crp);
677:
678: return error;
679: }
CVSweb