1 /* $FreeBSD: src/sys/netipsec/ipsec_input.c,v 1.2.4.2 2003/03/28 20:32:53 sam Exp $ */
2 /* $OpenBSD: ipsec_input.c,v 1.63 2003/02/20 18:35:43 deraadt Exp $ */
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
8 * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
11 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
12 * by Angelos D. Keromytis.
14 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
17 * Additional features in 1999 by Angelos D. Keromytis.
19 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
20 * Angelos D. Keromytis and Niels Provos.
21 * Copyright (c) 2001, Angelos D. Keromytis.
23 * Permission to use, copy, and modify this software with or without fee
24 * is hereby granted, provided that this entire notice is included in
25 * all copies of any software which is or includes a copy or
26 * modification of this software.
27 * You may use this code under the GNU public license if you so wish. Please
28 * contribute changes back to the authors under this freer than GPL license
29 * so that we may further the use of strong encryption without limitations to
32 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
33 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
34 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
35 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
40 * IPsec input processing.
44 #include "opt_inet6.h"
45 #include "opt_ipsec.h"
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/malloc.h>
51 #include <sys/domain.h>
52 #include <sys/protosw.h>
53 #include <sys/socket.h>
54 #include <sys/errno.h>
55 #include <sys/syslog.h>
56 #include <sys/in_cksum.h>
59 #include <net/route.h>
60 #include <net/netisr.h>
62 #include <netinet/in.h>
63 #include <netinet/in_systm.h>
64 #include <netinet/ip.h>
65 #include <netinet/ip_var.h>
66 #include <netinet/in_var.h>
68 #include <netinet/ip6.h>
70 #include <netinet6/ip6_var.h>
72 #include <netinet/in_pcb.h>
74 #include <netinet/icmp6.h>
77 #include <netproto/ipsec/ipsec.h>
79 #include <netproto/ipsec/ipsec6.h>
81 #include <netproto/ipsec/ah_var.h>
82 #include <netproto/ipsec/esp.h>
83 #include <netproto/ipsec/esp_var.h>
84 #include <netproto/ipsec/ipcomp_var.h>
86 #include <netproto/ipsec/key.h>
87 #include <netproto/ipsec/keydb.h>
89 #include <netproto/ipsec/xform.h>
90 #include <netinet6/ip6protosw.h>
92 #include <machine/stdarg.h>
94 #include <net/net_osdep.h>
96 #define IPSEC_ISTAT(p,x,y,z) ((p) == IPPROTO_ESP ? (x)++ : \
97 (p) == IPPROTO_AH ? (y)++ : (z)++)
100 * ipsec_common_input gets called when an IPsec-protected packet
101 * is received by IPv4 or IPv6. It's job is to find the right SA
102 # and call the appropriate transform. The transform callback
103 * takes care of further processing (like ingress filtering).
106 ipsec_common_input(struct mbuf
*m
, int skip
, int protoff
, int af
, int sproto
)
108 union sockaddr_union dst_address
;
109 struct secasvar
*sav
;
113 IPSEC_ISTAT(sproto
, espstat
.esps_input
, ahstat
.ahs_input
,
114 ipcompstat
.ipcomps_input
);
116 KASSERT(m
!= NULL
, ("ipsec_common_input: null packet"));
118 if ((sproto
== IPPROTO_ESP
&& !esp_enable
) ||
119 (sproto
== IPPROTO_AH
&& !ah_enable
) ||
120 (sproto
== IPPROTO_IPCOMP
&& !ipcomp_enable
)) {
122 IPSEC_ISTAT(sproto
, espstat
.esps_pdrops
, ahstat
.ahs_pdrops
,
123 ipcompstat
.ipcomps_pdrops
);
127 if (m
->m_pkthdr
.len
- skip
< 2 * sizeof (u_int32_t
)) {
129 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
, ahstat
.ahs_hdrops
,
130 ipcompstat
.ipcomps_hdrops
);
131 DPRINTF(("ipsec_common_input: packet too small\n"));
135 /* Retrieve the SPI from the relevant IPsec header */
136 if (sproto
== IPPROTO_ESP
)
137 m_copydata(m
, skip
, sizeof(u_int32_t
), (caddr_t
) &spi
);
138 else if (sproto
== IPPROTO_AH
)
139 m_copydata(m
, skip
+ sizeof(u_int32_t
), sizeof(u_int32_t
),
141 else if (sproto
== IPPROTO_IPCOMP
) {
143 m_copydata(m
, skip
+ sizeof(u_int16_t
), sizeof(u_int16_t
),
145 spi
= ntohl(htons(cpi
));
149 * Find the SA and (indirectly) call the appropriate
150 * kernel crypto routine. The resulting mbuf chain is a valid
151 * IP packet ready to go through input processing.
153 bzero(&dst_address
, sizeof (dst_address
));
154 dst_address
.sa
.sa_family
= af
;
158 dst_address
.sin
.sin_len
= sizeof(struct sockaddr_in
);
159 m_copydata(m
, offsetof(struct ip
, ip_dst
),
160 sizeof(struct in_addr
),
161 (caddr_t
) &dst_address
.sin
.sin_addr
);
166 dst_address
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
167 m_copydata(m
, offsetof(struct ip6_hdr
, ip6_dst
),
168 sizeof(struct in6_addr
),
169 (caddr_t
) &dst_address
.sin6
.sin6_addr
);
173 DPRINTF(("ipsec_common_input: unsupported protocol "
176 IPSEC_ISTAT(sproto
, espstat
.esps_nopf
, ahstat
.ahs_nopf
,
177 ipcompstat
.ipcomps_nopf
);
183 /* NB: only pass dst since key_allocsa follows RFC2401 */
184 sav
= KEY_ALLOCSA(&dst_address
, sproto
, spi
);
186 DPRINTF(("ipsec_common_input: no key association found for"
188 ipsec_address(&dst_address
),
189 (u_long
) ntohl(spi
), sproto
));
190 IPSEC_ISTAT(sproto
, espstat
.esps_notdb
, ahstat
.ahs_notdb
,
191 ipcompstat
.ipcomps_notdb
);
197 if (sav
->tdb_xform
== NULL
) {
198 DPRINTF(("ipsec_common_input: attempted to use uninitialized"
200 ipsec_address(&dst_address
),
201 (u_long
) ntohl(spi
), sproto
));
202 IPSEC_ISTAT(sproto
, espstat
.esps_noxform
, ahstat
.ahs_noxform
,
203 ipcompstat
.ipcomps_noxform
);
211 * Call appropriate transform and return -- callback takes care of
214 error
= (*sav
->tdb_xform
->xf_input
)(m
, sav
, skip
, protoff
);
222 * Common input handler for IPv4 AH, ESP, and IPCOMP.
225 ipsec4_common_input(struct mbuf
**m
, int *offp
, int proto
)
227 return ipsec_common_input(*m
, *offp
, offsetof(struct ip
, ip_p
),
232 * IPsec input callback for INET protocols.
233 * This routine is called as the transform callback.
234 * Takes care of filtering and other sanity checks on
235 * the processed packet.
238 ipsec4_common_input_cb(struct mbuf
*m
, struct secasvar
*sav
,
239 int skip
, int protoff
, struct m_tag
*mt
)
241 int prot
, af
, sproto
;
244 struct tdb_ident
*tdbi
;
245 struct secasindex
*saidx
;
248 KASSERT(m
!= NULL
, ("ipsec4_common_input_cb: null mbuf"));
249 KASSERT(sav
!= NULL
, ("ipsec4_common_input_cb: null SA"));
250 KASSERT(sav
->sah
!= NULL
, ("ipsec4_common_input_cb: null SAH"));
251 saidx
= &sav
->sah
->saidx
;
252 af
= saidx
->dst
.sa
.sa_family
;
253 KASSERT(af
== AF_INET
, ("ipsec4_common_input_cb: unexpected af %u",af
));
254 sproto
= saidx
->proto
;
255 KASSERT(sproto
== IPPROTO_ESP
|| sproto
== IPPROTO_AH
||
256 sproto
== IPPROTO_IPCOMP
,
257 ("ipsec4_common_input_cb: unexpected security protocol %u",
262 DPRINTF(("ipsec4_common_input_cb: null mbuf"));
263 IPSEC_ISTAT(sproto
, espstat
.esps_badkcr
, ahstat
.ahs_badkcr
,
264 ipcompstat
.ipcomps_badkcr
);
270 /* Fix IPv4 header */
271 if (m
->m_len
< skip
&& (m
= m_pullup(m
, skip
)) == NULL
) {
272 DPRINTF(("ipsec4_common_input_cb: processing failed "
274 ipsec_address(&sav
->sah
->saidx
.dst
),
275 (u_long
) ntohl(sav
->spi
)));
276 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
, ahstat
.ahs_hdrops
,
277 ipcompstat
.ipcomps_hdrops
);
282 ip
= mtod(m
, struct ip
*);
283 ip
->ip_len
= htons(m
->m_pkthdr
.len
);
284 ip
->ip_off
= htons(ip
->ip_off
);
286 ip
->ip_sum
= in_cksum(m
, ip
->ip_hl
<< 2);
288 ip
= mtod(m
, struct ip
*);
292 /* IP-in-IP encapsulation */
293 if (prot
== IPPROTO_IPIP
) {
296 if (m
->m_pkthdr
.len
- skip
< sizeof(struct ip
)) {
297 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
298 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
303 /* ipn will now contain the inner IPv4 header */
304 m_copydata(m
, skip
, sizeof(struct ip
), (caddr_t
) &ipn
);
307 /* XXX PROXY address isn't recorded in SAH */
309 * Check that the inner source address is the same as
310 * the proxy address, if available.
312 if ((saidx
->proxy
.sa
.sa_family
== AF_INET
&&
313 saidx
->proxy
.sin
.sin_addr
.s_addr
!=
316 saidx
->proxy
.sin
.sin_addr
.s_addr
) ||
317 (saidx
->proxy
.sa
.sa_family
!= AF_INET
&&
318 saidx
->proxy
.sa
.sa_family
!= 0)) {
320 DPRINTF(("ipsec4_common_input_cb: inner "
321 "source address %s doesn't correspond to "
322 "expected proxy source %s, SA %s/%08lx\n",
323 inet_ntoa4(ipn
.ip_src
),
324 ipsp_address(saidx
->proxy
),
325 ipsp_address(saidx
->dst
),
326 (u_long
) ntohl(sav
->spi
)));
328 IPSEC_ISTAT(sproto
, espstat
.esps_pdrops
,
330 ipcompstat
.ipcomps_pdrops
);
337 /* IPv6-in-IP encapsulation. */
338 if (prot
== IPPROTO_IPV6
) {
341 if (m
->m_pkthdr
.len
- skip
< sizeof(struct ip6_hdr
)) {
342 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
343 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
348 /* ip6n will now contain the inner IPv6 header. */
349 m_copydata(m
, skip
, sizeof(struct ip6_hdr
), (caddr_t
) &ip6n
);
353 * Check that the inner source address is the same as
354 * the proxy address, if available.
356 if ((saidx
->proxy
.sa
.sa_family
== AF_INET6
&&
357 !IN6_IS_ADDR_UNSPECIFIED(&saidx
->proxy
.sin6
.sin6_addr
) &&
358 !IN6_ARE_ADDR_EQUAL(&ip6n
.ip6_src
,
359 &saidx
->proxy
.sin6
.sin6_addr
)) ||
360 (saidx
->proxy
.sa
.sa_family
!= AF_INET6
&&
361 saidx
->proxy
.sa
.sa_family
!= 0)) {
363 DPRINTF(("ipsec4_common_input_cb: inner "
364 "source address %s doesn't correspond to "
365 "expected proxy source %s, SA %s/%08lx\n",
366 ip6_sprintf(&ip6n
.ip6_src
),
367 ipsec_address(&saidx
->proxy
),
368 ipsec_address(&saidx
->dst
),
369 (u_long
) ntohl(sav
->spi
)));
371 IPSEC_ISTAT(sproto
, espstat
.esps_pdrops
,
373 ipcompstat
.ipcomps_pdrops
);
382 * Record what we've done to the packet (under what SA it was
383 * processed). If we've been passed an mtag, it means the packet
384 * was already processed by an ethernet/crypto combo card and
385 * thus has a tag attached with all the right information, but
386 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
387 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
389 if (mt
== NULL
&& sproto
!= IPPROTO_IPCOMP
) {
390 mtag
= m_tag_get(PACKET_TAG_IPSEC_IN_DONE
,
391 sizeof(struct tdb_ident
), M_NOWAIT
);
393 DPRINTF(("ipsec4_common_input_cb: failed to get tag\n"));
394 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
395 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
400 tdbi
= (struct tdb_ident
*)m_tag_data(mtag
);
401 bcopy(&saidx
->dst
, &tdbi
->dst
, saidx
->dst
.sa
.sa_len
);
402 tdbi
->proto
= sproto
;
403 tdbi
->spi
= sav
->spi
;
405 m_tag_prepend(m
, mtag
);
407 mt
->m_tag_id
= PACKET_TAG_IPSEC_IN_DONE
;
408 /* XXX do we need to mark m_flags??? */
411 key_sa_recordxfer(sav
, m
); /* record data transfer */
414 * Re-dispatch via software interrupt.
416 if (netisr_queue(NETISR_IP
, m
)) {
417 IPSEC_ISTAT(sproto
, espstat
.esps_qfull
, ahstat
.ahs_qfull
,
418 ipcompstat
.ipcomps_qfull
);
420 DPRINTF(("ipsec4_common_input_cb: queue full; "
421 "proto %u packet dropped\n", sproto
));
432 /* IPv6 AH wrapper. */
434 ipsec6_common_input(struct mbuf
**mp
, int *offp
, int proto
)
440 if (*offp
< sizeof(struct ip6_hdr
)) {
441 DPRINTF(("ipsec6_common_input: bad offset %u\n", *offp
));
443 } else if (*offp
== sizeof(struct ip6_hdr
)) {
444 protoff
= offsetof(struct ip6_hdr
, ip6_nxt
);
446 /* Chase down the header chain... */
447 protoff
= sizeof(struct ip6_hdr
);
451 m_copydata(*mp
, protoff
, sizeof(ip6e
),
454 if (ip6e
.ip6e_nxt
== IPPROTO_AH
)
455 l
= (ip6e
.ip6e_len
+ 2) << 2;
457 l
= (ip6e
.ip6e_len
+ 1) << 3;
458 KASSERT(l
> 0, ("ah6_input: l went zero or negative"));
459 } while (protoff
+ l
< *offp
);
461 /* Malformed packet check */
462 if (protoff
+ l
!= *offp
) {
463 DPRINTF(("ipsec6_common_input: bad packet header chain, "
464 "protoff %u, l %u, off %u\n", protoff
, l
, *offp
));
465 IPSEC_ISTAT(proto
, espstat
.esps_hdrops
,
467 ipcompstat
.ipcomps_hdrops
);
472 protoff
+= offsetof(struct ip6_ext
, ip6e_nxt
);
474 ipsec_common_input(*mp
, *offp
, protoff
, AF_INET6
, proto
);
479 esp6_ctlinput(netmsg_t msg
)
481 int cmd
= msg
->ctlinput
.nm_cmd
;
482 struct sockaddr
*sa
= msg
->ctlinput
.nm_arg
;
483 void *d
= msg
->ctlinput
.nm_extra
;
485 if (sa
->sa_family
!= AF_INET6
||
486 sa
->sa_len
!= sizeof(struct sockaddr_in6
))
488 if ((unsigned)cmd
>= PRC_NCMDS
)
491 /* if the parameter is from icmp6, decode it. */
493 struct ip6ctlparam
*ip6cp
= (struct ip6ctlparam
*)d
;
494 struct mbuf
*m
= ip6cp
->ip6c_m
;
495 int off
= ip6cp
->ip6c_off
;
497 struct ip6ctlparam ip6cp1
;
500 * Notify the error to all possible sockets via kpfctlinput2.
501 * Since the upper layer information (such as protocol type,
502 * source and destination ports) is embedded in the encrypted
503 * data and might have been cut, we can't directly call
504 * an upper layer ctlinput function. However, the pcbnotify
505 * function will consider source and destination addresses
506 * as well as the flow info value, and may be able to find
507 * some PCB that should be notified.
508 * Although kpfctlinput2 will call esp6_ctlinput(), there is
509 * no possibility of an infinite loop of function calls,
510 * because we don't pass the inner IPv6 header.
512 bzero(&ip6cp1
, sizeof(ip6cp1
));
513 ip6cp1
.ip6c_src
= ip6cp
->ip6c_src
;
514 kpfctlinput2(cmd
, sa
, (void *)&ip6cp1
);
517 * Then go to special cases that need ESP header information.
518 * XXX: We assume that when ip6 is non NULL,
519 * M and OFF are valid.
522 if (cmd
== PRC_MSGSIZE
) {
523 struct secasvar
*sav
;
527 /* check header length before using m_copydata */
528 if (m
->m_pkthdr
.len
< off
+ sizeof (struct esp
))
530 m_copydata(m
, off
+ offsetof(struct esp
, esp_spi
),
531 sizeof(u_int32_t
), (caddr_t
) &spi
);
533 * Check to see if we have a valid SA corresponding to
534 * the address in the ICMP message payload.
536 sav
= KEY_ALLOCSA((union sockaddr_union
*)sa
,
538 valid
= (sav
!= NULL
);
542 /* XXX Further validation? */
545 * Depending on whether the SA is "valid" and
546 * routing table size (mtudisc_{hi,lo}wat), we will:
547 * - recalcurate the new MTU and create the
548 * corresponding routing entry, or
549 * - ignore the MTU change notification.
551 icmp6_mtudisc_update(ip6cp
, valid
);
554 /* we normally notify any pcb here */
558 extern struct protosw inet6sw
[];
559 extern u_char ip6_protox
[];
562 * IPsec input callback, called by the transform callback. Takes care of
563 * filtering and other sanity checks on the processed packet.
566 ipsec6_common_input_cb(struct mbuf
*m
, struct secasvar
*sav
, int skip
, int protoff
,
569 int prot
, af
, sproto
;
572 struct tdb_ident
*tdbi
;
573 struct secasindex
*saidx
;
578 KASSERT(m
!= NULL
, ("ipsec6_common_input_cb: null mbuf"));
579 KASSERT(sav
!= NULL
, ("ipsec6_common_input_cb: null SA"));
580 KASSERT(sav
->sah
!= NULL
, ("ipsec6_common_input_cb: null SAH"));
581 saidx
= &sav
->sah
->saidx
;
582 af
= saidx
->dst
.sa
.sa_family
;
583 KASSERT(af
== AF_INET6
,
584 ("ipsec6_common_input_cb: unexpected af %u", af
));
585 sproto
= saidx
->proto
;
586 KASSERT(sproto
== IPPROTO_ESP
|| sproto
== IPPROTO_AH
||
587 sproto
== IPPROTO_IPCOMP
,
588 ("ipsec6_common_input_cb: unexpected security protocol %u",
593 DPRINTF(("ipsec4_common_input_cb: null mbuf"));
594 IPSEC_ISTAT(sproto
, espstat
.esps_badkcr
, ahstat
.ahs_badkcr
,
595 ipcompstat
.ipcomps_badkcr
);
600 /* Fix IPv6 header */
601 if (m
->m_len
< sizeof(struct ip6_hdr
) &&
602 (m
= m_pullup(m
, sizeof(struct ip6_hdr
))) == NULL
) {
604 DPRINTF(("ipsec_common_input_cb: processing failed "
605 "for SA %s/%08lx\n", ipsec_address(&sav
->sah
->saidx
.dst
),
606 (u_long
) ntohl(sav
->spi
)));
608 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
, ahstat
.ahs_hdrops
,
609 ipcompstat
.ipcomps_hdrops
);
614 ip6
= mtod(m
, struct ip6_hdr
*);
615 ip6
->ip6_plen
= htons(m
->m_pkthdr
.len
- sizeof(struct ip6_hdr
));
618 m_copydata(m
, protoff
, 1, (unsigned char *) &prot
);
621 /* IP-in-IP encapsulation */
622 if (prot
== IPPROTO_IPIP
) {
625 if (m
->m_pkthdr
.len
- skip
< sizeof(struct ip
)) {
626 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
627 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
632 /* ipn will now contain the inner IPv4 header */
633 m_copydata(m
, skip
, sizeof(struct ip
), (caddr_t
) &ipn
);
637 * Check that the inner source address is the same as
638 * the proxy address, if available.
640 if ((saidx
->proxy
.sa
.sa_family
== AF_INET
&&
641 saidx
->proxy
.sin
.sin_addr
.s_addr
!= INADDR_ANY
&&
642 ipn
.ip_src
.s_addr
!= saidx
->proxy
.sin
.sin_addr
.s_addr
) ||
643 (saidx
->proxy
.sa
.sa_family
!= AF_INET
&&
644 saidx
->proxy
.sa
.sa_family
!= 0)) {
646 DPRINTF(("ipsec_common_input_cb: inner "
647 "source address %s doesn't correspond to "
648 "expected proxy source %s, SA %s/%08lx\n",
649 inet_ntoa4(ipn
.ip_src
),
650 ipsec_address(&saidx
->proxy
),
651 ipsec_address(&saidx
->dst
),
652 (u_long
) ntohl(sav
->spi
)));
654 IPSEC_ISTATsproto
, (espstat
.esps_pdrops
,
655 ahstat
.ahs_pdrops
, ipcompstat
.ipcomps_pdrops
);
663 /* IPv6-in-IP encapsulation */
664 if (prot
== IPPROTO_IPV6
) {
667 if (m
->m_pkthdr
.len
- skip
< sizeof(struct ip6_hdr
)) {
668 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
669 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
674 /* ip6n will now contain the inner IPv6 header. */
675 m_copydata(m
, skip
, sizeof(struct ip6_hdr
), (caddr_t
) &ip6n
);
679 * Check that the inner source address is the same as
680 * the proxy address, if available.
682 if ((saidx
->proxy
.sa
.sa_family
== AF_INET6
&&
683 !IN6_IS_ADDR_UNSPECIFIED(&saidx
->proxy
.sin6
.sin6_addr
) &&
684 !IN6_ARE_ADDR_EQUAL(&ip6n
.ip6_src
,
685 &saidx
->proxy
.sin6
.sin6_addr
)) ||
686 (saidx
->proxy
.sa
.sa_family
!= AF_INET6
&&
687 saidx
->proxy
.sa
.sa_family
!= 0)) {
689 DPRINTF(("ipsec_common_input_cb: inner "
690 "source address %s doesn't correspond to "
691 "expected proxy source %s, SA %s/%08lx\n",
692 ip6_sprintf(&ip6n
.ip6_src
),
693 ipsec_address(&saidx
->proxy
),
694 ipsec_address(&saidx
->dst
),
695 (u_long
) ntohl(sav
->spi
)));
697 IPSEC_ISTAT(sproto
, espstat
.esps_pdrops
,
698 ahstat
.ahs_pdrops
, ipcompstat
.ipcomps_pdrops
);
706 * Record what we've done to the packet (under what SA it was
707 * processed). If we've been passed an mtag, it means the packet
708 * was already processed by an ethernet/crypto combo card and
709 * thus has a tag attached with all the right information, but
710 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to
711 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type.
713 if (mt
== NULL
&& sproto
!= IPPROTO_IPCOMP
) {
714 mtag
= m_tag_get(PACKET_TAG_IPSEC_IN_DONE
,
715 sizeof(struct tdb_ident
), M_NOWAIT
);
717 DPRINTF(("ipsec_common_input_cb: failed to "
719 IPSEC_ISTAT(sproto
, espstat
.esps_hdrops
,
720 ahstat
.ahs_hdrops
, ipcompstat
.ipcomps_hdrops
);
725 tdbi
= (struct tdb_ident
*)m_tag_data(mtag
);
726 bcopy(&saidx
->dst
, &tdbi
->dst
, sizeof(union sockaddr_union
));
727 tdbi
->proto
= sproto
;
728 tdbi
->spi
= sav
->spi
;
730 m_tag_prepend(m
, mtag
);
732 mt
->m_tag_id
= PACKET_TAG_IPSEC_IN_DONE
;
733 /* XXX do we need to mark m_flags??? */
736 key_sa_recordxfer(sav
, m
);
738 /* Retrieve new protocol */
739 m_copydata(m
, protoff
, sizeof(u_int8_t
), (caddr_t
) &nxt8
);
742 * See the end of ip6_input for this logic.
743 * IPPROTO_IPV[46] case will be processed just like other ones
747 while (nxt
!= IPPROTO_DONE
) {
748 if (ip6_hdrnestlimit
&& (++nest
> ip6_hdrnestlimit
)) {
749 ip6stat
.ip6s_toomanyhdr
++;
755 * Protection against faulty packet - there should be
756 * more sanity checks in header chain processing.
758 if (m
->m_pkthdr
.len
< skip
) {
759 ip6stat
.ip6s_tooshort
++;
760 in6_ifstat_inc(m
->m_pkthdr
.rcvif
, ifs6_in_truncated
);
765 * Enforce IPsec policy checking if we are seeing last header.
766 * note that we do not visit this with protocols with pcb layer
767 * code - like udp/tcp/raw ip.
769 if ((inet6sw
[ip6_protox
[nxt
]].pr_flags
& PR_LASTHDR
) != 0 &&
770 ipsec6_in_reject(m
, NULL
)) {
774 nxt
= (*inet6sw
[ip6_protox
[nxt
]].pr_input
)(&m
, &skip
, nxt
);