kernel - Change machdep.pmap_dynamic_delete default
[dragonfly.git] / sys / netinet6 / ipsec.c
blobf9aa5c47f3eb52d1d40db0fcec6ceb67114ced8b
1 /* $FreeBSD: src/sys/netinet6/ipsec.c,v 1.3.2.12 2003/05/06 06:46:58 suz Exp $ */
2 /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
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 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
34 * IPsec controller part.
37 #include "opt_inet.h"
38 #include "opt_inet6.h"
39 #include "opt_ipsec.h"
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/domain.h>
46 #include <sys/protosw.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/errno.h>
50 #include <sys/time.h>
51 #include <sys/kernel.h>
52 #include <sys/syslog.h>
53 #include <sys/sysctl.h>
54 #include <sys/proc.h>
55 #include <sys/in_cksum.h>
56 #include <sys/thread2.h>
58 #include <net/if.h>
59 #include <net/route.h>
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_pcb.h>
64 #include <netinet/ip.h>
65 #include <netinet/ip_var.h>
66 #include <netinet/in_var.h>
67 #include <netinet/udp.h>
68 #include <netinet/udp_var.h>
69 #include <netinet/ip_ecn.h>
70 #ifdef INET6
71 #include <netinet6/ip6_ecn.h>
72 #endif
73 #include <netinet/tcp.h>
75 #include <netinet/ip6.h>
76 #ifdef INET6
77 #include <netinet6/ip6_var.h>
78 #endif
79 #ifdef INET6
80 #include <netinet/icmp6.h>
81 #endif
83 #include <netinet6/ipsec.h>
84 #ifdef INET6
85 #include <netinet6/ipsec6.h>
86 #endif
87 #include <netinet6/ah.h>
88 #ifdef INET6
89 #include <netinet6/ah6.h>
90 #endif
91 #ifdef IPSEC_ESP
92 #include <netinet6/esp.h>
93 #ifdef INET6
94 #include <netinet6/esp6.h>
95 #endif
96 #endif
97 #include <netinet6/ipcomp.h>
98 #ifdef INET6
99 #include <netinet6/ipcomp6.h>
100 #endif
101 #include <netproto/key/key.h>
102 #include <netproto/key/keydb.h>
103 #include <netproto/key/key_debug.h>
105 #include <net/net_osdep.h>
107 #ifdef IPSEC_DEBUG
108 int ipsec_debug = 1;
109 #else
110 int ipsec_debug = 0;
111 #endif
113 struct ipsecstat ipsecstat;
114 int ip4_ah_cleartos = 1;
115 int ip4_ah_offsetmask = 0; /* maybe IP_DF? */
116 int ip4_ipsec_dfbit = 0; /* DF bit on encap. 0: clear 1: set 2: copy */
117 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
118 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
119 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
120 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
121 struct secpolicy ip4_def_policy;
122 int ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
123 int ip4_esp_randpad = -1;
125 #ifdef SYSCTL_DECL
126 SYSCTL_DECL(_net_inet_ipsec);
127 #ifdef INET6
128 SYSCTL_DECL(_net_inet6_ipsec6);
129 #endif
130 #endif
132 /* net.inet.ipsec */
133 SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS,
134 stats, CTLFLAG_RD, &ipsecstat, ipsecstat, "");
135 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
136 def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
137 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
138 CTLFLAG_RW, &ip4_esp_trans_deflev, 0, "");
139 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
140 CTLFLAG_RW, &ip4_esp_net_deflev, 0, "");
141 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
142 CTLFLAG_RW, &ip4_ah_trans_deflev, 0, "");
143 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
144 CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
145 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
146 ah_cleartos, CTLFLAG_RW, &ip4_ah_cleartos, 0, "");
147 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
148 ah_offsetmask, CTLFLAG_RW, &ip4_ah_offsetmask, 0, "");
149 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
150 dfbit, CTLFLAG_RW, &ip4_ipsec_dfbit, 0, "");
151 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
152 ecn, CTLFLAG_RW, &ip4_ipsec_ecn, 0, "");
153 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
154 debug, CTLFLAG_RW, &ipsec_debug, 0, "");
155 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
156 esp_randpad, CTLFLAG_RW, &ip4_esp_randpad, 0, "");
158 #ifdef INET6
159 struct ipsecstat ipsec6stat;
160 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
161 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
162 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
163 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
164 struct secpolicy ip6_def_policy;
165 int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */
166 int ip6_esp_randpad = -1;
168 /* net.inet6.ipsec6 */
169 SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS,
170 stats, CTLFLAG_RD, &ipsec6stat, ipsecstat, "");
171 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
172 def_policy, CTLFLAG_RW, &ip6_def_policy.policy, 0, "");
173 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
174 CTLFLAG_RW, &ip6_esp_trans_deflev, 0, "");
175 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
176 CTLFLAG_RW, &ip6_esp_net_deflev, 0, "");
177 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
178 CTLFLAG_RW, &ip6_ah_trans_deflev, 0, "");
179 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
180 CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
181 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
182 ecn, CTLFLAG_RW, &ip6_ipsec_ecn, 0, "");
183 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
184 debug, CTLFLAG_RW, &ipsec_debug, 0, "");
185 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
186 esp_randpad, CTLFLAG_RW, &ip6_esp_randpad, 0, "");
187 #endif /* INET6 */
189 static int ipsec_setspidx_mbuf
190 (struct secpolicyindex *, u_int, u_int, struct mbuf *, int);
191 static int ipsec4_setspidx_inpcb (struct mbuf *, struct inpcb *);
192 #ifdef INET6
193 static int ipsec6_setspidx_in6pcb (struct mbuf *, struct in6pcb *);
194 #endif
195 static int ipsec_setspidx (struct mbuf *, struct secpolicyindex *, int);
196 static void ipsec4_get_ulp (struct mbuf *, struct secpolicyindex *, int);
197 static int ipsec4_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
198 #ifdef INET6
199 static void ipsec6_get_ulp (struct mbuf *, struct secpolicyindex *, int);
200 static int ipsec6_setspidx_ipaddr (struct mbuf *, struct secpolicyindex *);
201 #endif
202 static struct inpcbpolicy *ipsec_newpcbpolicy (void);
203 static void ipsec_delpcbpolicy (struct inpcbpolicy *);
204 static struct secpolicy *ipsec_deepcopy_policy (struct secpolicy *);
205 static int ipsec_set_policy (struct secpolicy **, int, caddr_t, size_t, int);
206 static int ipsec_get_policy (struct secpolicy *, struct mbuf **);
207 static void vshiftl (unsigned char *, int, int);
208 static int ipsec_in_reject (struct secpolicy *, struct mbuf *);
209 static size_t ipsec_hdrsiz (struct secpolicy *);
210 #ifdef INET
211 static struct mbuf *ipsec4_splithdr (struct mbuf *);
212 #endif
213 #ifdef INET6
214 static struct mbuf *ipsec6_splithdr (struct mbuf *);
215 #endif
216 #ifdef INET
217 static int ipsec4_encapsulate (struct mbuf *, struct secasvar *);
218 #endif
219 #ifdef INET6
220 static int ipsec6_encapsulate (struct mbuf *, struct secasvar *);
221 #endif
224 * For OUTBOUND packet having a socket. Searching SPD for packet,
225 * and return a pointer to SP.
226 * OUT: NULL: no apropreate SP found, the following value is set to error.
227 * 0 : bypass
228 * EACCES : discard packet.
229 * ENOENT : ipsec_acquire() in progress, maybe.
230 * others : error occured.
231 * others: a pointer to SP
233 * NOTE: IPv6 mapped adddress concern is implemented here.
235 struct secpolicy *
236 ipsec4_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so, int *error)
238 struct inpcbpolicy *pcbsp = NULL;
239 struct secpolicy *currsp = NULL; /* policy on socket */
240 struct secpolicy *kernsp = NULL; /* policy on kernel */
242 /* sanity check */
243 if (m == NULL || so == NULL || error == NULL)
244 panic("ipsec4_getpolicybysock: NULL pointer was passed.");
246 switch (so->so_proto->pr_domain->dom_family) {
247 case AF_INET:
248 /* set spidx in pcb */
249 *error = ipsec4_setspidx_inpcb(m, so->so_pcb);
250 break;
251 #ifdef INET6
252 case AF_INET6:
253 /* set spidx in pcb */
254 *error = ipsec6_setspidx_in6pcb(m, so->so_pcb);
255 break;
256 #endif
257 default:
258 panic("ipsec4_getpolicybysock: unsupported address family");
260 if (*error)
261 return NULL;
262 switch (so->so_proto->pr_domain->dom_family) {
263 case AF_INET:
264 pcbsp = sotoinpcb(so)->inp_sp;
265 break;
266 #ifdef INET6
267 case AF_INET6:
268 pcbsp = sotoin6pcb(so)->in6p_sp;
269 break;
270 #endif
273 /* sanity check */
274 if (pcbsp == NULL)
275 panic("ipsec4_getpolicybysock: pcbsp is NULL.");
277 switch (dir) {
278 case IPSEC_DIR_INBOUND:
279 currsp = pcbsp->sp_in;
280 break;
281 case IPSEC_DIR_OUTBOUND:
282 currsp = pcbsp->sp_out;
283 break;
284 default:
285 panic("ipsec4_getpolicybysock: illegal direction.");
288 /* sanity check */
289 if (currsp == NULL)
290 panic("ipsec4_getpolicybysock: currsp is NULL.");
292 lwkt_gettoken(&key_token);
294 /* when privilieged socket */
295 if (pcbsp->priv) {
296 switch (currsp->policy) {
297 case IPSEC_POLICY_BYPASS:
298 currsp->refcnt++;
299 *error = 0;
300 lwkt_reltoken(&key_token);
301 return currsp;
303 case IPSEC_POLICY_ENTRUST:
304 /* look for a policy in SPD */
305 kernsp = key_allocsp(&currsp->spidx, dir);
307 /* SP found */
308 if (kernsp != NULL) {
309 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
310 kprintf("DP ipsec4_getpolicybysock called "
311 "to allocate SP:%p\n", kernsp));
312 *error = 0;
313 lwkt_reltoken(&key_token);
314 return kernsp;
317 /* no SP found */
318 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
319 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
320 ipseclog((LOG_INFO,
321 "fixed system default policy: %d->%d\n",
322 ip4_def_policy.policy, IPSEC_POLICY_NONE));
323 ip4_def_policy.policy = IPSEC_POLICY_NONE;
325 ip4_def_policy.refcnt++;
326 *error = 0;
327 lwkt_reltoken(&key_token);
328 return &ip4_def_policy;
330 case IPSEC_POLICY_IPSEC:
331 currsp->refcnt++;
332 *error = 0;
333 lwkt_reltoken(&key_token);
334 return currsp;
336 default:
337 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
338 "Invalid policy for PCB %d\n", currsp->policy));
339 *error = EINVAL;
340 lwkt_reltoken(&key_token);
341 return NULL;
343 /* NOTREACHED */
346 /* when non-privilieged socket */
347 /* look for a policy in SPD */
348 kernsp = key_allocsp(&currsp->spidx, dir);
350 /* SP found */
351 if (kernsp != NULL) {
352 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
353 kprintf("DP ipsec4_getpolicybysock called "
354 "to allocate SP:%p\n", kernsp));
355 *error = 0;
356 lwkt_reltoken(&key_token);
357 return kernsp;
360 /* no SP found */
361 switch (currsp->policy) {
362 case IPSEC_POLICY_BYPASS:
363 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
364 "Illegal policy for non-priviliged defined %d\n",
365 currsp->policy));
366 *error = EINVAL;
367 lwkt_reltoken(&key_token);
368 return NULL;
370 case IPSEC_POLICY_ENTRUST:
371 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD
372 && ip4_def_policy.policy != IPSEC_POLICY_NONE) {
373 ipseclog((LOG_INFO,
374 "fixed system default policy: %d->%d\n",
375 ip4_def_policy.policy, IPSEC_POLICY_NONE));
376 ip4_def_policy.policy = IPSEC_POLICY_NONE;
378 ip4_def_policy.refcnt++;
379 *error = 0;
380 lwkt_reltoken(&key_token);
381 return &ip4_def_policy;
383 case IPSEC_POLICY_IPSEC:
384 currsp->refcnt++;
385 *error = 0;
386 lwkt_reltoken(&key_token);
387 return currsp;
389 default:
390 ipseclog((LOG_ERR, "ipsec4_getpolicybysock: "
391 "Invalid policy for PCB %d\n", currsp->policy));
392 *error = EINVAL;
393 lwkt_reltoken(&key_token);
394 return NULL;
396 /* NOTREACHED */
400 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
401 * and return a pointer to SP.
402 * OUT: positive: a pointer to the entry for security policy leaf matched.
403 * NULL: no apropreate SP found, the following value is set to error.
404 * 0 : bypass
405 * EACCES : discard packet.
406 * ENOENT : ipsec_acquire() in progress, maybe.
407 * others : error occured.
409 struct secpolicy *
410 ipsec4_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
412 struct secpolicy *sp = NULL;
413 struct secpolicyindex spidx;
415 /* sanity check */
416 if (m == NULL || error == NULL)
417 panic("ipsec4_getpolicybyaddr: NULL pointer was passed.");
419 bzero(&spidx, sizeof(spidx));
421 /* make an index to look for a policy */
422 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET, m,
423 (flag & IP_FORWARDING) ? 0 : 1);
425 if (*error != 0)
426 return NULL;
428 lwkt_gettoken(&key_token);
429 sp = key_allocsp(&spidx, dir);
431 /* SP found */
432 if (sp != NULL) {
433 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
434 kprintf("DP ipsec4_getpolicybyaddr called "
435 "to allocate SP:%p\n", sp));
436 *error = 0;
437 lwkt_reltoken(&key_token);
438 return sp;
441 /* no SP found */
442 if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD &&
443 ip4_def_policy.policy != IPSEC_POLICY_NONE) {
444 ipseclog((LOG_INFO, "fixed system default policy:%d->%d\n",
445 ip4_def_policy.policy, IPSEC_POLICY_NONE));
446 ip4_def_policy.policy = IPSEC_POLICY_NONE;
448 ip4_def_policy.refcnt++;
449 *error = 0;
450 lwkt_reltoken(&key_token);
451 return &ip4_def_policy;
454 #ifdef INET6
456 * For OUTBOUND packet having a socket. Searching SPD for packet,
457 * and return a pointer to SP.
458 * OUT: NULL: no apropreate SP found, the following value is set to error.
459 * 0 : bypass
460 * EACCES : discard packet.
461 * ENOENT : ipsec_acquire() in progress, maybe.
462 * others : error occured.
463 * others: a pointer to SP
465 struct secpolicy *
466 ipsec6_getpolicybysock(struct mbuf *m, u_int dir, struct socket *so, int *error)
468 struct inpcbpolicy *pcbsp = NULL;
469 struct secpolicy *currsp = NULL; /* policy on socket */
470 struct secpolicy *kernsp = NULL; /* policy on kernel */
472 /* sanity check */
473 if (m == NULL || so == NULL || error == NULL)
474 panic("ipsec6_getpolicybysock: NULL pointer was passed.");
476 #ifdef DIAGNOSTIC
477 if (so->so_proto->pr_domain->dom_family != AF_INET6)
478 panic("ipsec6_getpolicybysock: socket domain != inet6");
479 #endif
481 lwkt_gettoken(&key_token);
483 /* set spidx in pcb */
484 ipsec6_setspidx_in6pcb(m, so->so_pcb);
485 pcbsp = sotoin6pcb(so)->in6p_sp;
487 /* sanity check */
488 if (pcbsp == NULL)
489 panic("ipsec6_getpolicybysock: pcbsp is NULL.");
491 switch (dir) {
492 case IPSEC_DIR_INBOUND:
493 currsp = pcbsp->sp_in;
494 break;
495 case IPSEC_DIR_OUTBOUND:
496 currsp = pcbsp->sp_out;
497 break;
498 default:
499 panic("ipsec6_getpolicybysock: illegal direction.");
502 /* sanity check */
503 if (currsp == NULL)
504 panic("ipsec6_getpolicybysock: currsp is NULL.");
506 /* when privilieged socket */
507 if (pcbsp->priv) {
508 switch (currsp->policy) {
509 case IPSEC_POLICY_BYPASS:
510 currsp->refcnt++;
511 *error = 0;
512 break;
513 case IPSEC_POLICY_ENTRUST:
514 /* look for a policy in SPD */
515 kernsp = key_allocsp(&currsp->spidx, dir);
517 /* SP found */
518 if (kernsp != NULL) {
519 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
520 kprintf("DP ipsec6_getpolicybysock called "
521 "to allocate SP:%p\n", kernsp));
522 *error = 0;
523 currsp = kernsp;
524 break;
527 /* no SP found */
528 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
529 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
530 ipseclog((LOG_INFO,
531 "fixed system default policy: %d->%d\n",
532 ip6_def_policy.policy, IPSEC_POLICY_NONE));
533 ip6_def_policy.policy = IPSEC_POLICY_NONE;
535 currsp = &ip6_def_policy;
536 currsp->refcnt++;
537 *error = 0;
538 break;
539 case IPSEC_POLICY_IPSEC:
540 currsp->refcnt++;
541 *error = 0;
542 break;
543 default:
544 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
545 "Invalid policy for PCB %d\n", currsp->policy));
546 *error = EINVAL;
547 lwkt_reltoken(&key_token);
548 currsp = NULL;
549 break;
551 lwkt_reltoken(&key_token);
552 return currsp;
553 /* NOTREACHED */
556 /* when non-privilieged socket */
557 /* look for a policy in SPD */
558 kernsp = key_allocsp(&currsp->spidx, dir);
560 /* SP found */
561 if (kernsp != NULL) {
562 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
563 kprintf("DP ipsec6_getpolicybysock called "
564 "to allocate SP:%p\n", kernsp));
565 *error = 0;
566 lwkt_reltoken(&key_token);
567 return kernsp;
570 /* no SP found */
571 switch (currsp->policy) {
572 case IPSEC_POLICY_BYPASS:
573 ipseclog((LOG_ERR, "ipsec6_getpolicybysock: "
574 "Illegal policy for non-priviliged defined %d\n",
575 currsp->policy));
576 *error = EINVAL;
577 currsp = NULL;
578 break;
579 case IPSEC_POLICY_ENTRUST:
580 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
581 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
582 ipseclog((LOG_INFO,
583 "fixed system default policy: %d->%d\n",
584 ip6_def_policy.policy, IPSEC_POLICY_NONE));
585 ip6_def_policy.policy = IPSEC_POLICY_NONE;
587 currsp = &ip6_def_policy;
588 currsp->refcnt++;
589 *error = 0;
590 break;
591 case IPSEC_POLICY_IPSEC:
592 currsp->refcnt++;
593 *error = 0;
594 break;
595 default:
596 ipseclog((LOG_ERR,
597 "ipsec6_policybysock: Invalid policy for PCB %d\n",
598 currsp->policy));
599 *error = EINVAL;
600 currsp = NULL;
601 break;
603 lwkt_reltoken(&key_token);
604 return currsp;
608 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
609 * and return a pointer to SP.
610 * `flag' means that packet is to be forwarded whether or not.
611 * flag = 1: forwad
612 * OUT: positive: a pointer to the entry for security policy leaf matched.
613 * NULL: no apropreate SP found, the following value is set to error.
614 * 0 : bypass
615 * EACCES : discard packet.
616 * ENOENT : ipsec_acquire() in progress, maybe.
617 * others : error occured.
619 #ifndef IP_FORWARDING
620 #define IP_FORWARDING 1
621 #endif
623 struct secpolicy *
624 ipsec6_getpolicybyaddr(struct mbuf *m, u_int dir, int flag, int *error)
626 struct secpolicy *sp = NULL;
627 struct secpolicyindex spidx;
629 /* sanity check */
630 if (m == NULL || error == NULL)
631 panic("ipsec6_getpolicybyaddr: NULL pointer was passed.");
632 bzero(&spidx, sizeof(spidx));
634 lwkt_gettoken(&key_token);
636 /* make an index to look for a policy */
637 *error = ipsec_setspidx_mbuf(&spidx, dir, AF_INET6, m,
638 (flag & IP_FORWARDING) ? 0 : 1);
639 if (*error != 0) {
640 lwkt_reltoken(&key_token);
641 return NULL;
644 sp = key_allocsp(&spidx, dir);
646 /* SP found */
647 if (sp != NULL) {
648 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
649 kprintf("DP ipsec6_getpolicybyaddr called "
650 "to allocate SP:%p\n", sp));
651 *error = 0;
652 lwkt_reltoken(&key_token);
653 return sp;
656 /* no SP found */
657 if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD
658 && ip6_def_policy.policy != IPSEC_POLICY_NONE) {
659 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
660 ip6_def_policy.policy, IPSEC_POLICY_NONE));
661 ip6_def_policy.policy = IPSEC_POLICY_NONE;
663 sp = &ip6_def_policy;
664 sp->refcnt++;
665 *error = 0;
666 lwkt_reltoken(&key_token);
668 return sp;
670 #endif /* INET6 */
673 * set IP address into spidx from mbuf.
674 * When Forwarding packet and ICMP echo reply, this function is used.
676 * IN: get the followings from mbuf.
677 * protocol family, src, dst, next protocol
678 * OUT:
679 * 0: success.
680 * other: failure, and set errno.
682 static int
683 ipsec_setspidx_mbuf(struct secpolicyindex *spidx, u_int dir, u_int family,
684 struct mbuf *m, int needport)
686 int error;
688 /* sanity check */
689 if (spidx == NULL || m == NULL)
690 panic("ipsec_setspidx_mbuf: NULL pointer was passed.");
692 bzero(spidx, sizeof(*spidx));
694 error = ipsec_setspidx(m, spidx, needport);
695 if (error)
696 goto bad;
697 spidx->dir = dir;
699 return 0;
701 bad:
702 /* XXX initialize */
703 bzero(spidx, sizeof(*spidx));
704 return EINVAL;
707 static int
708 ipsec4_setspidx_inpcb(struct mbuf *m, struct inpcb *pcb)
710 struct secpolicyindex *spidx;
711 int error;
713 /* sanity check */
714 if (pcb == NULL)
715 panic("ipsec4_setspidx_inpcb: no PCB found.");
716 if (pcb->inp_sp == NULL)
717 panic("ipsec4_setspidx_inpcb: no inp_sp found.");
718 if (pcb->inp_sp->sp_out == NULL || pcb->inp_sp->sp_in == NULL)
719 panic("ipsec4_setspidx_inpcb: no sp_in/out found.");
721 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
722 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
724 spidx = &pcb->inp_sp->sp_in->spidx;
725 error = ipsec_setspidx(m, spidx, 1);
726 if (error)
727 goto bad;
728 spidx->dir = IPSEC_DIR_INBOUND;
730 spidx = &pcb->inp_sp->sp_out->spidx;
731 error = ipsec_setspidx(m, spidx, 1);
732 if (error)
733 goto bad;
734 spidx->dir = IPSEC_DIR_OUTBOUND;
736 return 0;
738 bad:
739 bzero(&pcb->inp_sp->sp_in->spidx, sizeof(*spidx));
740 bzero(&pcb->inp_sp->sp_out->spidx, sizeof(*spidx));
741 return error;
744 #ifdef INET6
745 static int
746 ipsec6_setspidx_in6pcb(struct mbuf *m, struct in6pcb *pcb)
748 struct secpolicyindex *spidx;
749 int error;
751 /* sanity check */
752 if (pcb == NULL)
753 panic("ipsec6_setspidx_in6pcb: no PCB found.");
754 if (pcb->in6p_sp == NULL)
755 panic("ipsec6_setspidx_in6pcb: no in6p_sp found.");
756 if (pcb->in6p_sp->sp_out == NULL || pcb->in6p_sp->sp_in == NULL)
757 panic("ipsec6_setspidx_in6pcb: no sp_in/out found.");
759 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
760 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
762 spidx = &pcb->in6p_sp->sp_in->spidx;
763 error = ipsec_setspidx(m, spidx, 1);
764 if (error)
765 goto bad;
766 spidx->dir = IPSEC_DIR_INBOUND;
768 spidx = &pcb->in6p_sp->sp_out->spidx;
769 error = ipsec_setspidx(m, spidx, 1);
770 if (error)
771 goto bad;
772 spidx->dir = IPSEC_DIR_OUTBOUND;
774 return 0;
776 bad:
777 bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
778 bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
779 return error;
781 #endif
784 * configure security policy index (src/dst/proto/sport/dport)
785 * by looking at the content of mbuf.
786 * the caller is responsible for error recovery (like clearing up spidx).
788 static int
789 ipsec_setspidx(struct mbuf *m, struct secpolicyindex *spidx, int needport)
791 struct ip *ip = NULL;
792 struct ip ipbuf;
793 u_int v;
794 struct mbuf *n;
795 int len;
796 int error;
798 if (m == NULL)
799 panic("ipsec_setspidx: m == 0 passed.");
802 * validate m->m_pkthdr.len. we see incorrect length if we
803 * mistakenly call this function with inconsistent mbuf chain
804 * (like 4.4BSD tcp/udp processing). XXX should we panic here?
806 len = 0;
807 for (n = m; n; n = n->m_next)
808 len += n->m_len;
809 if (m->m_pkthdr.len != len) {
810 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
811 kprintf("ipsec_setspidx: "
812 "total of m_len(%d) != pkthdr.len(%d), "
813 "ignored.\n",
814 len, m->m_pkthdr.len));
815 return EINVAL;
818 if (m->m_pkthdr.len < sizeof(struct ip)) {
819 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
820 kprintf("ipsec_setspidx: "
821 "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
822 m->m_pkthdr.len));
823 return EINVAL;
826 if (m->m_len >= sizeof(*ip))
827 ip = mtod(m, struct ip *);
828 else {
829 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
830 ip = &ipbuf;
832 #ifdef _IP_VHL
833 v = _IP_VHL_V(ip->ip_vhl);
834 #else
835 v = ip->ip_v;
836 #endif
837 switch (v) {
838 case 4:
839 error = ipsec4_setspidx_ipaddr(m, spidx);
840 if (error)
841 return error;
842 ipsec4_get_ulp(m, spidx, needport);
843 return 0;
844 #ifdef INET6
845 case 6:
846 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
847 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
848 kprintf("ipsec_setspidx: "
849 "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
850 "ignored.\n", m->m_pkthdr.len));
851 return EINVAL;
853 error = ipsec6_setspidx_ipaddr(m, spidx);
854 if (error)
855 return error;
856 ipsec6_get_ulp(m, spidx, needport);
857 return 0;
858 #endif
859 default:
860 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
861 kprintf("ipsec_setspidx: "
862 "unknown IP version %u, ignored.\n", v));
863 return EINVAL;
867 static void
868 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
870 struct ip ip;
871 struct ip6_ext ip6e;
872 u_int8_t nxt;
873 int off;
874 struct tcphdr th;
875 struct udphdr uh;
877 /* sanity check */
878 if (m == NULL)
879 panic("ipsec4_get_ulp: NULL pointer was passed.");
880 if (m->m_pkthdr.len < sizeof(ip))
881 panic("ipsec4_get_ulp: too short");
883 /* set default */
884 spidx->ul_proto = IPSEC_ULPROTO_ANY;
885 ((struct sockaddr_in *)&spidx->src)->sin_port = IPSEC_PORT_ANY;
886 ((struct sockaddr_in *)&spidx->dst)->sin_port = IPSEC_PORT_ANY;
888 m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
889 /* ip_input() flips it into host endian XXX need more checking */
890 if (ip.ip_off & (IP_MF | IP_OFFMASK))
891 return;
893 nxt = ip.ip_p;
894 #ifdef _IP_VHL
895 off = _IP_VHL_HL(ip->ip_vhl) << 2;
896 #else
897 off = ip.ip_hl << 2;
898 #endif
899 while (off < m->m_pkthdr.len) {
900 switch (nxt) {
901 case IPPROTO_TCP:
902 spidx->ul_proto = nxt;
903 if (!needport)
904 return;
905 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
906 return;
907 m_copydata(m, off, sizeof(th), (caddr_t)&th);
908 ((struct sockaddr_in *)&spidx->src)->sin_port =
909 th.th_sport;
910 ((struct sockaddr_in *)&spidx->dst)->sin_port =
911 th.th_dport;
912 return;
913 case IPPROTO_UDP:
914 spidx->ul_proto = nxt;
915 if (!needport)
916 return;
917 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
918 return;
919 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
920 ((struct sockaddr_in *)&spidx->src)->sin_port =
921 uh.uh_sport;
922 ((struct sockaddr_in *)&spidx->dst)->sin_port =
923 uh.uh_dport;
924 return;
925 case IPPROTO_AH:
926 if (off + sizeof(ip6e) > m->m_pkthdr.len)
927 return;
928 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e);
929 off += (ip6e.ip6e_len + 2) << 2;
930 nxt = ip6e.ip6e_nxt;
931 break;
932 case IPPROTO_ICMP:
933 default:
934 /* XXX intermediate headers??? */
935 spidx->ul_proto = nxt;
936 return;
941 /* assumes that m is sane */
942 static int
943 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
945 struct ip *ip = NULL;
946 struct ip ipbuf;
947 struct sockaddr_in *sin;
949 if (m->m_len >= sizeof(*ip))
950 ip = mtod(m, struct ip *);
951 else {
952 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
953 ip = &ipbuf;
956 sin = (struct sockaddr_in *)&spidx->src;
957 bzero(sin, sizeof(*sin));
958 sin->sin_family = AF_INET;
959 sin->sin_len = sizeof(struct sockaddr_in);
960 bcopy(&ip->ip_src, &sin->sin_addr, sizeof(ip->ip_src));
961 spidx->prefs = sizeof(struct in_addr) << 3;
963 sin = (struct sockaddr_in *)&spidx->dst;
964 bzero(sin, sizeof(*sin));
965 sin->sin_family = AF_INET;
966 sin->sin_len = sizeof(struct sockaddr_in);
967 bcopy(&ip->ip_dst, &sin->sin_addr, sizeof(ip->ip_dst));
968 spidx->prefd = sizeof(struct in_addr) << 3;
969 return 0;
972 #ifdef INET6
973 static void
974 ipsec6_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
976 int off, nxt;
977 struct tcphdr th;
978 struct udphdr uh;
980 /* sanity check */
981 if (m == NULL)
982 panic("ipsec6_get_ulp: NULL pointer was passed.");
984 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
985 kprintf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
987 /* set default */
988 spidx->ul_proto = IPSEC_ULPROTO_ANY;
989 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
990 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
992 nxt = -1;
993 off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
994 if (off < 0 || m->m_pkthdr.len < off)
995 return;
997 switch (nxt) {
998 case IPPROTO_TCP:
999 spidx->ul_proto = nxt;
1000 if (!needport)
1001 break;
1002 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
1003 break;
1004 m_copydata(m, off, sizeof(th), (caddr_t)&th);
1005 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
1006 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
1007 break;
1008 case IPPROTO_UDP:
1009 spidx->ul_proto = nxt;
1010 if (!needport)
1011 break;
1012 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
1013 break;
1014 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
1015 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
1016 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
1017 break;
1018 case IPPROTO_ICMPV6:
1019 default:
1020 /* XXX intermediate headers??? */
1021 spidx->ul_proto = nxt;
1022 break;
1026 /* assumes that m is sane */
1027 static int
1028 ipsec6_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
1030 struct ip6_hdr *ip6 = NULL;
1031 struct ip6_hdr ip6buf;
1032 struct sockaddr_in6 *sin6;
1034 if (m->m_len >= sizeof(*ip6))
1035 ip6 = mtod(m, struct ip6_hdr *);
1036 else {
1037 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
1038 ip6 = &ip6buf;
1041 sin6 = (struct sockaddr_in6 *)&spidx->src;
1042 bzero(sin6, sizeof(*sin6));
1043 sin6->sin6_family = AF_INET6;
1044 sin6->sin6_len = sizeof(struct sockaddr_in6);
1045 bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
1046 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1047 sin6->sin6_addr.s6_addr16[1] = 0;
1048 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
1050 spidx->prefs = sizeof(struct in6_addr) << 3;
1052 sin6 = (struct sockaddr_in6 *)&spidx->dst;
1053 bzero(sin6, sizeof(*sin6));
1054 sin6->sin6_family = AF_INET6;
1055 sin6->sin6_len = sizeof(struct sockaddr_in6);
1056 bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
1057 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1058 sin6->sin6_addr.s6_addr16[1] = 0;
1059 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
1061 spidx->prefd = sizeof(struct in6_addr) << 3;
1063 return 0;
1065 #endif
1067 static struct inpcbpolicy *
1068 ipsec_newpcbpolicy(void)
1070 struct inpcbpolicy *p;
1072 p = (struct inpcbpolicy *)kmalloc(sizeof(*p), M_SECA, M_NOWAIT);
1073 return p;
1076 static void
1077 ipsec_delpcbpolicy(struct inpcbpolicy *p)
1079 kfree(p, M_SECA);
1082 /* initialize policy in PCB */
1084 ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
1086 struct inpcbpolicy *new;
1088 /* sanity check. */
1089 if (so == NULL || pcb_sp == NULL)
1090 panic("ipsec_init_policy: NULL pointer was passed.");
1092 lwkt_gettoken(&key_token);
1094 new = ipsec_newpcbpolicy();
1095 if (new == NULL) {
1096 ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
1097 lwkt_reltoken(&key_token);
1098 return ENOBUFS;
1100 bzero(new, sizeof(*new));
1102 if (so->so_cred != NULL && so->so_cred->cr_uid == 0)
1103 new->priv = 1;
1104 else
1105 new->priv = 0;
1107 if ((new->sp_in = key_newsp()) == NULL) {
1108 ipsec_delpcbpolicy(new);
1109 lwkt_reltoken(&key_token);
1110 return ENOBUFS;
1112 new->sp_in->state = IPSEC_SPSTATE_ALIVE;
1113 new->sp_in->policy = IPSEC_POLICY_ENTRUST;
1115 if ((new->sp_out = key_newsp()) == NULL) {
1116 key_freesp(new->sp_in);
1117 ipsec_delpcbpolicy(new);
1118 lwkt_reltoken(&key_token);
1119 return ENOBUFS;
1121 new->sp_out->state = IPSEC_SPSTATE_ALIVE;
1122 new->sp_out->policy = IPSEC_POLICY_ENTRUST;
1124 *pcb_sp = new;
1125 lwkt_reltoken(&key_token);
1127 return 0;
1130 /* copy old ipsec policy into new */
1132 ipsec_copy_policy(struct inpcbpolicy *old, struct inpcbpolicy *new)
1134 struct secpolicy *sp;
1136 lwkt_gettoken(&key_token);
1137 sp = ipsec_deepcopy_policy(old->sp_in);
1138 if (sp) {
1139 key_freesp(new->sp_in);
1140 new->sp_in = sp;
1141 } else {
1142 lwkt_reltoken(&key_token);
1143 return ENOBUFS;
1146 sp = ipsec_deepcopy_policy(old->sp_out);
1147 if (sp) {
1148 key_freesp(new->sp_out);
1149 new->sp_out = sp;
1150 } else {
1151 lwkt_reltoken(&key_token);
1152 return ENOBUFS;
1155 new->priv = old->priv;
1156 lwkt_reltoken(&key_token);
1158 return 0;
1161 /* deep-copy a policy in PCB */
1162 static struct secpolicy *
1163 ipsec_deepcopy_policy(struct secpolicy *src)
1165 struct ipsecrequest *newchain = NULL;
1166 struct ipsecrequest *p;
1167 struct ipsecrequest **q;
1168 struct ipsecrequest *r;
1169 struct secpolicy *dst;
1171 lwkt_gettoken(&key_token);
1172 dst = key_newsp();
1173 if (src == NULL || dst == NULL) {
1174 lwkt_reltoken(&key_token);
1175 return NULL;
1179 * deep-copy IPsec request chain. This is required since struct
1180 * ipsecrequest is not reference counted.
1182 q = &newchain;
1183 for (p = src->req; p; p = p->next) {
1184 *q = (struct ipsecrequest *)kmalloc(sizeof(struct ipsecrequest),
1185 M_SECA, M_NOWAIT | M_ZERO);
1186 if (*q == NULL)
1187 goto fail;
1188 (*q)->next = NULL;
1190 (*q)->saidx.proto = p->saidx.proto;
1191 (*q)->saidx.mode = p->saidx.mode;
1192 (*q)->level = p->level;
1193 (*q)->saidx.reqid = p->saidx.reqid;
1195 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
1196 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
1198 (*q)->sav = NULL;
1199 (*q)->sp = dst;
1201 q = &((*q)->next);
1204 dst->req = newchain;
1205 dst->state = src->state;
1206 dst->policy = src->policy;
1207 /* do not touch the refcnt fields */
1208 lwkt_reltoken(&key_token);
1210 return dst;
1212 fail:
1213 lwkt_reltoken(&key_token);
1214 for (p = newchain; p; p = r) {
1215 r = p->next;
1216 kfree(p, M_SECA);
1217 p = NULL;
1219 return NULL;
1222 /* set policy and ipsec request if present. */
1223 static int
1224 ipsec_set_policy(struct secpolicy **pcb_sp, int optname, caddr_t request,
1225 size_t len, int priv)
1227 struct sadb_x_policy *xpl;
1228 struct secpolicy *newsp = NULL;
1229 int error;
1231 /* sanity check. */
1232 if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
1233 return EINVAL;
1234 if (len < sizeof(*xpl))
1235 return EINVAL;
1236 xpl = (struct sadb_x_policy *)request;
1238 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1239 kprintf("ipsec_set_policy: passed policy\n");
1240 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1242 /* check policy type */
1243 /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1244 if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD ||
1245 xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1246 return EINVAL;
1248 /* check privileged socket */
1249 if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1250 return EACCES;
1252 /* allocation new SP entry */
1253 if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1254 return error;
1256 newsp->state = IPSEC_SPSTATE_ALIVE;
1258 /* clear old SP and set new SP */
1259 key_freesp(*pcb_sp);
1260 *pcb_sp = newsp;
1261 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1262 kprintf("ipsec_set_policy: new policy\n");
1263 kdebug_secpolicy(newsp));
1265 return 0;
1268 static int
1269 ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp)
1272 /* sanity check. */
1273 if (pcb_sp == NULL || mp == NULL)
1274 return EINVAL;
1276 *mp = key_sp2msg(pcb_sp);
1277 if (!*mp) {
1278 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1279 return ENOBUFS;
1282 KKASSERT((*mp)->m_type == MT_DATA);
1283 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1284 kprintf("ipsec_get_policy:\n");
1285 kdebug_mbuf(*mp));
1287 return 0;
1291 ipsec4_set_policy(struct inpcb *inp, int optname, caddr_t request, size_t len,
1292 int priv)
1294 struct sadb_x_policy *xpl;
1295 struct secpolicy **pcb_sp;
1296 int error;
1298 /* sanity check. */
1299 if (inp == NULL || request == NULL)
1300 return EINVAL;
1301 if (len < sizeof(*xpl))
1302 return EINVAL;
1303 xpl = (struct sadb_x_policy *)request;
1305 lwkt_gettoken(&key_token);
1306 /* select direction */
1307 switch (xpl->sadb_x_policy_dir) {
1308 case IPSEC_DIR_INBOUND:
1309 pcb_sp = &inp->inp_sp->sp_in;
1310 break;
1311 case IPSEC_DIR_OUTBOUND:
1312 pcb_sp = &inp->inp_sp->sp_out;
1313 break;
1314 default:
1315 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1316 xpl->sadb_x_policy_dir));
1317 lwkt_reltoken(&key_token);
1318 return EINVAL;
1320 error = ipsec_set_policy(pcb_sp, optname, request, len, priv);
1321 lwkt_reltoken(&key_token);
1322 return error;
1326 ipsec4_get_policy(struct inpcb *inp, caddr_t request, size_t len,
1327 struct mbuf **mp)
1329 struct sadb_x_policy *xpl;
1330 struct secpolicy *pcb_sp;
1331 int error;
1333 /* sanity check. */
1334 if (inp == NULL || request == NULL || mp == NULL)
1335 return EINVAL;
1336 if (inp->inp_sp == NULL)
1337 panic("policy in PCB is NULL");
1338 if (len < sizeof(*xpl))
1339 return EINVAL;
1340 xpl = (struct sadb_x_policy *)request;
1342 lwkt_gettoken(&key_token);
1344 /* select direction */
1345 switch (xpl->sadb_x_policy_dir) {
1346 case IPSEC_DIR_INBOUND:
1347 pcb_sp = inp->inp_sp->sp_in;
1348 break;
1349 case IPSEC_DIR_OUTBOUND:
1350 pcb_sp = inp->inp_sp->sp_out;
1351 break;
1352 default:
1353 ipseclog((LOG_ERR, "ipsec4_get_policy: invalid direction=%u\n",
1354 xpl->sadb_x_policy_dir));
1355 lwkt_reltoken(&key_token);
1356 return EINVAL;
1358 error = ipsec_get_policy(pcb_sp, mp);
1359 lwkt_reltoken(&key_token);
1360 return error;
1363 /* delete policy in PCB */
1365 ipsec4_delete_pcbpolicy(struct inpcb *inp)
1367 struct inpcbpolicy *isp;
1369 /* sanity check. */
1370 if (inp == NULL)
1371 panic("ipsec4_delete_pcbpolicy: NULL pointer was passed.");
1373 lwkt_gettoken(&key_token);
1375 if ((isp = inp->inp_sp) == NULL) {
1376 lwkt_reltoken(&key_token);
1377 return 0;
1380 if (isp->sp_in != NULL) {
1381 key_freesp(isp->sp_in);
1382 isp->sp_in = NULL;
1385 if (isp->sp_out != NULL) {
1386 key_freesp(isp->sp_out);
1387 isp->sp_out = NULL;
1389 KKASSERT(inp->inp_sp == isp);
1390 inp->inp_sp = NULL;
1391 ipsec_delpcbpolicy(isp);
1392 lwkt_reltoken(&key_token);
1394 return 0;
1397 #ifdef INET6
1399 ipsec6_set_policy(struct in6pcb *in6p, int optname, caddr_t request, size_t len,
1400 int priv)
1402 struct sadb_x_policy *xpl;
1403 struct secpolicy **pcb_sp;
1404 int error;
1406 /* sanity check. */
1407 if (in6p == NULL || request == NULL)
1408 return EINVAL;
1409 if (len < sizeof(*xpl))
1410 return EINVAL;
1411 xpl = (struct sadb_x_policy *)request;
1413 lwkt_gettoken(&key_token);
1415 /* select direction */
1416 switch (xpl->sadb_x_policy_dir) {
1417 case IPSEC_DIR_INBOUND:
1418 pcb_sp = &in6p->in6p_sp->sp_in;
1419 break;
1420 case IPSEC_DIR_OUTBOUND:
1421 pcb_sp = &in6p->in6p_sp->sp_out;
1422 break;
1423 default:
1424 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1425 xpl->sadb_x_policy_dir));
1426 lwkt_reltoken(&key_token);
1427 return EINVAL;
1430 error = ipsec_set_policy(pcb_sp, optname, request, len, priv);
1431 lwkt_reltoken(&key_token);
1432 return error;
1436 ipsec6_get_policy(struct in6pcb *in6p, caddr_t request, size_t len,
1437 struct mbuf **mp)
1439 struct sadb_x_policy *xpl;
1440 struct secpolicy *pcb_sp;
1441 int error;
1443 /* sanity check. */
1444 if (in6p == NULL || request == NULL || mp == NULL)
1445 return EINVAL;
1446 if (in6p->in6p_sp == NULL)
1447 panic("policy in PCB is NULL");
1448 if (len < sizeof(*xpl))
1449 return EINVAL;
1450 xpl = (struct sadb_x_policy *)request;
1452 lwkt_gettoken(&key_token);
1454 /* select direction */
1455 switch (xpl->sadb_x_policy_dir) {
1456 case IPSEC_DIR_INBOUND:
1457 pcb_sp = in6p->in6p_sp->sp_in;
1458 break;
1459 case IPSEC_DIR_OUTBOUND:
1460 pcb_sp = in6p->in6p_sp->sp_out;
1461 break;
1462 default:
1463 ipseclog((LOG_ERR, "ipsec6_get_policy: invalid direction=%u\n",
1464 xpl->sadb_x_policy_dir));
1465 lwkt_reltoken(&key_token);
1466 return EINVAL;
1469 error = ipsec_get_policy(pcb_sp, mp);
1470 lwkt_reltoken(&key_token);
1471 return error;
1475 ipsec6_delete_pcbpolicy(struct in6pcb *in6p)
1477 struct inpcbpolicy *isp;
1479 /* sanity check. */
1480 if (in6p == NULL)
1481 panic("ipsec6_delete_pcbpolicy: NULL pointer was passed.");
1483 lwkt_gettoken(&key_token);
1485 if ((isp = in6p->in6p_sp) == NULL) {
1486 lwkt_reltoken(&key_token);
1487 return 0;
1490 if (isp->sp_in != NULL) {
1491 key_freesp(isp->sp_in);
1492 isp->sp_in = NULL;
1495 if (isp->sp_out != NULL) {
1496 key_freesp(isp->sp_out);
1497 isp->sp_out = NULL;
1499 KKASSERT(in6p->in6p_sp == isp);
1500 in6p->in6p_sp = NULL;
1501 ipsec_delpcbpolicy(isp);
1502 lwkt_reltoken(&key_token);
1504 return 0;
1506 #endif
1509 * return current level.
1510 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1512 u_int
1513 ipsec_get_reqlevel(struct ipsecrequest *isr)
1515 u_int level = 0;
1516 u_int esp_trans_deflev, esp_net_deflev, ah_trans_deflev, ah_net_deflev;
1518 /* sanity check */
1519 if (isr == NULL || isr->sp == NULL)
1520 panic("ipsec_get_reqlevel: NULL pointer is passed.");
1521 if (((struct sockaddr *)&isr->sp->spidx.src)->sa_family
1522 != ((struct sockaddr *)&isr->sp->spidx.dst)->sa_family)
1523 panic("ipsec_get_reqlevel: family mismatched.");
1525 /* XXX note that we have ipseclog() expanded here - code sync issue */
1526 #define IPSEC_CHECK_DEFAULT(lev) \
1527 (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE \
1528 && (lev) != IPSEC_LEVEL_UNIQUE) \
1529 ? (ipsec_debug \
1530 ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1531 (lev), IPSEC_LEVEL_REQUIRE) \
1532 : 0), \
1533 (lev) = IPSEC_LEVEL_REQUIRE, \
1534 (lev) \
1535 : (lev))
1537 /* set default level */
1538 switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1539 #ifdef INET
1540 case AF_INET:
1541 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1542 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1543 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1544 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1545 break;
1546 #endif
1547 #ifdef INET6
1548 case AF_INET6:
1549 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1550 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1551 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1552 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1553 break;
1554 #endif /* INET6 */
1555 default:
1556 panic("key_get_reqlevel: Unknown family. %d",
1557 ((struct sockaddr *)&isr->sp->spidx.src)->sa_family);
1560 #undef IPSEC_CHECK_DEFAULT
1562 /* set level */
1563 switch (isr->level) {
1564 case IPSEC_LEVEL_DEFAULT:
1565 switch (isr->saidx.proto) {
1566 case IPPROTO_ESP:
1567 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1568 level = esp_net_deflev;
1569 else
1570 level = esp_trans_deflev;
1571 break;
1572 case IPPROTO_AH:
1573 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1574 level = ah_net_deflev;
1575 else
1576 level = ah_trans_deflev;
1577 case IPPROTO_IPCOMP:
1579 * we don't really care, as IPcomp document says that
1580 * we shouldn't compress small packets
1582 level = IPSEC_LEVEL_USE;
1583 break;
1584 default:
1585 panic("ipsec_get_reqlevel: "
1586 "Illegal protocol defined %u",
1587 isr->saidx.proto);
1589 break;
1591 case IPSEC_LEVEL_USE:
1592 case IPSEC_LEVEL_REQUIRE:
1593 level = isr->level;
1594 break;
1595 case IPSEC_LEVEL_UNIQUE:
1596 level = IPSEC_LEVEL_REQUIRE;
1597 break;
1599 default:
1600 panic("ipsec_get_reqlevel: Illegal IPsec level %u",
1601 isr->level);
1604 return level;
1608 * Check AH/ESP integrity.
1609 * OUT:
1610 * 0: valid
1611 * 1: invalid
1613 static int
1614 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1616 struct ipsecrequest *isr;
1617 u_int level;
1618 int need_auth, need_conf, need_icv;
1620 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1621 kprintf("ipsec_in_reject: using SP\n");
1622 kdebug_secpolicy(sp));
1624 /* check policy */
1625 switch (sp->policy) {
1626 case IPSEC_POLICY_DISCARD:
1627 return 1;
1628 case IPSEC_POLICY_BYPASS:
1629 case IPSEC_POLICY_NONE:
1630 return 0;
1632 case IPSEC_POLICY_IPSEC:
1633 break;
1635 case IPSEC_POLICY_ENTRUST:
1636 default:
1637 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
1640 need_auth = 0;
1641 need_conf = 0;
1642 need_icv = 0;
1644 /* XXX should compare policy against ipsec header history */
1646 for (isr = sp->req; isr != NULL; isr = isr->next) {
1647 /* get current level */
1648 level = ipsec_get_reqlevel(isr);
1650 switch (isr->saidx.proto) {
1651 case IPPROTO_ESP:
1652 if (level == IPSEC_LEVEL_REQUIRE) {
1653 need_conf++;
1655 if (isr->sav != NULL
1656 && isr->sav->flags == SADB_X_EXT_NONE
1657 && isr->sav->alg_auth != SADB_AALG_NONE)
1658 need_icv++;
1660 break;
1661 case IPPROTO_AH:
1662 if (level == IPSEC_LEVEL_REQUIRE) {
1663 need_auth++;
1664 need_icv++;
1666 break;
1667 case IPPROTO_IPCOMP:
1669 * we don't really care, as IPcomp document says that
1670 * we shouldn't compress small packets, IPComp policy
1671 * should always be treated as being in "use" level.
1673 break;
1677 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1678 kprintf("ipsec_in_reject: auth:%d conf:%d icv:%d m_flags:%x\n",
1679 need_auth, need_conf, need_icv, m->m_flags));
1681 if ((need_conf && !(m->m_flags & M_DECRYPTED))
1682 || (!need_auth && need_icv && !(m->m_flags & M_AUTHIPDGM))
1683 || (need_auth && !(m->m_flags & M_AUTHIPHDR)))
1684 return 1;
1686 return 0;
1690 * Check AH/ESP integrity.
1691 * This function is called from tcp_input(), udp_input(),
1692 * and {ah,esp}4_input for tunnel mode
1695 ipsec4_in_reject_so(struct mbuf *m, struct socket *so)
1697 struct secpolicy *sp = NULL;
1698 int error;
1699 int result;
1701 /* sanity check */
1702 if (m == NULL)
1703 return 0; /* XXX should be panic ? */
1705 /* get SP for this packet.
1706 * When we are called from ip_forward(), we call
1707 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1709 lwkt_gettoken(&key_token);
1710 if (so == NULL) {
1711 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
1712 IP_FORWARDING, &error);
1713 } else {
1714 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1717 /* XXX should be panic ? -> No, there may be error. */
1718 if (sp == NULL) {
1719 lwkt_reltoken(&key_token);
1720 return 0;
1723 result = ipsec_in_reject(sp, m);
1724 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1725 kprintf("DP ipsec4_in_reject_so call free SP:%p\n", sp));
1726 key_freesp(sp);
1727 lwkt_reltoken(&key_token);
1729 return result;
1733 ipsec4_in_reject(struct mbuf *m, struct inpcb *inp)
1735 if (inp == NULL)
1736 return ipsec4_in_reject_so(m, NULL);
1737 if (inp->inp_socket)
1738 return ipsec4_in_reject_so(m, inp->inp_socket);
1739 else
1740 panic("ipsec4_in_reject: invalid inpcb/socket");
1743 #ifdef INET6
1745 * Check AH/ESP integrity.
1746 * This function is called from tcp6_input(), udp6_input(),
1747 * and {ah,esp}6_input for tunnel mode
1750 ipsec6_in_reject_so(struct mbuf *m, struct socket *so)
1752 struct secpolicy *sp = NULL;
1753 int error;
1754 int result;
1756 /* sanity check */
1757 if (m == NULL)
1758 return 0; /* XXX should be panic ? */
1760 /* get SP for this packet.
1761 * When we are called from ip_forward(), we call
1762 * ipsec6_getpolicybyaddr() with IP_FORWARDING flag.
1764 lwkt_gettoken(&key_token);
1765 if (so == NULL) {
1766 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND,
1767 IP_FORWARDING, &error);
1768 } else {
1769 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error);
1772 if (sp == NULL) {
1773 lwkt_reltoken(&key_token);
1774 return 0; /* XXX should be panic ? */
1777 result = ipsec_in_reject(sp, m);
1778 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1779 kprintf("DP ipsec6_in_reject_so call free SP:%p\n", sp));
1780 key_freesp(sp);
1781 lwkt_reltoken(&key_token);
1783 return result;
1787 ipsec6_in_reject(struct mbuf *m, struct in6pcb *in6p)
1789 if (in6p == NULL)
1790 return ipsec6_in_reject_so(m, NULL);
1791 if (in6p->in6p_socket)
1792 return ipsec6_in_reject_so(m, in6p->in6p_socket);
1793 else
1794 panic("ipsec6_in_reject: invalid in6p/socket");
1796 #endif
1799 * compute the byte size to be occupied by IPsec header.
1800 * in case it is tunneled, it includes the size of outer IP header.
1801 * NOTE: SP passed is free in this function.
1803 static size_t
1804 ipsec_hdrsiz(struct secpolicy *sp)
1806 struct ipsecrequest *isr;
1807 size_t siz, clen;
1809 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1810 kprintf("ipsec_hdrsiz: using SP\n");
1811 kdebug_secpolicy(sp));
1813 /* check policy */
1814 switch (sp->policy) {
1815 case IPSEC_POLICY_DISCARD:
1816 case IPSEC_POLICY_BYPASS:
1817 case IPSEC_POLICY_NONE:
1818 return 0;
1820 case IPSEC_POLICY_IPSEC:
1821 break;
1823 case IPSEC_POLICY_ENTRUST:
1824 default:
1825 panic("ipsec_hdrsiz: Invalid policy found. %d", sp->policy);
1828 siz = 0;
1830 for (isr = sp->req; isr != NULL; isr = isr->next) {
1832 clen = 0;
1834 switch (isr->saidx.proto) {
1835 case IPPROTO_ESP:
1836 #ifdef IPSEC_ESP
1837 clen = esp_hdrsiz(isr);
1838 #else
1839 clen = 0; /* XXX */
1840 #endif
1841 break;
1842 case IPPROTO_AH:
1843 clen = ah_hdrsiz(isr);
1844 break;
1845 case IPPROTO_IPCOMP:
1846 clen = sizeof(struct ipcomp);
1847 break;
1850 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1851 switch (((struct sockaddr *)&isr->saidx.dst)->sa_family) {
1852 case AF_INET:
1853 clen += sizeof(struct ip);
1854 break;
1855 #ifdef INET6
1856 case AF_INET6:
1857 clen += sizeof(struct ip6_hdr);
1858 break;
1859 #endif
1860 default:
1861 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
1862 "unknown AF %d in IPsec tunnel SA\n",
1863 ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1864 break;
1867 siz += clen;
1870 return siz;
1873 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
1874 size_t
1875 ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp)
1877 struct secpolicy *sp = NULL;
1878 int error;
1879 size_t size;
1881 /* sanity check */
1882 if (m == NULL)
1883 return 0; /* XXX should be panic ? */
1884 if (inp != NULL && inp->inp_socket == NULL)
1885 panic("ipsec4_hdrsize: why is socket NULL but there is PCB.");
1887 /* get SP for this packet.
1888 * When we are called from ip_forward(), we call
1889 * ipsec4_getpolicybyaddr() with IP_FORWARDING flag.
1891 lwkt_gettoken(&key_token);
1892 if (inp == NULL)
1893 sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1894 else
1895 sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error);
1897 if (sp == NULL) {
1898 lwkt_reltoken(&key_token);
1899 return 0; /* XXX should be panic ? */
1902 size = ipsec_hdrsiz(sp);
1903 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1904 kprintf("DP ipsec4_hdrsiz call free SP:%p\n", sp));
1905 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1906 kprintf("ipsec4_hdrsiz: size:%lu.\n", (unsigned long)size));
1907 key_freesp(sp);
1908 lwkt_reltoken(&key_token);
1910 return size;
1913 #ifdef INET6
1914 /* This function is called from ipsec6_hdrsize_tcp(),
1915 * and maybe from ip6_forward.()
1917 size_t
1918 ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct in6pcb *in6p)
1920 struct secpolicy *sp = NULL;
1921 int error;
1922 size_t size;
1924 /* sanity check */
1925 if (m == NULL)
1926 return 0; /* XXX shoud be panic ? */
1927 if (in6p != NULL && in6p->in6p_socket == NULL)
1928 panic("ipsec6_hdrsize: why is socket NULL but there is PCB.");
1930 /* get SP for this packet */
1931 /* XXX Is it right to call with IP_FORWARDING. */
1932 lwkt_gettoken(&key_token);
1933 if (in6p == NULL)
1934 sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1935 else
1936 sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error);
1938 if (sp == NULL) {
1939 lwkt_reltoken(&key_token);
1940 return 0;
1942 size = ipsec_hdrsiz(sp);
1943 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1944 kprintf("DP ipsec6_hdrsiz call free SP:%p\n", sp));
1945 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1946 kprintf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
1947 key_freesp(sp);
1948 lwkt_reltoken(&key_token);
1950 return size;
1952 #endif /* INET6 */
1954 #ifdef INET
1956 * encapsulate for ipsec tunnel.
1957 * ip->ip_src must be fixed later on.
1959 static int
1960 ipsec4_encapsulate(struct mbuf *m, struct secasvar *sav)
1962 struct ip *oip;
1963 struct ip *ip;
1964 size_t hlen;
1965 size_t plen;
1967 /* can't tunnel between different AFs */
1968 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
1969 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
1970 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET) {
1971 m_freem(m);
1972 return EINVAL;
1974 #if 0
1975 /* XXX if the dst is myself, perform nothing. */
1976 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
1977 m_freem(m);
1978 return EINVAL;
1980 #endif
1982 if (m->m_len < sizeof(*ip))
1983 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
1985 ip = mtod(m, struct ip *);
1986 #ifdef _IP_VHL
1987 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
1988 #else
1989 hlen = ip->ip_hl << 2;
1990 #endif
1992 if (m->m_len != hlen)
1993 panic("ipsec4_encapsulate: assumption failed (first mbuf length)");
1995 /* generate header checksum */
1996 ip->ip_sum = 0;
1997 #ifdef _IP_VHL
1998 if (ip->ip_vhl == IP_VHL_BORING)
1999 ip->ip_sum = in_cksum_hdr(ip);
2000 else
2001 ip->ip_sum = in_cksum(m, hlen);
2002 #else
2003 ip->ip_sum = in_cksum(m, hlen);
2004 #endif
2006 plen = m->m_pkthdr.len;
2009 * grow the mbuf to accomodate the new IPv4 header.
2010 * NOTE: IPv4 options will never be copied.
2012 if (M_LEADINGSPACE(m->m_next) < hlen) {
2013 struct mbuf *n;
2014 MGET(n, M_NOWAIT, MT_DATA);
2015 if (!n) {
2016 m_freem(m);
2017 return ENOBUFS;
2019 n->m_len = hlen;
2020 n->m_next = m->m_next;
2021 m->m_next = n;
2022 m->m_pkthdr.len += hlen;
2023 oip = mtod(n, struct ip *);
2024 } else {
2025 m->m_next->m_len += hlen;
2026 m->m_next->m_data -= hlen;
2027 m->m_pkthdr.len += hlen;
2028 oip = mtod(m->m_next, struct ip *);
2030 ip = mtod(m, struct ip *);
2031 bcopy((caddr_t)ip, (caddr_t)oip, hlen);
2032 m->m_len = sizeof(struct ip);
2033 m->m_pkthdr.len -= (hlen - sizeof(struct ip));
2035 /* construct new IPv4 header. see RFC 2401 5.1.2.1 */
2036 /* ECN consideration. */
2037 ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos);
2038 #ifdef _IP_VHL
2039 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2);
2040 #else
2041 ip->ip_hl = sizeof(struct ip) >> 2;
2042 #endif
2043 ip->ip_off &= htons(~IP_OFFMASK);
2044 ip->ip_off &= htons(~IP_MF);
2045 switch (ip4_ipsec_dfbit) {
2046 case 0: /* clear DF bit */
2047 ip->ip_off &= htons(~IP_DF);
2048 break;
2049 case 1: /* set DF bit */
2050 ip->ip_off |= htons(IP_DF);
2051 break;
2052 default: /* copy DF bit */
2053 break;
2055 ip->ip_p = IPPROTO_IPIP;
2056 if (plen + sizeof(struct ip) < IP_MAXPACKET)
2057 ip->ip_len = htons(plen + sizeof(struct ip));
2058 else {
2059 ipseclog((LOG_ERR, "IPv4 ipsec: size exceeds limit: "
2060 "leave ip_len as is (invalid packet)\n"));
2062 #ifdef RANDOM_IP_ID
2063 ip->ip_id = ip_randomid();
2064 #else
2065 ip->ip_id = htons(ip_id++);
2066 #endif
2067 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr,
2068 &ip->ip_src, sizeof(ip->ip_src));
2069 bcopy(&((struct sockaddr_in *)&sav->sah->saidx.dst)->sin_addr,
2070 &ip->ip_dst, sizeof(ip->ip_dst));
2071 ip->ip_ttl = IPDEFTTL;
2073 /* XXX Should ip_src be updated later ? */
2075 return 0;
2077 #endif /* INET */
2079 #ifdef INET6
2080 static int
2081 ipsec6_encapsulate(struct mbuf *m, struct secasvar *sav)
2083 struct ip6_hdr *oip6;
2084 struct ip6_hdr *ip6;
2085 size_t plen;
2087 /* can't tunnel between different AFs */
2088 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2089 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family
2090 || ((struct sockaddr *)&sav->sah->saidx.src)->sa_family != AF_INET6) {
2091 m_freem(m);
2092 return EINVAL;
2094 #if 0
2095 /* XXX if the dst is myself, perform nothing. */
2096 if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) {
2097 m_freem(m);
2098 return EINVAL;
2100 #endif
2102 plen = m->m_pkthdr.len;
2105 * grow the mbuf to accomodate the new IPv6 header.
2107 if (m->m_len != sizeof(struct ip6_hdr))
2108 panic("ipsec6_encapsulate: assumption failed (first mbuf length)");
2109 if (M_LEADINGSPACE(m->m_next) < sizeof(struct ip6_hdr)) {
2110 struct mbuf *n;
2111 MGET(n, M_NOWAIT, MT_DATA);
2112 if (!n) {
2113 m_freem(m);
2114 return ENOBUFS;
2116 n->m_len = sizeof(struct ip6_hdr);
2117 n->m_next = m->m_next;
2118 m->m_next = n;
2119 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2120 oip6 = mtod(n, struct ip6_hdr *);
2121 } else {
2122 m->m_next->m_len += sizeof(struct ip6_hdr);
2123 m->m_next->m_data -= sizeof(struct ip6_hdr);
2124 m->m_pkthdr.len += sizeof(struct ip6_hdr);
2125 oip6 = mtod(m->m_next, struct ip6_hdr *);
2127 ip6 = mtod(m, struct ip6_hdr *);
2128 bcopy((caddr_t)ip6, (caddr_t)oip6, sizeof(struct ip6_hdr));
2130 /* XXX: Fake scoped addresses */
2131 in6_clearscope(&oip6->ip6_src);
2132 in6_clearscope(&oip6->ip6_dst);
2134 /* construct new IPv6 header. see RFC 2401 5.1.2.2 */
2135 /* ECN consideration. */
2136 ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow);
2137 if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr))
2138 ip6->ip6_plen = htons(plen);
2139 else {
2140 /* ip6->ip6_plen will be updated in ip6_output() */
2142 ip6->ip6_nxt = IPPROTO_IPV6;
2143 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.src)->sin6_addr,
2144 &ip6->ip6_src, sizeof(ip6->ip6_src));
2145 bcopy(&((struct sockaddr_in6 *)&sav->sah->saidx.dst)->sin6_addr,
2146 &ip6->ip6_dst, sizeof(ip6->ip6_dst));
2147 ip6->ip6_hlim = IPV6_DEFHLIM;
2149 /* XXX Should ip6_src be updated later ? */
2151 return 0;
2153 #endif /* INET6 */
2156 * Check the variable replay window.
2157 * ipsec_chkreplay() performs replay check before ICV verification.
2158 * ipsec_updatereplay() updates replay bitmap. This must be called after
2159 * ICV verification (it also performs replay check, which is usually done
2160 * beforehand).
2161 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
2163 * based on RFC 2401.
2165 * XXX need to update for 64bit sequence number - 2401bis
2168 ipsec_chkreplay(u_int32_t seq, struct secasvar *sav)
2170 const struct secreplay *replay;
2171 u_int32_t diff;
2172 int fr;
2173 u_int32_t wsizeb; /* constant: bits of window size */
2174 int frlast; /* constant: last frame */
2176 /* sanity check */
2177 if (sav == NULL)
2178 panic("ipsec_chkreplay: NULL pointer was passed.");
2180 replay = sav->replay;
2182 if (replay->wsize == 0)
2183 return 1; /* no need to check replay. */
2185 /* constant */
2186 frlast = replay->wsize - 1;
2187 wsizeb = replay->wsize << 3;
2189 /* sequence number of 0 is invalid */
2190 if (seq == 0)
2191 return 0;
2193 /* first time is always okay */
2194 if (replay->count == 0)
2195 return 1;
2197 if (seq > replay->lastseq) {
2198 /* larger sequences are okay */
2199 return 1;
2200 } else {
2201 /* seq is equal or less than lastseq. */
2202 diff = replay->lastseq - seq;
2204 /* over range to check, i.e. too old or wrapped */
2205 if (diff >= wsizeb)
2206 return 0;
2208 fr = frlast - diff / 8;
2210 /* this packet already seen ? */
2211 if (replay->bitmap[fr] & (1 << (diff % 8)))
2212 return 0;
2214 /* out of order but good */
2215 return 1;
2220 * check replay counter whether to update or not.
2221 * OUT: 0: OK
2222 * 1: NG
2223 * XXX need to update for 64bit sequence number - 2401bis
2226 ipsec_updatereplay(u_int32_t seq, struct secasvar *sav)
2228 struct secreplay *replay;
2229 u_int32_t diff;
2230 int fr;
2231 u_int32_t wsizeb; /* constant: bits of window size */
2232 int frlast; /* constant: last frame */
2234 /* sanity check */
2235 if (sav == NULL)
2236 panic("ipsec_chkreplay: NULL pointer was passed.");
2238 replay = sav->replay;
2240 if (replay->wsize == 0)
2241 goto ok; /* no need to check replay. */
2243 /* constant */
2244 frlast = replay->wsize - 1;
2245 wsizeb = replay->wsize << 3;
2247 /* sequence number of 0 is invalid */
2248 if (seq == 0)
2249 return 1;
2251 /* first time */
2252 if (replay->count == 0) {
2253 replay->lastseq = seq;
2254 bzero(replay->bitmap, replay->wsize);
2255 replay->bitmap[frlast] = 1;
2256 goto ok;
2259 if (seq > replay->lastseq) {
2260 /* seq is larger than lastseq. */
2261 diff = seq - replay->lastseq;
2263 /* new larger sequence number */
2264 if (diff < wsizeb) {
2265 /* In window */
2266 /* set bit for this packet */
2267 vshiftl(replay->bitmap, diff, replay->wsize);
2268 replay->bitmap[frlast] |= 1;
2269 } else {
2270 /* this packet has a "way larger" */
2271 bzero(replay->bitmap, replay->wsize);
2272 replay->bitmap[frlast] = 1;
2274 replay->lastseq = seq;
2276 /* larger is good */
2277 } else {
2278 /* seq is equal or less than lastseq. */
2279 diff = replay->lastseq - seq;
2281 /* over range to check, i.e. too old or wrapped */
2282 if (diff >= wsizeb)
2283 return 1;
2285 fr = frlast - diff / 8;
2287 /* this packet already seen ? */
2288 if (replay->bitmap[fr] & (1 << (diff % 8)))
2289 return 1;
2291 /* mark as seen */
2292 replay->bitmap[fr] |= (1 << (diff % 8));
2294 /* out of order but good */
2298 if (replay->count == ~0) {
2300 /* set overflow flag */
2301 replay->overflow++;
2303 /* don't increment, no more packets accepted */
2304 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
2305 return 1;
2307 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
2308 replay->overflow, ipsec_logsastr(sav)));
2311 replay->count++;
2313 return 0;
2317 * shift variable length buffer to left.
2318 * IN: bitmap: pointer to the buffer
2319 * nbit: the number of to shift.
2320 * wsize: buffer size (bytes).
2322 static void
2323 vshiftl(unsigned char *bitmap, int nbit, int wsize)
2325 int s, j, i;
2326 unsigned char over;
2328 for (j = 0; j < nbit; j += 8) {
2329 s = (nbit - j < 8) ? (nbit - j): 8;
2330 bitmap[0] <<= s;
2331 for (i = 1; i < wsize; i++) {
2332 over = (bitmap[i] >> (8 - s));
2333 bitmap[i] <<= s;
2334 bitmap[i-1] |= over;
2338 return;
2341 const char *
2342 ipsec4_logpacketstr(struct ip *ip, u_int32_t spi)
2344 static char buf[256];
2345 char *p;
2346 u_int8_t *s, *d;
2348 s = (u_int8_t *)(&ip->ip_src);
2349 d = (u_int8_t *)(&ip->ip_dst);
2351 p = buf;
2352 ksnprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2353 while (p && *p)
2354 p++;
2355 ksnprintf(p, sizeof(buf) - (p - buf), "src=%u.%u.%u.%u",
2356 s[0], s[1], s[2], s[3]);
2357 while (p && *p)
2358 p++;
2359 ksnprintf(p, sizeof(buf) - (p - buf), " dst=%u.%u.%u.%u",
2360 d[0], d[1], d[2], d[3]);
2361 while (p && *p)
2362 p++;
2363 ksnprintf(p, sizeof(buf) - (p - buf), ")");
2365 return buf;
2368 #ifdef INET6
2369 const char *
2370 ipsec6_logpacketstr(struct ip6_hdr *ip6, u_int32_t spi)
2372 static char buf[256];
2373 char *p;
2375 p = buf;
2376 ksnprintf(buf, sizeof(buf), "packet(SPI=%u ", (u_int32_t)ntohl(spi));
2377 while (p && *p)
2378 p++;
2379 ksnprintf(p, sizeof(buf) - (p - buf), "src=%s",
2380 ip6_sprintf(&ip6->ip6_src));
2381 while (p && *p)
2382 p++;
2383 ksnprintf(p, sizeof(buf) - (p - buf), " dst=%s",
2384 ip6_sprintf(&ip6->ip6_dst));
2385 while (p && *p)
2386 p++;
2387 ksnprintf(p, sizeof(buf) - (p - buf), ")");
2389 return buf;
2391 #endif /* INET6 */
2393 const char *
2394 ipsec_logsastr(struct secasvar *sav)
2396 static char buf[256];
2397 char *p;
2398 struct secasindex *saidx = &sav->sah->saidx;
2400 /* validity check */
2401 if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family
2402 != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family)
2403 panic("ipsec_logsastr: family mismatched.");
2405 p = buf;
2406 ksnprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
2407 while (p && *p)
2408 p++;
2409 if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET) {
2410 u_int8_t *s, *d;
2411 s = (u_int8_t *)&((struct sockaddr_in *)&saidx->src)->sin_addr;
2412 d = (u_int8_t *)&((struct sockaddr_in *)&saidx->dst)->sin_addr;
2413 ksnprintf(p, sizeof(buf) - (p - buf),
2414 "src=%d.%d.%d.%d dst=%d.%d.%d.%d",
2415 s[0], s[1], s[2], s[3], d[0], d[1], d[2], d[3]);
2417 #ifdef INET6
2418 else if (((struct sockaddr *)&saidx->src)->sa_family == AF_INET6) {
2419 ksnprintf(p, sizeof(buf) - (p - buf),
2420 "src=%s",
2421 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->src)->sin6_addr));
2422 while (p && *p)
2423 p++;
2424 ksnprintf(p, sizeof(buf) - (p - buf),
2425 " dst=%s",
2426 ip6_sprintf(&((struct sockaddr_in6 *)&saidx->dst)->sin6_addr));
2428 #endif
2429 while (p && *p)
2430 p++;
2431 ksnprintf(p, sizeof(buf) - (p - buf), ")");
2433 return buf;
2436 void
2437 ipsec_dumpmbuf(struct mbuf *m)
2439 int totlen;
2440 int i;
2441 u_char *p;
2443 totlen = 0;
2444 kprintf("---\n");
2445 while (m) {
2446 p = mtod(m, u_char *);
2447 for (i = 0; i < m->m_len; i++) {
2448 kprintf("%02x ", p[i]);
2449 totlen++;
2450 if (totlen % 16 == 0)
2451 kprintf("\n");
2453 m = m->m_next;
2455 if (totlen % 16 != 0)
2456 kprintf("\n");
2457 kprintf("---\n");
2460 #ifdef INET
2462 * IPsec output logic for IPv4.
2465 ipsec4_output(struct ipsec_output_state *state, struct secpolicy *sp, int flags)
2467 struct ip *ip = NULL;
2468 struct ipsecrequest *isr = NULL;
2469 struct secasindex saidx;
2470 int error;
2471 struct sockaddr_in *dst4;
2472 struct sockaddr_in *sin;
2474 if (!state)
2475 panic("state == NULL in ipsec4_output");
2476 if (!state->m)
2477 panic("state->m == NULL in ipsec4_output");
2478 if (!state->ro)
2479 panic("state->ro == NULL in ipsec4_output");
2480 if (!state->dst)
2481 panic("state->dst == NULL in ipsec4_output");
2483 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2484 kprintf("ipsec4_output: applyed SP\n");
2485 kdebug_secpolicy(sp));
2487 for (isr = sp->req; isr != NULL; isr = isr->next) {
2489 #if 0 /* give up to check restriction of transport mode */
2490 /* XXX but should be checked somewhere */
2492 * some of the IPsec operation must be performed only in
2493 * originating case.
2495 if (isr->saidx.mode == IPSEC_MODE_TRANSPORT
2496 && (flags & IP_FORWARDING))
2497 continue;
2498 #endif
2500 /* make SA index for search proper SA */
2501 ip = mtod(state->m, struct ip *);
2502 bcopy(&isr->saidx, &saidx, sizeof(saidx));
2503 saidx.mode = isr->saidx.mode;
2504 saidx.reqid = isr->saidx.reqid;
2505 sin = (struct sockaddr_in *)&saidx.src;
2506 if (sin->sin_len == 0) {
2507 sin->sin_len = sizeof(*sin);
2508 sin->sin_family = AF_INET;
2509 sin->sin_port = IPSEC_PORT_ANY;
2510 bcopy(&ip->ip_src, &sin->sin_addr,
2511 sizeof(sin->sin_addr));
2513 sin = (struct sockaddr_in *)&saidx.dst;
2514 if (sin->sin_len == 0) {
2515 sin->sin_len = sizeof(*sin);
2516 sin->sin_family = AF_INET;
2517 sin->sin_port = IPSEC_PORT_ANY;
2518 bcopy(&ip->ip_dst, &sin->sin_addr,
2519 sizeof(sin->sin_addr));
2522 if ((error = key_checkrequest(isr, &saidx)) != 0) {
2524 * IPsec processing is required, but no SA found.
2525 * I assume that key_acquire() had been called
2526 * to get/establish the SA. Here I discard
2527 * this packet because it is responsibility for
2528 * upper layer to retransmit the packet.
2530 ipsecstat.out_nosa++;
2531 goto bad;
2534 /* validity check */
2535 if (isr->sav == NULL) {
2536 switch (ipsec_get_reqlevel(isr)) {
2537 case IPSEC_LEVEL_USE:
2538 continue;
2539 case IPSEC_LEVEL_REQUIRE:
2540 /* must be not reached here. */
2541 panic("ipsec4_output: no SA found, but required.");
2546 * If there is no valid SA, we give up to process any
2547 * more. In such a case, the SA's status is changed
2548 * from DYING to DEAD after allocating. If a packet
2549 * send to the receiver by dead SA, the receiver can
2550 * not decode a packet because SA has been dead.
2552 if (isr->sav->state != SADB_SASTATE_MATURE
2553 && isr->sav->state != SADB_SASTATE_DYING) {
2554 ipsecstat.out_nosa++;
2555 error = EINVAL;
2556 goto bad;
2560 * There may be the case that SA status will be changed when
2561 * we are refering to one. So calling crit_enter().
2563 crit_enter();
2565 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2567 * build IPsec tunnel.
2569 /* XXX should be processed with other familiy */
2570 if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET) {
2571 ipseclog((LOG_ERR, "ipsec4_output: "
2572 "family mismatched between inner and outer spi=%u\n",
2573 (u_int32_t)ntohl(isr->sav->spi)));
2574 crit_exit();
2575 error = EAFNOSUPPORT;
2576 goto bad;
2579 state->m = ipsec4_splithdr(state->m);
2580 if (!state->m) {
2581 crit_exit();
2582 error = ENOMEM;
2583 goto bad;
2585 error = ipsec4_encapsulate(state->m, isr->sav);
2586 crit_exit();
2587 if (error) {
2588 state->m = NULL;
2589 goto bad;
2591 ip = mtod(state->m, struct ip *);
2593 state->ro = &isr->sav->sah->sa_route;
2594 state->dst = (struct sockaddr *)&state->ro->ro_dst;
2595 dst4 = (struct sockaddr_in *)state->dst;
2596 if (state->ro->ro_rt
2597 && ((state->ro->ro_rt->rt_flags & RTF_UP) == 0
2598 || dst4->sin_addr.s_addr != ip->ip_dst.s_addr)) {
2599 RTFREE(state->ro->ro_rt);
2600 state->ro->ro_rt = NULL;
2602 if (state->ro->ro_rt == NULL) {
2603 dst4->sin_family = AF_INET;
2604 dst4->sin_len = sizeof(*dst4);
2605 dst4->sin_addr = ip->ip_dst;
2606 rtalloc(state->ro);
2608 if (state->ro->ro_rt == NULL) {
2609 ipstat.ips_noroute++;
2610 error = EHOSTUNREACH;
2611 goto bad;
2614 /* adjust state->dst if tunnel endpoint is offlink */
2615 if (state->ro->ro_rt->rt_flags & RTF_GATEWAY) {
2616 state->dst = (struct sockaddr *)state->ro->ro_rt->rt_gateway;
2617 dst4 = (struct sockaddr_in *)state->dst;
2619 } else
2620 crit_exit();
2622 state->m = ipsec4_splithdr(state->m);
2623 if (!state->m) {
2624 error = ENOMEM;
2625 goto bad;
2627 switch (isr->saidx.proto) {
2628 case IPPROTO_ESP:
2629 #ifdef IPSEC_ESP
2630 if ((error = esp4_output(state->m, isr)) != 0) {
2631 state->m = NULL;
2632 goto bad;
2634 break;
2635 #else
2636 m_freem(state->m);
2637 state->m = NULL;
2638 error = EINVAL;
2639 goto bad;
2640 #endif
2641 case IPPROTO_AH:
2642 if ((error = ah4_output(state->m, isr)) != 0) {
2643 state->m = NULL;
2644 goto bad;
2646 break;
2647 case IPPROTO_IPCOMP:
2648 if ((error = ipcomp4_output(state->m, isr)) != 0) {
2649 state->m = NULL;
2650 goto bad;
2652 break;
2653 default:
2654 ipseclog((LOG_ERR,
2655 "ipsec4_output: unknown ipsec protocol %d\n",
2656 isr->saidx.proto));
2657 m_freem(state->m);
2658 state->m = NULL;
2659 error = EINVAL;
2660 goto bad;
2663 if (state->m == NULL) {
2664 error = ENOMEM;
2665 goto bad;
2667 ip = mtod(state->m, struct ip *);
2670 return 0;
2672 bad:
2673 m_freem(state->m);
2674 state->m = NULL;
2675 return error;
2677 #endif
2679 #ifdef INET6
2681 * IPsec output logic for IPv6, transport mode.
2684 ipsec6_output_trans(struct ipsec_output_state *state, u_char *nexthdrp,
2685 struct mbuf *mprev, struct secpolicy *sp, int flags,
2686 boolean_t *tun)
2688 struct ip6_hdr *ip6;
2689 struct ipsecrequest *isr = NULL;
2690 struct secasindex saidx;
2691 int error = 0;
2692 int plen;
2693 struct sockaddr_in6 *sin6;
2695 if (!state)
2696 panic("state == NULL in ipsec6_output_trans");
2697 if (!state->m)
2698 panic("state->m == NULL in ipsec6_output_trans");
2699 if (!nexthdrp)
2700 panic("nexthdrp == NULL in ipsec6_output_trans");
2701 if (!mprev)
2702 panic("mprev == NULL in ipsec6_output_trans");
2703 if (!sp)
2704 panic("sp == NULL in ipsec6_output_trans");
2705 if (!tun)
2706 panic("tun == NULL in ipsec6_output_trans");
2708 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2709 kprintf("ipsec6_output_trans: applyed SP\n");
2710 kdebug_secpolicy(sp));
2712 lwkt_gettoken(&key_token);
2714 *tun = 0;
2715 for (isr = sp->req; isr; isr = isr->next) {
2716 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2717 /* the rest will be handled by ipsec6_output_tunnel() */
2718 break;
2721 /* make SA index for search proper SA */
2722 ip6 = mtod(state->m, struct ip6_hdr *);
2723 bcopy(&isr->saidx, &saidx, sizeof(saidx));
2724 saidx.mode = isr->saidx.mode;
2725 saidx.reqid = isr->saidx.reqid;
2726 sin6 = (struct sockaddr_in6 *)&saidx.src;
2727 if (sin6->sin6_len == 0) {
2728 sin6->sin6_len = sizeof(*sin6);
2729 sin6->sin6_family = AF_INET6;
2730 sin6->sin6_port = IPSEC_PORT_ANY;
2731 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
2732 sizeof(ip6->ip6_src));
2733 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
2734 /* fix scope id for comparing SPD */
2735 sin6->sin6_addr.s6_addr16[1] = 0;
2736 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
2739 sin6 = (struct sockaddr_in6 *)&saidx.dst;
2740 if (sin6->sin6_len == 0) {
2741 sin6->sin6_len = sizeof(*sin6);
2742 sin6->sin6_family = AF_INET6;
2743 sin6->sin6_port = IPSEC_PORT_ANY;
2744 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
2745 sizeof(ip6->ip6_dst));
2746 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
2747 /* fix scope id for comparing SPD */
2748 sin6->sin6_addr.s6_addr16[1] = 0;
2749 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
2753 if (key_checkrequest(isr, &saidx) == ENOENT) {
2755 * IPsec processing is required, but no SA found.
2756 * I assume that key_acquire() had been called
2757 * to get/establish the SA. Here I discard
2758 * this packet because it is responsibility for
2759 * upper layer to retransmit the packet.
2761 ipsec6stat.out_nosa++;
2762 error = ENOENT;
2765 * Notify the fact that the packet is discarded
2766 * to ourselves. I believe this is better than
2767 * just silently discarding. (jinmei@kame.net)
2768 * XXX: should we restrict the error to TCP packets?
2769 * XXX: should we directly notify sockets via
2770 * kpfctlinputs?
2772 icmp6_error(state->m, ICMP6_DST_UNREACH,
2773 ICMP6_DST_UNREACH_ADMIN, 0);
2774 state->m = NULL; /* icmp6_error freed the mbuf */
2775 goto bad;
2778 /* validity check */
2779 if (isr->sav == NULL) {
2780 switch (ipsec_get_reqlevel(isr)) {
2781 case IPSEC_LEVEL_USE:
2782 continue;
2783 case IPSEC_LEVEL_REQUIRE:
2784 /* must be not reached here. */
2785 panic("ipsec6_output_trans: no SA found, but required.");
2790 * If there is no valid SA, we give up to process.
2791 * see same place at ipsec4_output().
2793 if (isr->sav->state != SADB_SASTATE_MATURE
2794 && isr->sav->state != SADB_SASTATE_DYING) {
2795 ipsec6stat.out_nosa++;
2796 error = EINVAL;
2797 goto bad;
2800 switch (isr->saidx.proto) {
2801 case IPPROTO_ESP:
2802 #ifdef IPSEC_ESP
2803 error = esp6_output(state->m, nexthdrp, mprev->m_next, isr);
2804 #else
2805 m_freem(state->m);
2806 error = EINVAL;
2807 #endif
2808 break;
2809 case IPPROTO_AH:
2810 error = ah6_output(state->m, nexthdrp, mprev->m_next, isr);
2811 break;
2812 case IPPROTO_IPCOMP:
2813 error = ipcomp6_output(state->m, nexthdrp, mprev->m_next, isr);
2814 break;
2815 default:
2816 ipseclog((LOG_ERR, "ipsec6_output_trans: "
2817 "unknown ipsec protocol %d\n", isr->saidx.proto));
2818 m_freem(state->m);
2819 ipsec6stat.out_inval++;
2820 error = EINVAL;
2821 break;
2823 if (error) {
2824 state->m = NULL;
2825 goto bad;
2827 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
2828 if (plen > IPV6_MAXPACKET) {
2829 ipseclog((LOG_ERR, "ipsec6_output_trans: "
2830 "IPsec with IPv6 jumbogram is not supported\n"));
2831 ipsec6stat.out_inval++;
2832 error = EINVAL; /* XXX */
2833 goto bad;
2835 ip6 = mtod(state->m, struct ip6_hdr *);
2836 ip6->ip6_plen = htons(plen);
2839 /* if we have more to go, we need a tunnel mode processing */
2840 if (isr != NULL)
2841 *tun = TRUE;
2842 lwkt_reltoken(&key_token);
2843 return 0;
2845 bad:
2846 lwkt_reltoken(&key_token);
2847 m_freem(state->m);
2848 state->m = NULL;
2849 return error;
2853 * IPsec output logic for IPv6, tunnel mode.
2856 ipsec6_output_tunnel(struct ipsec_output_state *state, struct secpolicy *sp,
2857 int flags)
2859 struct ip6_hdr *ip6;
2860 struct ipsecrequest *isr = NULL;
2861 struct secasindex saidx;
2862 int error = 0;
2863 int plen;
2864 struct sockaddr_in6* dst6;
2866 if (!state)
2867 panic("state == NULL in ipsec6_output_tunnel");
2868 if (!state->m)
2869 panic("state->m == NULL in ipsec6_output_tunnel");
2870 if (!sp)
2871 panic("sp == NULL in ipsec6_output_tunnel");
2873 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
2874 kprintf("ipsec6_output_tunnel: applyed SP\n");
2875 kdebug_secpolicy(sp));
2878 * transport mode ipsec (before the 1st tunnel mode) is already
2879 * processed by ipsec6_output_trans().
2881 lwkt_gettoken(&key_token);
2882 for (isr = sp->req; isr; isr = isr->next) {
2883 if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
2884 break;
2887 for (/* already initialized */; isr; isr = isr->next) {
2888 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2889 /* When tunnel mode, SA peers must be specified. */
2890 bcopy(&isr->saidx, &saidx, sizeof(saidx));
2891 } else {
2892 /* make SA index to look for a proper SA */
2893 struct sockaddr_in6 *sin6;
2895 bzero(&saidx, sizeof(saidx));
2896 saidx.proto = isr->saidx.proto;
2897 saidx.mode = isr->saidx.mode;
2898 saidx.reqid = isr->saidx.reqid;
2900 ip6 = mtod(state->m, struct ip6_hdr *);
2901 sin6 = (struct sockaddr_in6 *)&saidx.src;
2902 if (sin6->sin6_len == 0) {
2903 sin6->sin6_len = sizeof(*sin6);
2904 sin6->sin6_family = AF_INET6;
2905 sin6->sin6_port = IPSEC_PORT_ANY;
2906 bcopy(&ip6->ip6_src, &sin6->sin6_addr,
2907 sizeof(ip6->ip6_src));
2908 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
2909 /* fix scope id for comparing SPD */
2910 sin6->sin6_addr.s6_addr16[1] = 0;
2911 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
2914 sin6 = (struct sockaddr_in6 *)&saidx.dst;
2915 if (sin6->sin6_len == 0) {
2916 sin6->sin6_len = sizeof(*sin6);
2917 sin6->sin6_family = AF_INET6;
2918 sin6->sin6_port = IPSEC_PORT_ANY;
2919 bcopy(&ip6->ip6_dst, &sin6->sin6_addr,
2920 sizeof(ip6->ip6_dst));
2921 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
2922 /* fix scope id for comparing SPD */
2923 sin6->sin6_addr.s6_addr16[1] = 0;
2924 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
2929 if (key_checkrequest(isr, &saidx) == ENOENT) {
2931 * IPsec processing is required, but no SA found.
2932 * I assume that key_acquire() had been called
2933 * to get/establish the SA. Here I discard
2934 * this packet because it is responsibility for
2935 * upper layer to retransmit the packet.
2937 ipsec6stat.out_nosa++;
2938 error = ENOENT;
2939 goto bad;
2942 /* validity check */
2943 if (isr->sav == NULL) {
2944 switch (ipsec_get_reqlevel(isr)) {
2945 case IPSEC_LEVEL_USE:
2946 continue;
2947 case IPSEC_LEVEL_REQUIRE:
2948 /* must be not reached here. */
2949 panic("ipsec6_output_tunnel: no SA found, but required.");
2954 * If there is no valid SA, we give up to process.
2955 * see same place at ipsec4_output().
2957 if (isr->sav->state != SADB_SASTATE_MATURE
2958 && isr->sav->state != SADB_SASTATE_DYING) {
2959 ipsec6stat.out_nosa++;
2960 error = EINVAL;
2961 goto bad;
2965 * There may be the case that SA status will be changed when
2966 * we are refering to one. So calling crit_enter().
2968 crit_enter();
2970 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
2972 * build IPsec tunnel.
2974 /* XXX should be processed with other familiy */
2975 if (((struct sockaddr *)&isr->sav->sah->saidx.src)->sa_family != AF_INET6) {
2976 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
2977 "family mismatched between inner and outer, spi=%u\n",
2978 (u_int32_t)ntohl(isr->sav->spi)));
2979 crit_exit();
2980 ipsec6stat.out_inval++;
2981 error = EAFNOSUPPORT;
2982 goto bad;
2985 state->m = ipsec6_splithdr(state->m);
2986 if (!state->m) {
2987 crit_exit();
2988 ipsec6stat.out_nomem++;
2989 error = ENOMEM;
2990 goto bad;
2992 error = ipsec6_encapsulate(state->m, isr->sav);
2993 crit_exit();
2994 if (error) {
2995 state->m = NULL;
2996 goto bad;
2998 ip6 = mtod(state->m, struct ip6_hdr *);
3000 state->ro = &isr->sav->sah->sa_route;
3001 state->dst = (struct sockaddr *)&state->ro->ro_dst;
3002 dst6 = (struct sockaddr_in6 *)state->dst;
3003 if (state->ro->ro_rt &&
3004 ((state->ro->ro_rt->rt_flags & RTF_UP) == 0 ||
3005 !IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ip6->ip6_dst))) {
3006 RTFREE(state->ro->ro_rt);
3007 state->ro->ro_rt = NULL;
3009 if (state->ro->ro_rt == NULL) {
3010 bzero(dst6, sizeof(*dst6));
3011 dst6->sin6_family = AF_INET6;
3012 dst6->sin6_len = sizeof(*dst6);
3013 dst6->sin6_addr = ip6->ip6_dst;
3014 rtalloc(state->ro);
3016 if (state->ro->ro_rt == NULL) {
3017 ip6stat.ip6s_noroute++;
3018 ipsec6stat.out_noroute++;
3019 error = EHOSTUNREACH;
3020 goto bad;
3023 /* adjust state->dst if tunnel endpoint is offlink */
3024 if (state->ro->ro_rt->rt_flags & RTF_GATEWAY) {
3025 state->dst = (struct sockaddr *)state->ro->ro_rt->rt_gateway;
3026 dst6 = (struct sockaddr_in6 *)state->dst;
3028 } else
3029 crit_exit();
3031 state->m = ipsec6_splithdr(state->m);
3032 if (!state->m) {
3033 ipsec6stat.out_nomem++;
3034 error = ENOMEM;
3035 goto bad;
3037 ip6 = mtod(state->m, struct ip6_hdr *);
3038 switch (isr->saidx.proto) {
3039 case IPPROTO_ESP:
3040 #ifdef IPSEC_ESP
3041 error = esp6_output(state->m, &ip6->ip6_nxt,
3042 state->m->m_next, isr);
3043 #else
3044 m_freem(state->m);
3045 error = EINVAL;
3046 #endif
3047 break;
3048 case IPPROTO_AH:
3049 error = ah6_output(state->m, &ip6->ip6_nxt,
3050 state->m->m_next, isr);
3051 break;
3052 case IPPROTO_IPCOMP:
3053 /* XXX code should be here */
3054 /* FALLTHROUGH */
3055 default:
3056 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3057 "unknown ipsec protocol %d\n", isr->saidx.proto));
3058 m_freem(state->m);
3059 ipsec6stat.out_inval++;
3060 error = EINVAL;
3061 break;
3063 if (error) {
3064 state->m = NULL;
3065 goto bad;
3067 plen = state->m->m_pkthdr.len - sizeof(struct ip6_hdr);
3068 if (plen > IPV6_MAXPACKET) {
3069 ipseclog((LOG_ERR, "ipsec6_output_tunnel: "
3070 "IPsec with IPv6 jumbogram is not supported\n"));
3071 ipsec6stat.out_inval++;
3072 error = EINVAL; /* XXX */
3073 goto bad;
3075 ip6 = mtod(state->m, struct ip6_hdr *);
3076 ip6->ip6_plen = htons(plen);
3078 lwkt_reltoken(&key_token);
3080 return 0;
3082 bad:
3083 lwkt_reltoken(&key_token);
3084 m_freem(state->m);
3085 state->m = NULL;
3086 return error;
3088 #endif /* INET6 */
3090 #ifdef INET
3092 * Chop IP header and option off from the payload.
3094 static struct mbuf *
3095 ipsec4_splithdr(struct mbuf *m)
3097 struct mbuf *mh;
3098 struct ip *ip;
3099 int hlen;
3101 if (m->m_len < sizeof(struct ip))
3102 panic("ipsec4_splithdr: first mbuf too short");
3103 ip = mtod(m, struct ip *);
3104 #ifdef _IP_VHL
3105 hlen = _IP_VHL_HL(ip->ip_vhl) << 2;
3106 #else
3107 hlen = ip->ip_hl << 2;
3108 #endif
3109 if (m->m_len > hlen) {
3110 MGETHDR(mh, M_NOWAIT, MT_HEADER);
3111 if (!mh) {
3112 m_freem(m);
3113 return NULL;
3115 M_MOVE_PKTHDR(mh, m);
3116 MH_ALIGN(mh, hlen);
3117 m->m_len -= hlen;
3118 m->m_data += hlen;
3119 mh->m_next = m;
3120 m = mh;
3121 m->m_len = hlen;
3122 bcopy((caddr_t)ip, mtod(m, caddr_t), hlen);
3123 } else if (m->m_len < hlen) {
3124 m = m_pullup(m, hlen);
3125 if (!m)
3126 return NULL;
3128 return m;
3130 #endif
3132 #ifdef INET6
3133 static struct mbuf *
3134 ipsec6_splithdr(struct mbuf *m)
3136 struct mbuf *mh;
3137 struct ip6_hdr *ip6;
3138 int hlen;
3140 if (m->m_len < sizeof(struct ip6_hdr))
3141 panic("ipsec6_splithdr: first mbuf too short");
3142 ip6 = mtod(m, struct ip6_hdr *);
3143 hlen = sizeof(struct ip6_hdr);
3144 if (m->m_len > hlen) {
3145 MGETHDR(mh, M_NOWAIT, MT_HEADER);
3146 if (!mh) {
3147 m_freem(m);
3148 return NULL;
3150 M_MOVE_PKTHDR(mh, m);
3151 MH_ALIGN(mh, hlen);
3152 m->m_len -= hlen;
3153 m->m_data += hlen;
3154 mh->m_next = m;
3155 m = mh;
3156 m->m_len = hlen;
3157 bcopy((caddr_t)ip6, mtod(m, caddr_t), hlen);
3158 } else if (m->m_len < hlen) {
3159 m = m_pullup(m, hlen);
3160 if (!m)
3161 return NULL;
3163 return m;
3165 #endif
3167 /* validate inbound IPsec tunnel packet. */
3169 ipsec4_tunnel_validate(struct mbuf *m, /* no pullup permitted, m->m_len >= ip */
3170 int off, u_int nxt0, struct secasvar *sav)
3172 u_int8_t nxt = nxt0 & 0xff;
3173 struct sockaddr_in *sin;
3174 struct sockaddr_in osrc, odst, isrc, idst;
3175 int hlen;
3176 struct secpolicy *sp;
3177 struct ip *oip;
3179 #ifdef DIAGNOSTIC
3180 if (m->m_len < sizeof(struct ip))
3181 panic("too short mbuf on ipsec4_tunnel_validate");
3182 #endif
3183 if (nxt != IPPROTO_IPV4)
3184 return 0;
3185 if (m->m_pkthdr.len < off + sizeof(struct ip))
3186 return 0;
3187 /* do not decapsulate if the SA is for transport mode only */
3188 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3189 return 0;
3191 oip = mtod(m, struct ip *);
3192 #ifdef _IP_VHL
3193 hlen = _IP_VHL_HL(oip->ip_vhl) << 2;
3194 #else
3195 hlen = oip->ip_hl << 2;
3196 #endif
3197 if (hlen != sizeof(struct ip))
3198 return 0;
3200 /* AF_INET6 should be supported, but at this moment we don't. */
3201 sin = (struct sockaddr_in *)&sav->sah->saidx.dst;
3202 if (sin->sin_family != AF_INET)
3203 return 0;
3204 if (bcmp(&oip->ip_dst, &sin->sin_addr, sizeof(oip->ip_dst)) != 0)
3205 return 0;
3207 /* XXX slow */
3208 bzero(&osrc, sizeof(osrc));
3209 bzero(&odst, sizeof(odst));
3210 bzero(&isrc, sizeof(isrc));
3211 bzero(&idst, sizeof(idst));
3212 osrc.sin_family = odst.sin_family = isrc.sin_family = idst.sin_family =
3213 AF_INET;
3214 osrc.sin_len = odst.sin_len = isrc.sin_len = idst.sin_len =
3215 sizeof(struct sockaddr_in);
3216 osrc.sin_addr = oip->ip_src;
3217 odst.sin_addr = oip->ip_dst;
3218 m_copydata(m, off + offsetof(struct ip, ip_src), sizeof(isrc.sin_addr),
3219 (caddr_t)&isrc.sin_addr);
3220 m_copydata(m, off + offsetof(struct ip, ip_dst), sizeof(idst.sin_addr),
3221 (caddr_t)&idst.sin_addr);
3224 * RFC2401 5.2.1 (b): (assume that we are using tunnel mode)
3225 * - if the inner destination is multicast address, there can be
3226 * multiple permissible inner source address. implementation
3227 * may want to skip verification of inner source address against
3228 * SPD selector.
3229 * - if the inner protocol is ICMP, the packet may be an error report
3230 * from routers on the other side of the VPN cloud (R in the
3231 * following diagram). in this case, we cannot verify inner source
3232 * address against SPD selector.
3233 * me -- gw === gw -- R -- you
3235 * we consider the first bullet to be users responsibility on SPD entry
3236 * configuration (if you need to encrypt multicast traffic, set
3237 * the source range of SPD selector to 0.0.0.0/0, or have explicit
3238 * address ranges for possible senders).
3239 * the second bullet is not taken care of (yet).
3241 * therefore, we do not do anything special about inner source.
3244 lwkt_gettoken(&key_token);
3245 sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
3246 (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
3247 if (sp) {
3248 key_freesp(sp);
3249 lwkt_reltoken(&key_token);
3250 return 1;
3251 } else{
3252 lwkt_reltoken(&key_token);
3253 return 0;
3257 #ifdef INET6
3258 /* validate inbound IPsec tunnel packet. */
3260 ipsec6_tunnel_validate(struct mbuf *m, /* no pullup permitted, m->m_len >= ip */
3261 int off, u_int nxt0, struct secasvar *sav)
3263 u_int8_t nxt = nxt0 & 0xff;
3264 struct sockaddr_in6 *sin6;
3265 struct sockaddr_in6 osrc, odst, isrc, idst;
3266 struct secpolicy *sp;
3267 struct ip6_hdr *oip6;
3269 #ifdef DIAGNOSTIC
3270 if (m->m_len < sizeof(struct ip6_hdr))
3271 panic("too short mbuf on ipsec6_tunnel_validate");
3272 #endif
3273 if (nxt != IPPROTO_IPV6)
3274 return 0;
3275 if (m->m_pkthdr.len < off + sizeof(struct ip6_hdr))
3276 return 0;
3277 /* do not decapsulate if the SA is for transport mode only */
3278 if (sav->sah->saidx.mode == IPSEC_MODE_TRANSPORT)
3279 return 0;
3281 oip6 = mtod(m, struct ip6_hdr *);
3282 /* AF_INET should be supported, but at this moment we don't. */
3283 sin6 = (struct sockaddr_in6 *)&sav->sah->saidx.dst;
3284 if (sin6->sin6_family != AF_INET6)
3285 return 0;
3286 if (!IN6_ARE_ADDR_EQUAL(&oip6->ip6_dst, &sin6->sin6_addr))
3287 return 0;
3289 /* XXX slow */
3290 bzero(&osrc, sizeof(osrc));
3291 bzero(&odst, sizeof(odst));
3292 bzero(&isrc, sizeof(isrc));
3293 bzero(&idst, sizeof(idst));
3294 osrc.sin6_family = odst.sin6_family = isrc.sin6_family =
3295 idst.sin6_family = AF_INET6;
3296 osrc.sin6_len = odst.sin6_len = isrc.sin6_len = idst.sin6_len =
3297 sizeof(struct sockaddr_in6);
3298 osrc.sin6_addr = oip6->ip6_src;
3299 odst.sin6_addr = oip6->ip6_dst;
3300 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_src),
3301 sizeof(isrc.sin6_addr), (caddr_t)&isrc.sin6_addr);
3302 m_copydata(m, off + offsetof(struct ip6_hdr, ip6_dst),
3303 sizeof(idst.sin6_addr), (caddr_t)&idst.sin6_addr);
3306 * regarding to inner source address validation, see a long comment
3307 * in ipsec4_tunnel_validate.
3310 lwkt_gettoken(&key_token);
3311 sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst,
3312 (struct sockaddr *)&isrc, (struct sockaddr *)&idst);
3314 * when there is no suitable inbound policy for the packet of the ipsec
3315 * tunnel mode, the kernel never decapsulate the tunneled packet
3316 * as the ipsec tunnel mode even when the system wide policy is "none".
3317 * then the kernel leaves the generic tunnel module to process this
3318 * packet. if there is no rule of the generic tunnel, the packet
3319 * is rejected and the statistics will be counted up.
3321 if (sp) {
3322 key_freesp(sp);
3323 lwkt_reltoken(&key_token);
3324 return 1;
3325 } else {
3326 lwkt_reltoken(&key_token);
3327 return 0;
3330 #endif
3333 * Make a mbuf chain for encryption.
3334 * If the original mbuf chain contains a mbuf with a cluster,
3335 * allocate a new cluster and copy the data to the new cluster.
3336 * XXX: this hack is inefficient, but is necessary to handle cases
3337 * of TCP retransmission...
3339 struct mbuf *
3340 ipsec_copypkt(struct mbuf *m)
3342 struct mbuf *n, **mpp, *mnew;
3344 for (n = m, mpp = &m; n; n = n->m_next) {
3345 if (n->m_flags & M_EXT) {
3347 * Make a copy only if there is more than one
3348 * references to the cluster.
3349 * XXX: is this approach effective?
3351 if (m_sharecount(n) > 1) {
3352 int remain, copied;
3353 struct mbuf *mm;
3355 if (n->m_flags & M_PKTHDR) {
3356 MGETHDR(mnew, M_NOWAIT, MT_HEADER);
3357 if (mnew == NULL)
3358 goto fail;
3359 if (!m_dup_pkthdr(mnew, n, M_NOWAIT)) {
3360 m_free(mnew);
3361 goto fail;
3363 } else {
3364 MGET(mnew, M_NOWAIT, MT_DATA);
3365 if (mnew == NULL)
3366 goto fail;
3368 mnew->m_len = 0;
3369 mm = mnew;
3372 * Copy data. If we don't have enough space to
3373 * store the whole data, allocate a cluster
3374 * or additional mbufs.
3375 * XXX: we don't use m_copyback(), since the
3376 * function does not use clusters and thus is
3377 * inefficient.
3379 remain = n->m_len;
3380 copied = 0;
3381 while (1) {
3382 int len;
3383 struct mbuf *mn;
3385 if (remain <= (mm->m_flags & M_PKTHDR ? MHLEN : MLEN))
3386 len = remain;
3387 else { /* allocate a cluster */
3388 MCLGET(mm, M_NOWAIT);
3389 if (!(mm->m_flags & M_EXT)) {
3390 m_free(mm);
3391 goto fail;
3393 len = remain < MCLBYTES ?
3394 remain : MCLBYTES;
3397 bcopy(n->m_data + copied, mm->m_data,
3398 len);
3400 copied += len;
3401 remain -= len;
3402 mm->m_len = len;
3404 if (remain <= 0) /* completed? */
3405 break;
3407 /* need another mbuf */
3408 MGETHDR(mn, M_NOWAIT, MT_HEADER);
3409 if (mn == NULL)
3410 goto fail;
3411 mn->m_pkthdr.rcvif = NULL;
3412 mm->m_next = mn;
3413 mm = mn;
3416 /* adjust chain */
3417 mm->m_next = m_free(n);
3418 n = mm;
3419 *mpp = mnew;
3420 mpp = &n->m_next;
3422 continue;
3425 *mpp = n;
3426 mpp = &n->m_next;
3429 return (m);
3430 fail:
3431 m_freem(m);
3432 return (NULL);
3435 void
3436 ipsec_delaux(struct mbuf *m)
3438 struct m_tag *mtag;
3440 while ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL)) != NULL)
3441 m_tag_delete(m, mtag);
3445 ipsec_addhist(struct mbuf *m, int proto, u_int32_t spi)
3447 struct m_tag *mtag;
3448 struct ipsec_history *p;
3450 mtag = m_tag_get(PACKET_TAG_IPSEC_HISTORY,
3451 sizeof(struct ipsec_history), M_NOWAIT);
3452 if (mtag == NULL)
3453 return ENOBUFS;
3454 p = (struct ipsec_history *)m_tag_data(mtag);
3455 bzero(p, sizeof(*p));
3456 p->ih_proto = proto;
3457 p->ih_spi = spi;
3458 m_tag_prepend(m, mtag);
3459 return 0;
3462 struct ipsec_history *
3463 ipsec_gethist(struct mbuf *m, int *lenp)
3465 struct m_tag *mtag;
3467 mtag = m_tag_find(m, PACKET_TAG_IPSEC_HISTORY, NULL);
3468 if (mtag == NULL)
3469 return NULL;
3470 /* XXX NB: noone uses this so fake it */
3471 if (lenp)
3472 *lenp = sizeof(struct ipsec_history);
3473 return (struct ipsec_history *)m_tag_data(mtag);