ip6_output.c revision 1.144 1 /* $NetBSD: ip6_output.c,v 1.144 2012/01/10 20:05:37 drochner Exp $ */
2 /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
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.
19 *
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.
31 */
32
33 /*
34 * Copyright (c) 1982, 1986, 1988, 1990, 1993
35 * The Regents of the University of California. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
62 */
63
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.144 2012/01/10 20:05:37 drochner Exp $");
66
67 #include "opt_inet.h"
68 #include "opt_inet6.h"
69 #include "opt_ipsec.h"
70 #include "opt_pfil_hooks.h"
71
72 #include <sys/param.h>
73 #include <sys/malloc.h>
74 #include <sys/mbuf.h>
75 #include <sys/errno.h>
76 #include <sys/protosw.h>
77 #include <sys/socket.h>
78 #include <sys/socketvar.h>
79 #include <sys/systm.h>
80 #include <sys/proc.h>
81 #include <sys/kauth.h>
82
83 #include <net/if.h>
84 #include <net/route.h>
85 #ifdef PFIL_HOOKS
86 #include <net/pfil.h>
87 #endif
88
89 #include <netinet/in.h>
90 #include <netinet/in_var.h>
91 #include <netinet/ip6.h>
92 #include <netinet/icmp6.h>
93 #include <netinet/in_offload.h>
94 #include <netinet6/in6_offload.h>
95 #include <netinet6/ip6_var.h>
96 #include <netinet6/ip6_private.h>
97 #include <netinet6/in6_pcb.h>
98 #include <netinet6/nd6.h>
99 #include <netinet6/ip6protosw.h>
100 #include <netinet6/scope6_var.h>
101
102 #ifdef KAME_IPSEC
103 #include <netinet6/ipsec.h>
104 #include <netinet6/ipsec_private.h>
105 #include <netkey/key.h>
106 #endif /* KAME_IPSEC */
107
108 #ifdef FAST_IPSEC
109 #include <netipsec/ipsec.h>
110 #include <netipsec/ipsec6.h>
111 #include <netipsec/key.h>
112 #include <netipsec/xform.h>
113 #endif
114
115
116 #include <net/net_osdep.h>
117
118 #ifdef PFIL_HOOKS
119 extern struct pfil_head inet6_pfil_hook; /* XXX */
120 #endif
121
122 struct ip6_exthdrs {
123 struct mbuf *ip6e_ip6;
124 struct mbuf *ip6e_hbh;
125 struct mbuf *ip6e_dest1;
126 struct mbuf *ip6e_rthdr;
127 struct mbuf *ip6e_dest2;
128 };
129
130 static int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **,
131 kauth_cred_t, int);
132 static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *);
133 static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, kauth_cred_t,
134 int, int, int);
135 static int ip6_setmoptions(const struct sockopt *, struct ip6_moptions **);
136 static int ip6_getmoptions(struct sockopt *, struct ip6_moptions *);
137 static int ip6_copyexthdr(struct mbuf **, void *, int);
138 static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
139 struct ip6_frag **);
140 static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
141 static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
142 static int ip6_getpmtu(struct route *, struct route *, struct ifnet *,
143 const struct in6_addr *, u_long *, int *);
144 static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
145
146 #ifdef RFC2292
147 static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *);
148 #endif
149
150 /*
151 * IP6 output. The packet in mbuf chain m contains a skeletal IP6
152 * header (with pri, len, nxt, hlim, src, dst).
153 * This function may modify ver and hlim only.
154 * The mbuf chain containing the packet will be freed.
155 * The mbuf opt, if present, will not be freed.
156 *
157 * type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and
158 * nd_ifinfo.linkmtu is u_int32_t. so we use u_long to hold largest one,
159 * which is rt_rmx.rmx_mtu.
160 */
161 int
162 ip6_output(
163 struct mbuf *m0,
164 struct ip6_pktopts *opt,
165 struct route *ro,
166 int flags,
167 struct ip6_moptions *im6o,
168 struct socket *so,
169 struct ifnet **ifpp /* XXX: just for statistics */
170 )
171 {
172 struct ip6_hdr *ip6, *mhip6;
173 struct ifnet *ifp, *origifp;
174 struct mbuf *m = m0;
175 int hlen, tlen, len, off;
176 bool tso;
177 struct route ip6route;
178 struct rtentry *rt = NULL;
179 const struct sockaddr_in6 *dst = NULL;
180 struct sockaddr_in6 src_sa, dst_sa;
181 int error = 0;
182 struct in6_ifaddr *ia = NULL;
183 u_long mtu;
184 int alwaysfrag, dontfrag;
185 u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
186 struct ip6_exthdrs exthdrs;
187 struct in6_addr finaldst, src0, dst0;
188 u_int32_t zone;
189 struct route *ro_pmtu = NULL;
190 int hdrsplit = 0;
191 int needipsec = 0;
192 #ifdef KAME_IPSEC
193 int needipsectun = 0;
194 struct secpolicy *sp = NULL;
195
196 ip6 = mtod(m, struct ip6_hdr *);
197 #endif /* KAME_IPSEC */
198 #ifdef FAST_IPSEC
199 struct secpolicy *sp = NULL;
200 int s;
201 #endif
202
203 memset(&ip6route, 0, sizeof(ip6route));
204
205 #ifdef DIAGNOSTIC
206 if ((m->m_flags & M_PKTHDR) == 0)
207 panic("ip6_output: no HDR");
208
209 if ((m->m_pkthdr.csum_flags &
210 (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) != 0) {
211 panic("ip6_output: IPv4 checksum offload flags: %d",
212 m->m_pkthdr.csum_flags);
213 }
214
215 if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) ==
216 (M_CSUM_TCPv6|M_CSUM_UDPv6)) {
217 panic("ip6_output: conflicting checksum offload flags: %d",
218 m->m_pkthdr.csum_flags);
219 }
220 #endif
221
222 M_CSUM_DATA_IPv6_HL_SET(m->m_pkthdr.csum_data, sizeof(struct ip6_hdr));
223
224 #define MAKE_EXTHDR(hp, mp) \
225 do { \
226 if (hp) { \
227 struct ip6_ext *eh = (struct ip6_ext *)(hp); \
228 error = ip6_copyexthdr((mp), (void *)(hp), \
229 ((eh)->ip6e_len + 1) << 3); \
230 if (error) \
231 goto freehdrs; \
232 } \
233 } while (/*CONSTCOND*/ 0)
234
235 memset(&exthdrs, 0, sizeof(exthdrs));
236 if (opt) {
237 /* Hop-by-Hop options header */
238 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
239 /* Destination options header(1st part) */
240 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
241 /* Routing header */
242 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
243 /* Destination options header(2nd part) */
244 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
245 }
246
247 #ifdef KAME_IPSEC
248 if ((flags & IPV6_FORWARDING) != 0) {
249 needipsec = 0;
250 goto skippolicycheck;
251 }
252
253 /* get a security policy for this packet */
254 if (so == NULL)
255 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
256 else {
257 if (IPSEC_PCB_SKIP_IPSEC(sotoinpcb_hdr(so)->inph_sp,
258 IPSEC_DIR_OUTBOUND)) {
259 needipsec = 0;
260 goto skippolicycheck;
261 }
262 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
263 }
264
265 if (sp == NULL) {
266 IPSEC6_STATINC(IPSEC_STAT_OUT_INVAL);
267 goto freehdrs;
268 }
269
270 error = 0;
271
272 /* check policy */
273 switch (sp->policy) {
274 case IPSEC_POLICY_DISCARD:
275 /*
276 * This packet is just discarded.
277 */
278 IPSEC6_STATINC(IPSEC_STAT_OUT_POLVIO);
279 goto freehdrs;
280
281 case IPSEC_POLICY_BYPASS:
282 case IPSEC_POLICY_NONE:
283 /* no need to do IPsec. */
284 needipsec = 0;
285 break;
286
287 case IPSEC_POLICY_IPSEC:
288 if (sp->req == NULL) {
289 /* XXX should be panic ? */
290 printf("ip6_output: No IPsec request specified.\n");
291 error = EINVAL;
292 goto freehdrs;
293 }
294 needipsec = 1;
295 break;
296
297 case IPSEC_POLICY_ENTRUST:
298 default:
299 printf("ip6_output: Invalid policy found. %d\n", sp->policy);
300 }
301
302 skippolicycheck:;
303 #endif /* KAME_IPSEC */
304
305 /*
306 * Calculate the total length of the extension header chain.
307 * Keep the length of the unfragmentable part for fragmentation.
308 */
309 optlen = 0;
310 if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
311 if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
312 if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
313 unfragpartlen = optlen + sizeof(struct ip6_hdr);
314 /* NOTE: we don't add AH/ESP length here. do that later. */
315 if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
316
317 #ifdef FAST_IPSEC
318 /* Check the security policy (SP) for the packet */
319
320 sp = ipsec6_check_policy(m,so,flags,&needipsec,&error);
321 if (error != 0) {
322 /*
323 * Hack: -EINVAL is used to signal that a packet
324 * should be silently discarded. This is typically
325 * because we asked key management for an SA and
326 * it was delayed (e.g. kicked up to IKE).
327 */
328 if (error == -EINVAL)
329 error = 0;
330 goto freehdrs;
331 }
332 #endif /* FAST_IPSEC */
333
334
335 if (needipsec &&
336 (m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) {
337 in6_delayed_cksum(m);
338 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
339 }
340
341
342 /*
343 * If we need IPsec, or there is at least one extension header,
344 * separate IP6 header from the payload.
345 */
346 if ((needipsec || optlen) && !hdrsplit) {
347 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
348 m = NULL;
349 goto freehdrs;
350 }
351 m = exthdrs.ip6e_ip6;
352 hdrsplit++;
353 }
354
355 /* adjust pointer */
356 ip6 = mtod(m, struct ip6_hdr *);
357
358 /* adjust mbuf packet header length */
359 m->m_pkthdr.len += optlen;
360 plen = m->m_pkthdr.len - sizeof(*ip6);
361
362 /* If this is a jumbo payload, insert a jumbo payload option. */
363 if (plen > IPV6_MAXPACKET) {
364 if (!hdrsplit) {
365 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
366 m = NULL;
367 goto freehdrs;
368 }
369 m = exthdrs.ip6e_ip6;
370 hdrsplit++;
371 }
372 /* adjust pointer */
373 ip6 = mtod(m, struct ip6_hdr *);
374 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
375 goto freehdrs;
376 optlen += 8; /* XXX JUMBOOPTLEN */
377 ip6->ip6_plen = 0;
378 } else
379 ip6->ip6_plen = htons(plen);
380
381 /*
382 * Concatenate headers and fill in next header fields.
383 * Here we have, on "m"
384 * IPv6 payload
385 * and we insert headers accordingly. Finally, we should be getting:
386 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
387 *
388 * during the header composing process, "m" points to IPv6 header.
389 * "mprev" points to an extension header prior to esp.
390 */
391 {
392 u_char *nexthdrp = &ip6->ip6_nxt;
393 struct mbuf *mprev = m;
394
395 /*
396 * we treat dest2 specially. this makes IPsec processing
397 * much easier. the goal here is to make mprev point the
398 * mbuf prior to dest2.
399 *
400 * result: IPv6 dest2 payload
401 * m and mprev will point to IPv6 header.
402 */
403 if (exthdrs.ip6e_dest2) {
404 if (!hdrsplit)
405 panic("assumption failed: hdr not split");
406 exthdrs.ip6e_dest2->m_next = m->m_next;
407 m->m_next = exthdrs.ip6e_dest2;
408 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
409 ip6->ip6_nxt = IPPROTO_DSTOPTS;
410 }
411
412 #define MAKE_CHAIN(m, mp, p, i)\
413 do {\
414 if (m) {\
415 if (!hdrsplit) \
416 panic("assumption failed: hdr not split"); \
417 *mtod((m), u_char *) = *(p);\
418 *(p) = (i);\
419 p = mtod((m), u_char *);\
420 (m)->m_next = (mp)->m_next;\
421 (mp)->m_next = (m);\
422 (mp) = (m);\
423 }\
424 } while (/*CONSTCOND*/ 0)
425 /*
426 * result: IPv6 hbh dest1 rthdr dest2 payload
427 * m will point to IPv6 header. mprev will point to the
428 * extension header prior to dest2 (rthdr in the above case).
429 */
430 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
431 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
432 IPPROTO_DSTOPTS);
433 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
434 IPPROTO_ROUTING);
435
436 M_CSUM_DATA_IPv6_HL_SET(m->m_pkthdr.csum_data,
437 sizeof(struct ip6_hdr) + optlen);
438
439 #ifdef KAME_IPSEC
440 if (!needipsec)
441 goto skip_ipsec2;
442
443 /*
444 * pointers after IPsec headers are not valid any more.
445 * other pointers need a great care too.
446 * (IPsec routines should not mangle mbufs prior to AH/ESP)
447 */
448 exthdrs.ip6e_dest2 = NULL;
449
450 {
451 struct ip6_rthdr *rh = NULL;
452 int segleft_org = 0;
453 struct ipsec_output_state state;
454
455 if (exthdrs.ip6e_rthdr) {
456 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
457 segleft_org = rh->ip6r_segleft;
458 rh->ip6r_segleft = 0;
459 }
460
461 memset(&state, 0, sizeof(state));
462 state.m = m;
463 error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
464 &needipsectun);
465 m = state.m;
466 if (error) {
467 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
468 /* mbuf is already reclaimed in ipsec6_output_trans. */
469 m = NULL;
470 switch (error) {
471 case EHOSTUNREACH:
472 case ENETUNREACH:
473 case EMSGSIZE:
474 case ENOBUFS:
475 case ENOMEM:
476 break;
477 default:
478 printf("ip6_output (ipsec): error code %d\n", error);
479 /* FALLTHROUGH */
480 case ENOENT:
481 /* don't show these error codes to the user */
482 error = 0;
483 break;
484 }
485 goto bad;
486 }
487 if (exthdrs.ip6e_rthdr) {
488 /* ah6_output doesn't modify mbuf chain */
489 rh->ip6r_segleft = segleft_org;
490 }
491 }
492 skip_ipsec2:;
493 #endif
494 }
495
496 /*
497 * If there is a routing header, replace destination address field
498 * with the first hop of the routing header.
499 */
500 if (exthdrs.ip6e_rthdr) {
501 struct ip6_rthdr *rh;
502 struct ip6_rthdr0 *rh0;
503 struct in6_addr *addr;
504 struct sockaddr_in6 sa;
505
506 rh = (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
507 struct ip6_rthdr *));
508 finaldst = ip6->ip6_dst;
509 switch (rh->ip6r_type) {
510 case IPV6_RTHDR_TYPE_0:
511 rh0 = (struct ip6_rthdr0 *)rh;
512 addr = (struct in6_addr *)(rh0 + 1);
513
514 /*
515 * construct a sockaddr_in6 form of
516 * the first hop.
517 *
518 * XXX: we may not have enough
519 * information about its scope zone;
520 * there is no standard API to pass
521 * the information from the
522 * application.
523 */
524 sockaddr_in6_init(&sa, addr, 0, 0, 0);
525 if ((error = sa6_embedscope(&sa,
526 ip6_use_defzone)) != 0) {
527 goto bad;
528 }
529 ip6->ip6_dst = sa.sin6_addr;
530 (void)memmove(&addr[0], &addr[1],
531 sizeof(struct in6_addr) *
532 (rh0->ip6r0_segleft - 1));
533 addr[rh0->ip6r0_segleft - 1] = finaldst;
534 /* XXX */
535 in6_clearscope(addr + rh0->ip6r0_segleft - 1);
536 break;
537 default: /* is it possible? */
538 error = EINVAL;
539 goto bad;
540 }
541 }
542
543 /* Source address validation */
544 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
545 (flags & IPV6_UNSPECSRC) == 0) {
546 error = EOPNOTSUPP;
547 IP6_STATINC(IP6_STAT_BADSCOPE);
548 goto bad;
549 }
550 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
551 error = EOPNOTSUPP;
552 IP6_STATINC(IP6_STAT_BADSCOPE);
553 goto bad;
554 }
555
556 IP6_STATINC(IP6_STAT_LOCALOUT);
557
558 /*
559 * Route packet.
560 */
561 /* initialize cached route */
562 if (ro == NULL) {
563 ro = &ip6route;
564 }
565 ro_pmtu = ro;
566 if (opt && opt->ip6po_rthdr)
567 ro = &opt->ip6po_route;
568
569 /*
570 * if specified, try to fill in the traffic class field.
571 * do not override if a non-zero value is already set.
572 * we check the diffserv field and the ecn field separately.
573 */
574 if (opt && opt->ip6po_tclass >= 0) {
575 int mask = 0;
576
577 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)
578 mask |= 0xfc;
579 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0)
580 mask |= 0x03;
581 if (mask != 0)
582 ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20);
583 }
584
585 /* fill in or override the hop limit field, if necessary. */
586 if (opt && opt->ip6po_hlim != -1)
587 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
588 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
589 if (im6o != NULL)
590 ip6->ip6_hlim = im6o->im6o_multicast_hlim;
591 else
592 ip6->ip6_hlim = ip6_defmcasthlim;
593 }
594
595 #ifdef KAME_IPSEC
596 if (needipsec && needipsectun) {
597 struct ipsec_output_state state;
598
599 /*
600 * All the extension headers will become inaccessible
601 * (since they can be encrypted).
602 * Don't panic, we need no more updates to extension headers
603 * on inner IPv6 packet (since they are now encapsulated).
604 *
605 * IPv6 [ESP|AH] IPv6 [extension headers] payload
606 */
607 memset(&exthdrs, 0, sizeof(exthdrs));
608 exthdrs.ip6e_ip6 = m;
609
610 memset(&state, 0, sizeof(state));
611 state.m = m;
612 state.ro = ro;
613 state.dst = rtcache_getdst(ro);
614
615 error = ipsec6_output_tunnel(&state, sp, flags);
616
617 m = state.m;
618 ro_pmtu = ro = state.ro;
619 dst = satocsin6(state.dst);
620 if (error) {
621 /* mbuf is already reclaimed in ipsec6_output_tunnel. */
622 m0 = m = NULL;
623 m = NULL;
624 switch (error) {
625 case EHOSTUNREACH:
626 case ENETUNREACH:
627 case EMSGSIZE:
628 case ENOBUFS:
629 case ENOMEM:
630 break;
631 default:
632 printf("ip6_output (ipsec): error code %d\n", error);
633 /* FALLTHROUGH */
634 case ENOENT:
635 /* don't show these error codes to the user */
636 error = 0;
637 break;
638 }
639 goto bad;
640 }
641
642 exthdrs.ip6e_ip6 = m;
643 }
644 #endif /* KAME_IPSEC */
645 #ifdef FAST_IPSEC
646 if (needipsec) {
647 s = splsoftnet();
648 error = ipsec6_process_packet(m,sp->req);
649
650 /*
651 * Preserve KAME behaviour: ENOENT can be returned
652 * when an SA acquire is in progress. Don't propagate
653 * this to user-level; it confuses applications.
654 * XXX this will go away when the SADB is redone.
655 */
656 if (error == ENOENT)
657 error = 0;
658 splx(s);
659 goto done;
660 }
661 #endif /* FAST_IPSEC */
662
663
664
665 /* adjust pointer */
666 ip6 = mtod(m, struct ip6_hdr *);
667
668 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
669 if ((error = in6_selectroute(&dst_sa, opt, im6o, ro,
670 &ifp, &rt, 0)) != 0) {
671 if (ifp != NULL)
672 in6_ifstat_inc(ifp, ifs6_out_discard);
673 goto bad;
674 }
675 if (rt == NULL) {
676 /*
677 * If in6_selectroute() does not return a route entry,
678 * dst may not have been updated.
679 */
680 rtcache_setdst(ro, sin6tosa(&dst_sa));
681 }
682
683 /*
684 * then rt (for unicast) and ifp must be non-NULL valid values.
685 */
686 if ((flags & IPV6_FORWARDING) == 0) {
687 /* XXX: the FORWARDING flag can be set for mrouting. */
688 in6_ifstat_inc(ifp, ifs6_out_request);
689 }
690 if (rt != NULL) {
691 ia = (struct in6_ifaddr *)(rt->rt_ifa);
692 rt->rt_use++;
693 }
694
695 /*
696 * The outgoing interface must be in the zone of source and
697 * destination addresses. We should use ia_ifp to support the
698 * case of sending packets to an address of our own.
699 */
700 if (ia != NULL && ia->ia_ifp)
701 origifp = ia->ia_ifp;
702 else
703 origifp = ifp;
704
705 src0 = ip6->ip6_src;
706 if (in6_setscope(&src0, origifp, &zone))
707 goto badscope;
708 sockaddr_in6_init(&src_sa, &ip6->ip6_src, 0, 0, 0);
709 if (sa6_recoverscope(&src_sa) || zone != src_sa.sin6_scope_id)
710 goto badscope;
711
712 dst0 = ip6->ip6_dst;
713 if (in6_setscope(&dst0, origifp, &zone))
714 goto badscope;
715 /* re-initialize to be sure */
716 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
717 if (sa6_recoverscope(&dst_sa) || zone != dst_sa.sin6_scope_id)
718 goto badscope;
719
720 /* scope check is done. */
721
722 if (rt == NULL || IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
723 if (dst == NULL)
724 dst = satocsin6(rtcache_getdst(ro));
725 KASSERT(dst != NULL);
726 } else if (opt && rtcache_validate(&opt->ip6po_nextroute) != NULL) {
727 /*
728 * The nexthop is explicitly specified by the
729 * application. We assume the next hop is an IPv6
730 * address.
731 */
732 dst = (struct sockaddr_in6 *)opt->ip6po_nexthop;
733 } else if ((rt->rt_flags & RTF_GATEWAY))
734 dst = (struct sockaddr_in6 *)rt->rt_gateway;
735 else if (dst == NULL)
736 dst = satocsin6(rtcache_getdst(ro));
737
738 /*
739 * XXXXXX: original code follows:
740 */
741 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
742 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
743 else {
744 struct in6_multi *in6m;
745
746 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
747
748 in6_ifstat_inc(ifp, ifs6_out_mcast);
749
750 /*
751 * Confirm that the outgoing interface supports multicast.
752 */
753 if (!(ifp->if_flags & IFF_MULTICAST)) {
754 IP6_STATINC(IP6_STAT_NOROUTE);
755 in6_ifstat_inc(ifp, ifs6_out_discard);
756 error = ENETUNREACH;
757 goto bad;
758 }
759
760 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
761 if (in6m != NULL &&
762 (im6o == NULL || im6o->im6o_multicast_loop)) {
763 /*
764 * If we belong to the destination multicast group
765 * on the outgoing interface, and the caller did not
766 * forbid loopback, loop back a copy.
767 */
768 KASSERT(dst != NULL);
769 ip6_mloopback(ifp, m, dst);
770 } else {
771 /*
772 * If we are acting as a multicast router, perform
773 * multicast forwarding as if the packet had just
774 * arrived on the interface to which we are about
775 * to send. The multicast forwarding function
776 * recursively calls this function, using the
777 * IPV6_FORWARDING flag to prevent infinite recursion.
778 *
779 * Multicasts that are looped back by ip6_mloopback(),
780 * above, will be forwarded by the ip6_input() routine,
781 * if necessary.
782 */
783 if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
784 if (ip6_mforward(ip6, ifp, m) != 0) {
785 m_freem(m);
786 goto done;
787 }
788 }
789 }
790 /*
791 * Multicasts with a hoplimit of zero may be looped back,
792 * above, but must not be transmitted on a network.
793 * Also, multicasts addressed to the loopback interface
794 * are not sent -- the above call to ip6_mloopback() will
795 * loop back a copy if this host actually belongs to the
796 * destination group on the loopback interface.
797 */
798 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
799 IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
800 m_freem(m);
801 goto done;
802 }
803 }
804
805 /*
806 * Fill the outgoing inteface to tell the upper layer
807 * to increment per-interface statistics.
808 */
809 if (ifpp)
810 *ifpp = ifp;
811
812 /* Determine path MTU. */
813 if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu,
814 &alwaysfrag)) != 0)
815 goto bad;
816 #ifdef KAME_IPSEC
817 if (needipsectun)
818 mtu = IPV6_MMTU;
819 #endif
820
821 /*
822 * The caller of this function may specify to use the minimum MTU
823 * in some cases.
824 * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU
825 * setting. The logic is a bit complicated; by default, unicast
826 * packets will follow path MTU while multicast packets will be sent at
827 * the minimum MTU. If IP6PO_MINMTU_ALL is specified, all packets
828 * including unicast ones will be sent at the minimum MTU. Multicast
829 * packets will always be sent at the minimum MTU unless
830 * IP6PO_MINMTU_DISABLE is explicitly specified.
831 * See RFC 3542 for more details.
832 */
833 if (mtu > IPV6_MMTU) {
834 if ((flags & IPV6_MINMTU))
835 mtu = IPV6_MMTU;
836 else if (opt && opt->ip6po_minmtu == IP6PO_MINMTU_ALL)
837 mtu = IPV6_MMTU;
838 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
839 (opt == NULL ||
840 opt->ip6po_minmtu != IP6PO_MINMTU_DISABLE)) {
841 mtu = IPV6_MMTU;
842 }
843 }
844
845 /*
846 * clear embedded scope identifiers if necessary.
847 * in6_clearscope will touch the addresses only when necessary.
848 */
849 in6_clearscope(&ip6->ip6_src);
850 in6_clearscope(&ip6->ip6_dst);
851
852 /*
853 * If the outgoing packet contains a hop-by-hop options header,
854 * it must be examined and processed even by the source node.
855 * (RFC 2460, section 4.)
856 */
857 if (ip6->ip6_nxt == IPV6_HOPOPTS) {
858 u_int32_t dummy1; /* XXX unused */
859 u_int32_t dummy2; /* XXX unused */
860 int hoff = sizeof(struct ip6_hdr);
861
862 if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) {
863 /* m was already freed at this point */
864 error = EINVAL;/* better error? */
865 goto done;
866 }
867
868 ip6 = mtod(m, struct ip6_hdr *);
869 }
870
871 #ifdef PFIL_HOOKS
872 /*
873 * Run through list of hooks for output packets.
874 */
875 if ((error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
876 goto done;
877 if (m == NULL)
878 goto done;
879 ip6 = mtod(m, struct ip6_hdr *);
880 #endif /* PFIL_HOOKS */
881 /*
882 * Send the packet to the outgoing interface.
883 * If necessary, do IPv6 fragmentation before sending.
884 *
885 * the logic here is rather complex:
886 * 1: normal case (dontfrag == 0, alwaysfrag == 0)
887 * 1-a: send as is if tlen <= path mtu
888 * 1-b: fragment if tlen > path mtu
889 *
890 * 2: if user asks us not to fragment (dontfrag == 1)
891 * 2-a: send as is if tlen <= interface mtu
892 * 2-b: error if tlen > interface mtu
893 *
894 * 3: if we always need to attach fragment header (alwaysfrag == 1)
895 * always fragment
896 *
897 * 4: if dontfrag == 1 && alwaysfrag == 1
898 * error, as we cannot handle this conflicting request
899 */
900 tlen = m->m_pkthdr.len;
901 tso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv6) != 0;
902 if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG))
903 dontfrag = 1;
904 else
905 dontfrag = 0;
906
907 if (dontfrag && alwaysfrag) { /* case 4 */
908 /* conflicting request - can't transmit */
909 error = EMSGSIZE;
910 goto bad;
911 }
912 if (dontfrag && (!tso && tlen > IN6_LINKMTU(ifp))) { /* case 2-b */
913 /*
914 * Even if the DONTFRAG option is specified, we cannot send the
915 * packet when the data length is larger than the MTU of the
916 * outgoing interface.
917 * Notify the error by sending IPV6_PATHMTU ancillary data as
918 * well as returning an error code (the latter is not described
919 * in the API spec.)
920 */
921 u_int32_t mtu32;
922 struct ip6ctlparam ip6cp;
923
924 mtu32 = (u_int32_t)mtu;
925 memset(&ip6cp, 0, sizeof(ip6cp));
926 ip6cp.ip6c_cmdarg = (void *)&mtu32;
927 pfctlinput2(PRC_MSGSIZE,
928 rtcache_getdst(ro_pmtu), &ip6cp);
929
930 error = EMSGSIZE;
931 goto bad;
932 }
933
934 /*
935 * transmit packet without fragmentation
936 */
937 if (dontfrag || (!alwaysfrag && (tlen <= mtu || tso))) {
938 /* case 1-a and 2-a */
939 struct in6_ifaddr *ia6;
940 int sw_csum;
941
942 ip6 = mtod(m, struct ip6_hdr *);
943 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
944 if (ia6) {
945 /* Record statistics for this interface address. */
946 ia6->ia_ifa.ifa_data.ifad_outbytes += m->m_pkthdr.len;
947 }
948 #ifdef KAME_IPSEC
949 /* clean ipsec history once it goes out of the node */
950 ipsec_delaux(m);
951 #endif
952
953 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
954 if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) {
955 if (IN6_NEED_CHECKSUM(ifp,
956 sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) {
957 in6_delayed_cksum(m);
958 }
959 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
960 }
961
962 KASSERT(dst != NULL);
963 if (__predict_true(!tso ||
964 (ifp->if_capenable & IFCAP_TSOv6) != 0)) {
965 error = nd6_output(ifp, origifp, m, dst, rt);
966 } else {
967 error = ip6_tso_output(ifp, origifp, m, dst, rt);
968 }
969 goto done;
970 }
971
972 if (tso) {
973 error = EINVAL; /* XXX */
974 goto bad;
975 }
976
977 /*
978 * try to fragment the packet. case 1-b and 3
979 */
980 if (mtu < IPV6_MMTU) {
981 /* path MTU cannot be less than IPV6_MMTU */
982 error = EMSGSIZE;
983 in6_ifstat_inc(ifp, ifs6_out_fragfail);
984 goto bad;
985 } else if (ip6->ip6_plen == 0) {
986 /* jumbo payload cannot be fragmented */
987 error = EMSGSIZE;
988 in6_ifstat_inc(ifp, ifs6_out_fragfail);
989 goto bad;
990 } else {
991 struct mbuf **mnext, *m_frgpart;
992 struct ip6_frag *ip6f;
993 u_int32_t id = htonl(ip6_randomid());
994 u_char nextproto;
995 #if 0 /* see below */
996 struct ip6ctlparam ip6cp;
997 u_int32_t mtu32;
998 #endif
999
1000 /*
1001 * Too large for the destination or interface;
1002 * fragment if possible.
1003 * Must be able to put at least 8 bytes per fragment.
1004 */
1005 hlen = unfragpartlen;
1006 if (mtu > IPV6_MAXPACKET)
1007 mtu = IPV6_MAXPACKET;
1008
1009 #if 0
1010 /*
1011 * It is believed this code is a leftover from the
1012 * development of the IPV6_RECVPATHMTU sockopt and
1013 * associated work to implement RFC3542.
1014 * It's not entirely clear what the intent of the API
1015 * is at this point, so disable this code for now.
1016 * The IPV6_RECVPATHMTU sockopt and/or IPV6_DONTFRAG
1017 * will send notifications if the application requests.
1018 */
1019
1020 /* Notify a proper path MTU to applications. */
1021 mtu32 = (u_int32_t)mtu;
1022 memset(&ip6cp, 0, sizeof(ip6cp));
1023 ip6cp.ip6c_cmdarg = (void *)&mtu32;
1024 pfctlinput2(PRC_MSGSIZE,
1025 rtcache_getdst(ro_pmtu), &ip6cp);
1026 #endif
1027
1028 len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
1029 if (len < 8) {
1030 error = EMSGSIZE;
1031 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1032 goto bad;
1033 }
1034
1035 mnext = &m->m_nextpkt;
1036
1037 /*
1038 * Change the next header field of the last header in the
1039 * unfragmentable part.
1040 */
1041 if (exthdrs.ip6e_rthdr) {
1042 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
1043 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
1044 } else if (exthdrs.ip6e_dest1) {
1045 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
1046 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
1047 } else if (exthdrs.ip6e_hbh) {
1048 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
1049 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
1050 } else {
1051 nextproto = ip6->ip6_nxt;
1052 ip6->ip6_nxt = IPPROTO_FRAGMENT;
1053 }
1054
1055 if ((m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6))
1056 != 0) {
1057 if (IN6_NEED_CHECKSUM(ifp,
1058 m->m_pkthdr.csum_flags &
1059 (M_CSUM_UDPv6|M_CSUM_TCPv6))) {
1060 in6_delayed_cksum(m);
1061 }
1062 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
1063 }
1064
1065 /*
1066 * Loop through length of segment after first fragment,
1067 * make new header and copy data of each part and link onto
1068 * chain.
1069 */
1070 m0 = m;
1071 for (off = hlen; off < tlen; off += len) {
1072 struct mbuf *mlast;
1073
1074 MGETHDR(m, M_DONTWAIT, MT_HEADER);
1075 if (!m) {
1076 error = ENOBUFS;
1077 IP6_STATINC(IP6_STAT_ODROPPED);
1078 goto sendorfree;
1079 }
1080 m->m_pkthdr.rcvif = NULL;
1081 m->m_flags = m0->m_flags & M_COPYFLAGS;
1082 *mnext = m;
1083 mnext = &m->m_nextpkt;
1084 m->m_data += max_linkhdr;
1085 mhip6 = mtod(m, struct ip6_hdr *);
1086 *mhip6 = *ip6;
1087 m->m_len = sizeof(*mhip6);
1088 error = ip6_insertfraghdr(m0, m, hlen, &ip6f);
1089 if (error) {
1090 IP6_STATINC(IP6_STAT_ODROPPED);
1091 goto sendorfree;
1092 }
1093 ip6f->ip6f_offlg = htons((u_int16_t)((off - hlen) & ~7));
1094 if (off + len >= tlen)
1095 len = tlen - off;
1096 else
1097 ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
1098 mhip6->ip6_plen = htons((u_int16_t)(len + hlen +
1099 sizeof(*ip6f) - sizeof(struct ip6_hdr)));
1100 if ((m_frgpart = m_copy(m0, off, len)) == 0) {
1101 error = ENOBUFS;
1102 IP6_STATINC(IP6_STAT_ODROPPED);
1103 goto sendorfree;
1104 }
1105 for (mlast = m; mlast->m_next; mlast = mlast->m_next)
1106 ;
1107 mlast->m_next = m_frgpart;
1108 m->m_pkthdr.len = len + hlen + sizeof(*ip6f);
1109 m->m_pkthdr.rcvif = NULL;
1110 ip6f->ip6f_reserved = 0;
1111 ip6f->ip6f_ident = id;
1112 ip6f->ip6f_nxt = nextproto;
1113 IP6_STATINC(IP6_STAT_OFRAGMENTS);
1114 in6_ifstat_inc(ifp, ifs6_out_fragcreat);
1115 }
1116
1117 in6_ifstat_inc(ifp, ifs6_out_fragok);
1118 }
1119
1120 /*
1121 * Remove leading garbages.
1122 */
1123 sendorfree:
1124 m = m0->m_nextpkt;
1125 m0->m_nextpkt = 0;
1126 m_freem(m0);
1127 for (m0 = m; m; m = m0) {
1128 m0 = m->m_nextpkt;
1129 m->m_nextpkt = 0;
1130 if (error == 0) {
1131 struct in6_ifaddr *ia6;
1132 ip6 = mtod(m, struct ip6_hdr *);
1133 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
1134 if (ia6) {
1135 /*
1136 * Record statistics for this interface
1137 * address.
1138 */
1139 ia6->ia_ifa.ifa_data.ifad_outbytes +=
1140 m->m_pkthdr.len;
1141 }
1142 #ifdef KAME_IPSEC
1143 /* clean ipsec history once it goes out of the node */
1144 ipsec_delaux(m);
1145 #endif
1146 KASSERT(dst != NULL);
1147 error = nd6_output(ifp, origifp, m, dst, rt);
1148 } else
1149 m_freem(m);
1150 }
1151
1152 if (error == 0)
1153 IP6_STATINC(IP6_STAT_FRAGMENTED);
1154
1155 done:
1156 rtcache_free(&ip6route);
1157
1158 #ifdef KAME_IPSEC
1159 if (sp != NULL)
1160 key_freesp(sp);
1161 #endif /* KAME_IPSEC */
1162 #ifdef FAST_IPSEC
1163 if (sp != NULL)
1164 KEY_FREESP(&sp);
1165 #endif /* FAST_IPSEC */
1166
1167
1168 return (error);
1169
1170 freehdrs:
1171 m_freem(exthdrs.ip6e_hbh); /* m_freem will check if mbuf is 0 */
1172 m_freem(exthdrs.ip6e_dest1);
1173 m_freem(exthdrs.ip6e_rthdr);
1174 m_freem(exthdrs.ip6e_dest2);
1175 /* FALLTHROUGH */
1176 bad:
1177 m_freem(m);
1178 goto done;
1179 badscope:
1180 IP6_STATINC(IP6_STAT_BADSCOPE);
1181 in6_ifstat_inc(origifp, ifs6_out_discard);
1182 if (error == 0)
1183 error = EHOSTUNREACH; /* XXX */
1184 goto bad;
1185 }
1186
1187 static int
1188 ip6_copyexthdr(struct mbuf **mp, void *hdr, int hlen)
1189 {
1190 struct mbuf *m;
1191
1192 if (hlen > MCLBYTES)
1193 return (ENOBUFS); /* XXX */
1194
1195 MGET(m, M_DONTWAIT, MT_DATA);
1196 if (!m)
1197 return (ENOBUFS);
1198
1199 if (hlen > MLEN) {
1200 MCLGET(m, M_DONTWAIT);
1201 if ((m->m_flags & M_EXT) == 0) {
1202 m_free(m);
1203 return (ENOBUFS);
1204 }
1205 }
1206 m->m_len = hlen;
1207 if (hdr)
1208 bcopy(hdr, mtod(m, void *), hlen);
1209
1210 *mp = m;
1211 return (0);
1212 }
1213
1214 /*
1215 * Process a delayed payload checksum calculation.
1216 */
1217 void
1218 in6_delayed_cksum(struct mbuf *m)
1219 {
1220 uint16_t csum, offset;
1221
1222 KASSERT((m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0);
1223 KASSERT((~m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0);
1224 KASSERT((m->m_pkthdr.csum_flags
1225 & (M_CSUM_UDPv4|M_CSUM_TCPv4|M_CSUM_TSOv4)) == 0);
1226
1227 offset = M_CSUM_DATA_IPv6_HL(m->m_pkthdr.csum_data);
1228 csum = in6_cksum(m, 0, offset, m->m_pkthdr.len - offset);
1229 if (csum == 0 && (m->m_pkthdr.csum_flags & M_CSUM_UDPv6) != 0) {
1230 csum = 0xffff;
1231 }
1232
1233 offset += M_CSUM_DATA_IPv6_OFFSET(m->m_pkthdr.csum_data);
1234 if ((offset + sizeof(csum)) > m->m_len) {
1235 m_copyback(m, offset, sizeof(csum), &csum);
1236 } else {
1237 *(uint16_t *)(mtod(m, char *) + offset) = csum;
1238 }
1239 }
1240
1241 /*
1242 * Insert jumbo payload option.
1243 */
1244 static int
1245 ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
1246 {
1247 struct mbuf *mopt;
1248 u_int8_t *optbuf;
1249 u_int32_t v;
1250
1251 #define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
1252
1253 /*
1254 * If there is no hop-by-hop options header, allocate new one.
1255 * If there is one but it doesn't have enough space to store the
1256 * jumbo payload option, allocate a cluster to store the whole options.
1257 * Otherwise, use it to store the options.
1258 */
1259 if (exthdrs->ip6e_hbh == 0) {
1260 MGET(mopt, M_DONTWAIT, MT_DATA);
1261 if (mopt == 0)
1262 return (ENOBUFS);
1263 mopt->m_len = JUMBOOPTLEN;
1264 optbuf = mtod(mopt, u_int8_t *);
1265 optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */
1266 exthdrs->ip6e_hbh = mopt;
1267 } else {
1268 struct ip6_hbh *hbh;
1269
1270 mopt = exthdrs->ip6e_hbh;
1271 if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
1272 /*
1273 * XXX assumption:
1274 * - exthdrs->ip6e_hbh is not referenced from places
1275 * other than exthdrs.
1276 * - exthdrs->ip6e_hbh is not an mbuf chain.
1277 */
1278 int oldoptlen = mopt->m_len;
1279 struct mbuf *n;
1280
1281 /*
1282 * XXX: give up if the whole (new) hbh header does
1283 * not fit even in an mbuf cluster.
1284 */
1285 if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
1286 return (ENOBUFS);
1287
1288 /*
1289 * As a consequence, we must always prepare a cluster
1290 * at this point.
1291 */
1292 MGET(n, M_DONTWAIT, MT_DATA);
1293 if (n) {
1294 MCLGET(n, M_DONTWAIT);
1295 if ((n->m_flags & M_EXT) == 0) {
1296 m_freem(n);
1297 n = NULL;
1298 }
1299 }
1300 if (!n)
1301 return (ENOBUFS);
1302 n->m_len = oldoptlen + JUMBOOPTLEN;
1303 bcopy(mtod(mopt, void *), mtod(n, void *),
1304 oldoptlen);
1305 optbuf = mtod(n, u_int8_t *) + oldoptlen;
1306 m_freem(mopt);
1307 mopt = exthdrs->ip6e_hbh = n;
1308 } else {
1309 optbuf = mtod(mopt, u_int8_t *) + mopt->m_len;
1310 mopt->m_len += JUMBOOPTLEN;
1311 }
1312 optbuf[0] = IP6OPT_PADN;
1313 optbuf[1] = 0;
1314
1315 /*
1316 * Adjust the header length according to the pad and
1317 * the jumbo payload option.
1318 */
1319 hbh = mtod(mopt, struct ip6_hbh *);
1320 hbh->ip6h_len += (JUMBOOPTLEN >> 3);
1321 }
1322
1323 /* fill in the option. */
1324 optbuf[2] = IP6OPT_JUMBO;
1325 optbuf[3] = 4;
1326 v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
1327 bcopy(&v, &optbuf[4], sizeof(u_int32_t));
1328
1329 /* finally, adjust the packet header length */
1330 exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
1331
1332 return (0);
1333 #undef JUMBOOPTLEN
1334 }
1335
1336 /*
1337 * Insert fragment header and copy unfragmentable header portions.
1338 */
1339 static int
1340 ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen,
1341 struct ip6_frag **frghdrp)
1342 {
1343 struct mbuf *n, *mlast;
1344
1345 if (hlen > sizeof(struct ip6_hdr)) {
1346 n = m_copym(m0, sizeof(struct ip6_hdr),
1347 hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
1348 if (n == 0)
1349 return (ENOBUFS);
1350 m->m_next = n;
1351 } else
1352 n = m;
1353
1354 /* Search for the last mbuf of unfragmentable part. */
1355 for (mlast = n; mlast->m_next; mlast = mlast->m_next)
1356 ;
1357
1358 if ((mlast->m_flags & M_EXT) == 0 &&
1359 M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) {
1360 /* use the trailing space of the last mbuf for the fragment hdr */
1361 *frghdrp = (struct ip6_frag *)(mtod(mlast, char *) +
1362 mlast->m_len);
1363 mlast->m_len += sizeof(struct ip6_frag);
1364 m->m_pkthdr.len += sizeof(struct ip6_frag);
1365 } else {
1366 /* allocate a new mbuf for the fragment header */
1367 struct mbuf *mfrg;
1368
1369 MGET(mfrg, M_DONTWAIT, MT_DATA);
1370 if (mfrg == 0)
1371 return (ENOBUFS);
1372 mfrg->m_len = sizeof(struct ip6_frag);
1373 *frghdrp = mtod(mfrg, struct ip6_frag *);
1374 mlast->m_next = mfrg;
1375 }
1376
1377 return (0);
1378 }
1379
1380 static int
1381 ip6_getpmtu(struct route *ro_pmtu, struct route *ro, struct ifnet *ifp,
1382 const struct in6_addr *dst, u_long *mtup, int *alwaysfragp)
1383 {
1384 struct rtentry *rt;
1385 u_int32_t mtu = 0;
1386 int alwaysfrag = 0;
1387 int error = 0;
1388
1389 if (ro_pmtu != ro) {
1390 union {
1391 struct sockaddr dst;
1392 struct sockaddr_in6 dst6;
1393 } u;
1394
1395 /* The first hop and the final destination may differ. */
1396 sockaddr_in6_init(&u.dst6, dst, 0, 0, 0);
1397 rt = rtcache_lookup(ro_pmtu, &u.dst);
1398 } else
1399 rt = rtcache_validate(ro_pmtu);
1400 if (rt != NULL) {
1401 u_int32_t ifmtu;
1402
1403 if (ifp == NULL)
1404 ifp = rt->rt_ifp;
1405 ifmtu = IN6_LINKMTU(ifp);
1406 mtu = rt->rt_rmx.rmx_mtu;
1407 if (mtu == 0)
1408 mtu = ifmtu;
1409 else if (mtu < IPV6_MMTU) {
1410 /*
1411 * RFC2460 section 5, last paragraph:
1412 * if we record ICMPv6 too big message with
1413 * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU
1414 * or smaller, with fragment header attached.
1415 * (fragment header is needed regardless from the
1416 * packet size, for translators to identify packets)
1417 */
1418 alwaysfrag = 1;
1419 mtu = IPV6_MMTU;
1420 } else if (mtu > ifmtu) {
1421 /*
1422 * The MTU on the route is larger than the MTU on
1423 * the interface! This shouldn't happen, unless the
1424 * MTU of the interface has been changed after the
1425 * interface was brought up. Change the MTU in the
1426 * route to match the interface MTU (as long as the
1427 * field isn't locked).
1428 */
1429 mtu = ifmtu;
1430 if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
1431 rt->rt_rmx.rmx_mtu = mtu;
1432 }
1433 } else if (ifp) {
1434 mtu = IN6_LINKMTU(ifp);
1435 } else
1436 error = EHOSTUNREACH; /* XXX */
1437
1438 *mtup = mtu;
1439 if (alwaysfragp)
1440 *alwaysfragp = alwaysfrag;
1441 return (error);
1442 }
1443
1444 /*
1445 * IP6 socket option processing.
1446 */
1447 int
1448 ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt)
1449 {
1450 int optdatalen, uproto;
1451 void *optdata;
1452 struct in6pcb *in6p = sotoin6pcb(so);
1453 int error, optval;
1454 int level, optname;
1455
1456 KASSERT(sopt != NULL);
1457
1458 level = sopt->sopt_level;
1459 optname = sopt->sopt_name;
1460
1461 error = optval = 0;
1462 uproto = (int)so->so_proto->pr_protocol;
1463
1464 if (level != IPPROTO_IPV6) {
1465 return ENOPROTOOPT;
1466 }
1467 switch (op) {
1468 case PRCO_SETOPT:
1469 switch (optname) {
1470 #ifdef RFC2292
1471 case IPV6_2292PKTOPTIONS:
1472 error = ip6_pcbopts(&in6p->in6p_outputopts, so, sopt);
1473 break;
1474 #endif
1475
1476 /*
1477 * Use of some Hop-by-Hop options or some
1478 * Destination options, might require special
1479 * privilege. That is, normal applications
1480 * (without special privilege) might be forbidden
1481 * from setting certain options in outgoing packets,
1482 * and might never see certain options in received
1483 * packets. [RFC 2292 Section 6]
1484 * KAME specific note:
1485 * KAME prevents non-privileged users from sending or
1486 * receiving ANY hbh/dst options in order to avoid
1487 * overhead of parsing options in the kernel.
1488 */
1489 case IPV6_RECVHOPOPTS:
1490 case IPV6_RECVDSTOPTS:
1491 case IPV6_RECVRTHDRDSTOPTS:
1492 error = kauth_authorize_generic(kauth_cred_get(),
1493 KAUTH_GENERIC_ISSUSER, NULL);
1494 if (error)
1495 break;
1496 /* FALLTHROUGH */
1497 case IPV6_UNICAST_HOPS:
1498 case IPV6_HOPLIMIT:
1499 case IPV6_FAITH:
1500
1501 case IPV6_RECVPKTINFO:
1502 case IPV6_RECVHOPLIMIT:
1503 case IPV6_RECVRTHDR:
1504 case IPV6_RECVPATHMTU:
1505 case IPV6_RECVTCLASS:
1506 case IPV6_V6ONLY:
1507 error = sockopt_getint(sopt, &optval);
1508 if (error)
1509 break;
1510 switch (optname) {
1511 case IPV6_UNICAST_HOPS:
1512 if (optval < -1 || optval >= 256)
1513 error = EINVAL;
1514 else {
1515 /* -1 = kernel default */
1516 in6p->in6p_hops = optval;
1517 }
1518 break;
1519 #define OPTSET(bit) \
1520 do { \
1521 if (optval) \
1522 in6p->in6p_flags |= (bit); \
1523 else \
1524 in6p->in6p_flags &= ~(bit); \
1525 } while (/*CONSTCOND*/ 0)
1526
1527 #ifdef RFC2292
1528 #define OPTSET2292(bit) \
1529 do { \
1530 in6p->in6p_flags |= IN6P_RFC2292; \
1531 if (optval) \
1532 in6p->in6p_flags |= (bit); \
1533 else \
1534 in6p->in6p_flags &= ~(bit); \
1535 } while (/*CONSTCOND*/ 0)
1536 #endif
1537
1538 #define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0)
1539
1540 case IPV6_RECVPKTINFO:
1541 #ifdef RFC2292
1542 /* cannot mix with RFC2292 */
1543 if (OPTBIT(IN6P_RFC2292)) {
1544 error = EINVAL;
1545 break;
1546 }
1547 #endif
1548 OPTSET(IN6P_PKTINFO);
1549 break;
1550
1551 case IPV6_HOPLIMIT:
1552 {
1553 struct ip6_pktopts **optp;
1554
1555 #ifdef RFC2292
1556 /* cannot mix with RFC2292 */
1557 if (OPTBIT(IN6P_RFC2292)) {
1558 error = EINVAL;
1559 break;
1560 }
1561 #endif
1562 optp = &in6p->in6p_outputopts;
1563 error = ip6_pcbopt(IPV6_HOPLIMIT,
1564 (u_char *)&optval,
1565 sizeof(optval),
1566 optp,
1567 kauth_cred_get(), uproto);
1568 break;
1569 }
1570
1571 case IPV6_RECVHOPLIMIT:
1572 #ifdef RFC2292
1573 /* cannot mix with RFC2292 */
1574 if (OPTBIT(IN6P_RFC2292)) {
1575 error = EINVAL;
1576 break;
1577 }
1578 #endif
1579 OPTSET(IN6P_HOPLIMIT);
1580 break;
1581
1582 case IPV6_RECVHOPOPTS:
1583 #ifdef RFC2292
1584 /* cannot mix with RFC2292 */
1585 if (OPTBIT(IN6P_RFC2292)) {
1586 error = EINVAL;
1587 break;
1588 }
1589 #endif
1590 OPTSET(IN6P_HOPOPTS);
1591 break;
1592
1593 case IPV6_RECVDSTOPTS:
1594 #ifdef RFC2292
1595 /* cannot mix with RFC2292 */
1596 if (OPTBIT(IN6P_RFC2292)) {
1597 error = EINVAL;
1598 break;
1599 }
1600 #endif
1601 OPTSET(IN6P_DSTOPTS);
1602 break;
1603
1604 case IPV6_RECVRTHDRDSTOPTS:
1605 #ifdef RFC2292
1606 /* cannot mix with RFC2292 */
1607 if (OPTBIT(IN6P_RFC2292)) {
1608 error = EINVAL;
1609 break;
1610 }
1611 #endif
1612 OPTSET(IN6P_RTHDRDSTOPTS);
1613 break;
1614
1615 case IPV6_RECVRTHDR:
1616 #ifdef RFC2292
1617 /* cannot mix with RFC2292 */
1618 if (OPTBIT(IN6P_RFC2292)) {
1619 error = EINVAL;
1620 break;
1621 }
1622 #endif
1623 OPTSET(IN6P_RTHDR);
1624 break;
1625
1626 case IPV6_FAITH:
1627 OPTSET(IN6P_FAITH);
1628 break;
1629
1630 case IPV6_RECVPATHMTU:
1631 /*
1632 * We ignore this option for TCP
1633 * sockets.
1634 * (RFC3542 leaves this case
1635 * unspecified.)
1636 */
1637 if (uproto != IPPROTO_TCP)
1638 OPTSET(IN6P_MTU);
1639 break;
1640
1641 case IPV6_V6ONLY:
1642 /*
1643 * make setsockopt(IPV6_V6ONLY)
1644 * available only prior to bind(2).
1645 * see ipng mailing list, Jun 22 2001.
1646 */
1647 if (in6p->in6p_lport ||
1648 !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
1649 error = EINVAL;
1650 break;
1651 }
1652 #ifdef INET6_BINDV6ONLY
1653 if (!optval)
1654 error = EINVAL;
1655 #else
1656 OPTSET(IN6P_IPV6_V6ONLY);
1657 #endif
1658 break;
1659 case IPV6_RECVTCLASS:
1660 #ifdef RFC2292
1661 /* cannot mix with RFC2292 XXX */
1662 if (OPTBIT(IN6P_RFC2292)) {
1663 error = EINVAL;
1664 break;
1665 }
1666 #endif
1667 OPTSET(IN6P_TCLASS);
1668 break;
1669
1670 }
1671 break;
1672
1673 case IPV6_OTCLASS:
1674 {
1675 struct ip6_pktopts **optp;
1676 u_int8_t tclass;
1677
1678 error = sockopt_get(sopt, &tclass, sizeof(tclass));
1679 if (error)
1680 break;
1681 optp = &in6p->in6p_outputopts;
1682 error = ip6_pcbopt(optname,
1683 (u_char *)&tclass,
1684 sizeof(tclass),
1685 optp,
1686 kauth_cred_get(), uproto);
1687 break;
1688 }
1689
1690 case IPV6_TCLASS:
1691 case IPV6_DONTFRAG:
1692 case IPV6_USE_MIN_MTU:
1693 error = sockopt_getint(sopt, &optval);
1694 if (error)
1695 break;
1696 {
1697 struct ip6_pktopts **optp;
1698 optp = &in6p->in6p_outputopts;
1699 error = ip6_pcbopt(optname,
1700 (u_char *)&optval,
1701 sizeof(optval),
1702 optp,
1703 kauth_cred_get(), uproto);
1704 break;
1705 }
1706
1707 #ifdef RFC2292
1708 case IPV6_2292PKTINFO:
1709 case IPV6_2292HOPLIMIT:
1710 case IPV6_2292HOPOPTS:
1711 case IPV6_2292DSTOPTS:
1712 case IPV6_2292RTHDR:
1713 /* RFC 2292 */
1714 error = sockopt_getint(sopt, &optval);
1715 if (error)
1716 break;
1717
1718 switch (optname) {
1719 case IPV6_2292PKTINFO:
1720 OPTSET2292(IN6P_PKTINFO);
1721 break;
1722 case IPV6_2292HOPLIMIT:
1723 OPTSET2292(IN6P_HOPLIMIT);
1724 break;
1725 case IPV6_2292HOPOPTS:
1726 /*
1727 * Check super-user privilege.
1728 * See comments for IPV6_RECVHOPOPTS.
1729 */
1730 error =
1731 kauth_authorize_generic(kauth_cred_get(),
1732 KAUTH_GENERIC_ISSUSER, NULL);
1733 if (error)
1734 return (error);
1735 OPTSET2292(IN6P_HOPOPTS);
1736 break;
1737 case IPV6_2292DSTOPTS:
1738 error =
1739 kauth_authorize_generic(kauth_cred_get(),
1740 KAUTH_GENERIC_ISSUSER, NULL);
1741 if (error)
1742 return (error);
1743 OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
1744 break;
1745 case IPV6_2292RTHDR:
1746 OPTSET2292(IN6P_RTHDR);
1747 break;
1748 }
1749 break;
1750 #endif
1751 case IPV6_PKTINFO:
1752 case IPV6_HOPOPTS:
1753 case IPV6_RTHDR:
1754 case IPV6_DSTOPTS:
1755 case IPV6_RTHDRDSTOPTS:
1756 case IPV6_NEXTHOP: {
1757 /* new advanced API (RFC3542) */
1758 void *optbuf;
1759 int optbuflen;
1760 struct ip6_pktopts **optp;
1761
1762 #ifdef RFC2292
1763 /* cannot mix with RFC2292 */
1764 if (OPTBIT(IN6P_RFC2292)) {
1765 error = EINVAL;
1766 break;
1767 }
1768 #endif
1769
1770 optbuflen = sopt->sopt_size;
1771 optbuf = malloc(optbuflen, M_IP6OPT, M_NOWAIT);
1772 if (optbuf == NULL) {
1773 error = ENOBUFS;
1774 break;
1775 }
1776
1777 sockopt_get(sopt, optbuf, optbuflen);
1778 optp = &in6p->in6p_outputopts;
1779 error = ip6_pcbopt(optname, optbuf, optbuflen,
1780 optp, kauth_cred_get(), uproto);
1781 break;
1782 }
1783 #undef OPTSET
1784
1785 case IPV6_MULTICAST_IF:
1786 case IPV6_MULTICAST_HOPS:
1787 case IPV6_MULTICAST_LOOP:
1788 case IPV6_JOIN_GROUP:
1789 case IPV6_LEAVE_GROUP:
1790 error = ip6_setmoptions(sopt, &in6p->in6p_moptions);
1791 break;
1792
1793 case IPV6_PORTRANGE:
1794 error = sockopt_getint(sopt, &optval);
1795 if (error)
1796 break;
1797
1798 switch (optval) {
1799 case IPV6_PORTRANGE_DEFAULT:
1800 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1801 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1802 break;
1803
1804 case IPV6_PORTRANGE_HIGH:
1805 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1806 in6p->in6p_flags |= IN6P_HIGHPORT;
1807 break;
1808
1809 case IPV6_PORTRANGE_LOW:
1810 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1811 in6p->in6p_flags |= IN6P_LOWPORT;
1812 break;
1813
1814 default:
1815 error = EINVAL;
1816 break;
1817 }
1818 break;
1819
1820
1821 #if defined(KAME_IPSEC) || defined(FAST_IPSEC)
1822 case IPV6_IPSEC_POLICY:
1823 error = ipsec6_set_policy(in6p, optname,
1824 sopt->sopt_data, sopt->sopt_size, kauth_cred_get());
1825 break;
1826 #endif /* IPSEC */
1827
1828 default:
1829 error = ENOPROTOOPT;
1830 break;
1831 }
1832 break;
1833
1834 case PRCO_GETOPT:
1835 switch (optname) {
1836 #ifdef RFC2292
1837 case IPV6_2292PKTOPTIONS:
1838 /*
1839 * RFC3542 (effectively) deprecated the
1840 * semantics of the 2292-style pktoptions.
1841 * Since it was not reliable in nature (i.e.,
1842 * applications had to expect the lack of some
1843 * information after all), it would make sense
1844 * to simplify this part by always returning
1845 * empty data.
1846 */
1847 break;
1848 #endif
1849
1850 case IPV6_RECVHOPOPTS:
1851 case IPV6_RECVDSTOPTS:
1852 case IPV6_RECVRTHDRDSTOPTS:
1853 case IPV6_UNICAST_HOPS:
1854 case IPV6_RECVPKTINFO:
1855 case IPV6_RECVHOPLIMIT:
1856 case IPV6_RECVRTHDR:
1857 case IPV6_RECVPATHMTU:
1858
1859 case IPV6_FAITH:
1860 case IPV6_V6ONLY:
1861 case IPV6_PORTRANGE:
1862 case IPV6_RECVTCLASS:
1863 switch (optname) {
1864
1865 case IPV6_RECVHOPOPTS:
1866 optval = OPTBIT(IN6P_HOPOPTS);
1867 break;
1868
1869 case IPV6_RECVDSTOPTS:
1870 optval = OPTBIT(IN6P_DSTOPTS);
1871 break;
1872
1873 case IPV6_RECVRTHDRDSTOPTS:
1874 optval = OPTBIT(IN6P_RTHDRDSTOPTS);
1875 break;
1876
1877 case IPV6_UNICAST_HOPS:
1878 optval = in6p->in6p_hops;
1879 break;
1880
1881 case IPV6_RECVPKTINFO:
1882 optval = OPTBIT(IN6P_PKTINFO);
1883 break;
1884
1885 case IPV6_RECVHOPLIMIT:
1886 optval = OPTBIT(IN6P_HOPLIMIT);
1887 break;
1888
1889 case IPV6_RECVRTHDR:
1890 optval = OPTBIT(IN6P_RTHDR);
1891 break;
1892
1893 case IPV6_RECVPATHMTU:
1894 optval = OPTBIT(IN6P_MTU);
1895 break;
1896
1897 case IPV6_FAITH:
1898 optval = OPTBIT(IN6P_FAITH);
1899 break;
1900
1901 case IPV6_V6ONLY:
1902 optval = OPTBIT(IN6P_IPV6_V6ONLY);
1903 break;
1904
1905 case IPV6_PORTRANGE:
1906 {
1907 int flags;
1908 flags = in6p->in6p_flags;
1909 if (flags & IN6P_HIGHPORT)
1910 optval = IPV6_PORTRANGE_HIGH;
1911 else if (flags & IN6P_LOWPORT)
1912 optval = IPV6_PORTRANGE_LOW;
1913 else
1914 optval = 0;
1915 break;
1916 }
1917 case IPV6_RECVTCLASS:
1918 optval = OPTBIT(IN6P_TCLASS);
1919 break;
1920
1921 }
1922 if (error)
1923 break;
1924 error = sockopt_setint(sopt, optval);
1925 break;
1926
1927 case IPV6_PATHMTU:
1928 {
1929 u_long pmtu = 0;
1930 struct ip6_mtuinfo mtuinfo;
1931 struct route *ro = &in6p->in6p_route;
1932
1933 if (!(so->so_state & SS_ISCONNECTED))
1934 return (ENOTCONN);
1935 /*
1936 * XXX: we dot not consider the case of source
1937 * routing, or optional information to specify
1938 * the outgoing interface.
1939 */
1940 error = ip6_getpmtu(ro, NULL, NULL,
1941 &in6p->in6p_faddr, &pmtu, NULL);
1942 if (error)
1943 break;
1944 if (pmtu > IPV6_MAXPACKET)
1945 pmtu = IPV6_MAXPACKET;
1946
1947 memset(&mtuinfo, 0, sizeof(mtuinfo));
1948 mtuinfo.ip6m_mtu = (u_int32_t)pmtu;
1949 optdata = (void *)&mtuinfo;
1950 optdatalen = sizeof(mtuinfo);
1951 if (optdatalen > MCLBYTES)
1952 return (EMSGSIZE); /* XXX */
1953 error = sockopt_set(sopt, optdata, optdatalen);
1954 break;
1955 }
1956
1957 #ifdef RFC2292
1958 case IPV6_2292PKTINFO:
1959 case IPV6_2292HOPLIMIT:
1960 case IPV6_2292HOPOPTS:
1961 case IPV6_2292RTHDR:
1962 case IPV6_2292DSTOPTS:
1963 switch (optname) {
1964 case IPV6_2292PKTINFO:
1965 optval = OPTBIT(IN6P_PKTINFO);
1966 break;
1967 case IPV6_2292HOPLIMIT:
1968 optval = OPTBIT(IN6P_HOPLIMIT);
1969 break;
1970 case IPV6_2292HOPOPTS:
1971 optval = OPTBIT(IN6P_HOPOPTS);
1972 break;
1973 case IPV6_2292RTHDR:
1974 optval = OPTBIT(IN6P_RTHDR);
1975 break;
1976 case IPV6_2292DSTOPTS:
1977 optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS);
1978 break;
1979 }
1980 error = sockopt_setint(sopt, optval);
1981 break;
1982 #endif
1983 case IPV6_PKTINFO:
1984 case IPV6_HOPOPTS:
1985 case IPV6_RTHDR:
1986 case IPV6_DSTOPTS:
1987 case IPV6_RTHDRDSTOPTS:
1988 case IPV6_NEXTHOP:
1989 case IPV6_OTCLASS:
1990 case IPV6_TCLASS:
1991 case IPV6_DONTFRAG:
1992 case IPV6_USE_MIN_MTU:
1993 error = ip6_getpcbopt(in6p->in6p_outputopts,
1994 optname, sopt);
1995 break;
1996
1997 case IPV6_MULTICAST_IF:
1998 case IPV6_MULTICAST_HOPS:
1999 case IPV6_MULTICAST_LOOP:
2000 case IPV6_JOIN_GROUP:
2001 case IPV6_LEAVE_GROUP:
2002 error = ip6_getmoptions(sopt, in6p->in6p_moptions);
2003 break;
2004
2005 #if defined(KAME_IPSEC) || defined(FAST_IPSEC)
2006 case IPV6_IPSEC_POLICY:
2007 {
2008 struct mbuf *m = NULL;
2009
2010 /* XXX this will return EINVAL as sopt is empty */
2011 error = ipsec6_get_policy(in6p, sopt->sopt_data,
2012 sopt->sopt_size, &m);
2013 if (!error)
2014 error = sockopt_setmbuf(sopt, m);
2015
2016 break;
2017 }
2018 #endif /* IPSEC */
2019
2020 default:
2021 error = ENOPROTOOPT;
2022 break;
2023 }
2024 break;
2025 }
2026 return (error);
2027 }
2028
2029 int
2030 ip6_raw_ctloutput(int op, struct socket *so, struct sockopt *sopt)
2031 {
2032 int error = 0, optval;
2033 const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
2034 struct in6pcb *in6p = sotoin6pcb(so);
2035 int level, optname;
2036
2037 KASSERT(sopt != NULL);
2038
2039 level = sopt->sopt_level;
2040 optname = sopt->sopt_name;
2041
2042 if (level != IPPROTO_IPV6) {
2043 return ENOPROTOOPT;
2044 }
2045
2046 switch (optname) {
2047 case IPV6_CHECKSUM:
2048 /*
2049 * For ICMPv6 sockets, no modification allowed for checksum
2050 * offset, permit "no change" values to help existing apps.
2051 *
2052 * XXX RFC3542 says: "An attempt to set IPV6_CHECKSUM
2053 * for an ICMPv6 socket will fail." The current
2054 * behavior does not meet RFC3542.
2055 */
2056 switch (op) {
2057 case PRCO_SETOPT:
2058 error = sockopt_getint(sopt, &optval);
2059 if (error)
2060 break;
2061 if ((optval % 2) != 0) {
2062 /* the API assumes even offset values */
2063 error = EINVAL;
2064 } else if (so->so_proto->pr_protocol ==
2065 IPPROTO_ICMPV6) {
2066 if (optval != icmp6off)
2067 error = EINVAL;
2068 } else
2069 in6p->in6p_cksum = optval;
2070 break;
2071
2072 case PRCO_GETOPT:
2073 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
2074 optval = icmp6off;
2075 else
2076 optval = in6p->in6p_cksum;
2077
2078 error = sockopt_setint(sopt, optval);
2079 break;
2080
2081 default:
2082 error = EINVAL;
2083 break;
2084 }
2085 break;
2086
2087 default:
2088 error = ENOPROTOOPT;
2089 break;
2090 }
2091
2092 return (error);
2093 }
2094
2095 #ifdef RFC2292
2096 /*
2097 * Set up IP6 options in pcb for insertion in output packets or
2098 * specifying behavior of outgoing packets.
2099 */
2100 static int
2101 ip6_pcbopts(struct ip6_pktopts **pktopt, struct socket *so,
2102 struct sockopt *sopt)
2103 {
2104 struct ip6_pktopts *opt = *pktopt;
2105 struct mbuf *m;
2106 int error = 0;
2107
2108 /* turn off any old options. */
2109 if (opt) {
2110 #ifdef DIAGNOSTIC
2111 if (opt->ip6po_pktinfo || opt->ip6po_nexthop ||
2112 opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 ||
2113 opt->ip6po_rhinfo.ip6po_rhi_rthdr)
2114 printf("ip6_pcbopts: all specified options are cleared.\n");
2115 #endif
2116 ip6_clearpktopts(opt, -1);
2117 } else {
2118 opt = malloc(sizeof(*opt), M_IP6OPT, M_NOWAIT);
2119 if (opt == NULL)
2120 return (ENOBUFS);
2121 }
2122 *pktopt = NULL;
2123
2124 if (sopt == NULL || sopt->sopt_size == 0) {
2125 /*
2126 * Only turning off any previous options, regardless of
2127 * whether the opt is just created or given.
2128 */
2129 free(opt, M_IP6OPT);
2130 return (0);
2131 }
2132
2133 /* set options specified by user. */
2134 m = sockopt_getmbuf(sopt);
2135 if (m == NULL) {
2136 free(opt, M_IP6OPT);
2137 return (ENOBUFS);
2138 }
2139
2140 error = ip6_setpktopts(m, opt, NULL, kauth_cred_get(),
2141 so->so_proto->pr_protocol);
2142 m_freem(m);
2143 if (error != 0) {
2144 ip6_clearpktopts(opt, -1); /* XXX: discard all options */
2145 free(opt, M_IP6OPT);
2146 return (error);
2147 }
2148 *pktopt = opt;
2149 return (0);
2150 }
2151 #endif
2152
2153 /*
2154 * initialize ip6_pktopts. beware that there are non-zero default values in
2155 * the struct.
2156 */
2157 void
2158 ip6_initpktopts(struct ip6_pktopts *opt)
2159 {
2160
2161 memset(opt, 0, sizeof(*opt));
2162 opt->ip6po_hlim = -1; /* -1 means default hop limit */
2163 opt->ip6po_tclass = -1; /* -1 means default traffic class */
2164 opt->ip6po_minmtu = IP6PO_MINMTU_MCASTONLY;
2165 }
2166
2167 #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) /* XXX */
2168 static int
2169 ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
2170 kauth_cred_t cred, int uproto)
2171 {
2172 struct ip6_pktopts *opt;
2173
2174 if (*pktopt == NULL) {
2175 *pktopt = malloc(sizeof(struct ip6_pktopts), M_IP6OPT,
2176 M_NOWAIT);
2177 if (*pktopt == NULL)
2178 return (ENOBUFS);
2179
2180 ip6_initpktopts(*pktopt);
2181 }
2182 opt = *pktopt;
2183
2184 return (ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto));
2185 }
2186
2187 static int
2188 ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt)
2189 {
2190 void *optdata = NULL;
2191 int optdatalen = 0;
2192 struct ip6_ext *ip6e;
2193 int error = 0;
2194 struct in6_pktinfo null_pktinfo;
2195 int deftclass = 0, on;
2196 int defminmtu = IP6PO_MINMTU_MCASTONLY;
2197
2198 switch (optname) {
2199 case IPV6_PKTINFO:
2200 if (pktopt && pktopt->ip6po_pktinfo)
2201 optdata = (void *)pktopt->ip6po_pktinfo;
2202 else {
2203 /* XXX: we don't have to do this every time... */
2204 memset(&null_pktinfo, 0, sizeof(null_pktinfo));
2205 optdata = (void *)&null_pktinfo;
2206 }
2207 optdatalen = sizeof(struct in6_pktinfo);
2208 break;
2209 case IPV6_OTCLASS:
2210 /* XXX */
2211 return (EINVAL);
2212 case IPV6_TCLASS:
2213 if (pktopt && pktopt->ip6po_tclass >= 0)
2214 optdata = (void *)&pktopt->ip6po_tclass;
2215 else
2216 optdata = (void *)&deftclass;
2217 optdatalen = sizeof(int);
2218 break;
2219 case IPV6_HOPOPTS:
2220 if (pktopt && pktopt->ip6po_hbh) {
2221 optdata = (void *)pktopt->ip6po_hbh;
2222 ip6e = (struct ip6_ext *)pktopt->ip6po_hbh;
2223 optdatalen = (ip6e->ip6e_len + 1) << 3;
2224 }
2225 break;
2226 case IPV6_RTHDR:
2227 if (pktopt && pktopt->ip6po_rthdr) {
2228 optdata = (void *)pktopt->ip6po_rthdr;
2229 ip6e = (struct ip6_ext *)pktopt->ip6po_rthdr;
2230 optdatalen = (ip6e->ip6e_len + 1) << 3;
2231 }
2232 break;
2233 case IPV6_RTHDRDSTOPTS:
2234 if (pktopt && pktopt->ip6po_dest1) {
2235 optdata = (void *)pktopt->ip6po_dest1;
2236 ip6e = (struct ip6_ext *)pktopt->ip6po_dest1;
2237 optdatalen = (ip6e->ip6e_len + 1) << 3;
2238 }
2239 break;
2240 case IPV6_DSTOPTS:
2241 if (pktopt && pktopt->ip6po_dest2) {
2242 optdata = (void *)pktopt->ip6po_dest2;
2243 ip6e = (struct ip6_ext *)pktopt->ip6po_dest2;
2244 optdatalen = (ip6e->ip6e_len + 1) << 3;
2245 }
2246 break;
2247 case IPV6_NEXTHOP:
2248 if (pktopt && pktopt->ip6po_nexthop) {
2249 optdata = (void *)pktopt->ip6po_nexthop;
2250 optdatalen = pktopt->ip6po_nexthop->sa_len;
2251 }
2252 break;
2253 case IPV6_USE_MIN_MTU:
2254 if (pktopt)
2255 optdata = (void *)&pktopt->ip6po_minmtu;
2256 else
2257 optdata = (void *)&defminmtu;
2258 optdatalen = sizeof(int);
2259 break;
2260 case IPV6_DONTFRAG:
2261 if (pktopt && ((pktopt->ip6po_flags) & IP6PO_DONTFRAG))
2262 on = 1;
2263 else
2264 on = 0;
2265 optdata = (void *)&on;
2266 optdatalen = sizeof(on);
2267 break;
2268 default: /* should not happen */
2269 #ifdef DIAGNOSTIC
2270 panic("ip6_getpcbopt: unexpected option\n");
2271 #endif
2272 return (ENOPROTOOPT);
2273 }
2274
2275 error = sockopt_set(sopt, optdata, optdatalen);
2276
2277 return (error);
2278 }
2279
2280 void
2281 ip6_clearpktopts(struct ip6_pktopts *pktopt, int optname)
2282 {
2283 if (optname == -1 || optname == IPV6_PKTINFO) {
2284 if (pktopt->ip6po_pktinfo)
2285 free(pktopt->ip6po_pktinfo, M_IP6OPT);
2286 pktopt->ip6po_pktinfo = NULL;
2287 }
2288 if (optname == -1 || optname == IPV6_HOPLIMIT)
2289 pktopt->ip6po_hlim = -1;
2290 if (optname == -1 || optname == IPV6_TCLASS)
2291 pktopt->ip6po_tclass = -1;
2292 if (optname == -1 || optname == IPV6_NEXTHOP) {
2293 rtcache_free(&pktopt->ip6po_nextroute);
2294 if (pktopt->ip6po_nexthop)
2295 free(pktopt->ip6po_nexthop, M_IP6OPT);
2296 pktopt->ip6po_nexthop = NULL;
2297 }
2298 if (optname == -1 || optname == IPV6_HOPOPTS) {
2299 if (pktopt->ip6po_hbh)
2300 free(pktopt->ip6po_hbh, M_IP6OPT);
2301 pktopt->ip6po_hbh = NULL;
2302 }
2303 if (optname == -1 || optname == IPV6_RTHDRDSTOPTS) {
2304 if (pktopt->ip6po_dest1)
2305 free(pktopt->ip6po_dest1, M_IP6OPT);
2306 pktopt->ip6po_dest1 = NULL;
2307 }
2308 if (optname == -1 || optname == IPV6_RTHDR) {
2309 if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
2310 free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
2311 pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
2312 rtcache_free(&pktopt->ip6po_route);
2313 }
2314 if (optname == -1 || optname == IPV6_DSTOPTS) {
2315 if (pktopt->ip6po_dest2)
2316 free(pktopt->ip6po_dest2, M_IP6OPT);
2317 pktopt->ip6po_dest2 = NULL;
2318 }
2319 }
2320
2321 #define PKTOPT_EXTHDRCPY(type) \
2322 do { \
2323 if (src->type) { \
2324 int hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
2325 dst->type = malloc(hlen, M_IP6OPT, canwait); \
2326 if (dst->type == NULL) \
2327 goto bad; \
2328 memcpy(dst->type, src->type, hlen); \
2329 } \
2330 } while (/*CONSTCOND*/ 0)
2331
2332 static int
2333 copypktopts(struct ip6_pktopts *dst, struct ip6_pktopts *src, int canwait)
2334 {
2335 dst->ip6po_hlim = src->ip6po_hlim;
2336 dst->ip6po_tclass = src->ip6po_tclass;
2337 dst->ip6po_flags = src->ip6po_flags;
2338 if (src->ip6po_pktinfo) {
2339 dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo),
2340 M_IP6OPT, canwait);
2341 if (dst->ip6po_pktinfo == NULL)
2342 goto bad;
2343 *dst->ip6po_pktinfo = *src->ip6po_pktinfo;
2344 }
2345 if (src->ip6po_nexthop) {
2346 dst->ip6po_nexthop = malloc(src->ip6po_nexthop->sa_len,
2347 M_IP6OPT, canwait);
2348 if (dst->ip6po_nexthop == NULL)
2349 goto bad;
2350 memcpy(dst->ip6po_nexthop, src->ip6po_nexthop,
2351 src->ip6po_nexthop->sa_len);
2352 }
2353 PKTOPT_EXTHDRCPY(ip6po_hbh);
2354 PKTOPT_EXTHDRCPY(ip6po_dest1);
2355 PKTOPT_EXTHDRCPY(ip6po_dest2);
2356 PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
2357 return (0);
2358
2359 bad:
2360 if (dst->ip6po_pktinfo) free(dst->ip6po_pktinfo, M_IP6OPT);
2361 if (dst->ip6po_nexthop) free(dst->ip6po_nexthop, M_IP6OPT);
2362 if (dst->ip6po_hbh) free(dst->ip6po_hbh, M_IP6OPT);
2363 if (dst->ip6po_dest1) free(dst->ip6po_dest1, M_IP6OPT);
2364 if (dst->ip6po_dest2) free(dst->ip6po_dest2, M_IP6OPT);
2365 if (dst->ip6po_rthdr) free(dst->ip6po_rthdr, M_IP6OPT);
2366
2367 return (ENOBUFS);
2368 }
2369 #undef PKTOPT_EXTHDRCPY
2370
2371 struct ip6_pktopts *
2372 ip6_copypktopts(struct ip6_pktopts *src, int canwait)
2373 {
2374 int error;
2375 struct ip6_pktopts *dst;
2376
2377 dst = malloc(sizeof(*dst), M_IP6OPT, canwait);
2378 if (dst == NULL)
2379 return (NULL);
2380 ip6_initpktopts(dst);
2381
2382 if ((error = copypktopts(dst, src, canwait)) != 0) {
2383 free(dst, M_IP6OPT);
2384 return (NULL);
2385 }
2386
2387 return (dst);
2388 }
2389
2390 void
2391 ip6_freepcbopts(struct ip6_pktopts *pktopt)
2392 {
2393 if (pktopt == NULL)
2394 return;
2395
2396 ip6_clearpktopts(pktopt, -1);
2397
2398 free(pktopt, M_IP6OPT);
2399 }
2400
2401 /*
2402 * Set the IP6 multicast options in response to user setsockopt().
2403 */
2404 static int
2405 ip6_setmoptions(const struct sockopt *sopt, struct ip6_moptions **im6op)
2406 {
2407 int error = 0;
2408 u_int loop, ifindex;
2409 struct ipv6_mreq mreq;
2410 struct ifnet *ifp;
2411 struct ip6_moptions *im6o = *im6op;
2412 struct route ro;
2413 struct in6_multi_mship *imm;
2414 struct lwp *l = curlwp; /* XXX */
2415
2416 if (im6o == NULL) {
2417 /*
2418 * No multicast option buffer attached to the pcb;
2419 * allocate one and initialize to default values.
2420 */
2421 im6o = malloc(sizeof(*im6o), M_IPMOPTS, M_NOWAIT);
2422 if (im6o == NULL)
2423 return (ENOBUFS);
2424
2425 *im6op = im6o;
2426 im6o->im6o_multicast_ifp = NULL;
2427 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2428 im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
2429 LIST_INIT(&im6o->im6o_memberships);
2430 }
2431
2432 switch (sopt->sopt_name) {
2433
2434 case IPV6_MULTICAST_IF:
2435 /*
2436 * Select the interface for outgoing multicast packets.
2437 */
2438 error = sockopt_get(sopt, &ifindex, sizeof(ifindex));
2439 if (error != 0)
2440 break;
2441
2442 if (ifindex != 0) {
2443 if (if_indexlim <= ifindex || !ifindex2ifnet[ifindex]) {
2444 error = ENXIO; /* XXX EINVAL? */
2445 break;
2446 }
2447 ifp = ifindex2ifnet[ifindex];
2448 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
2449 error = EADDRNOTAVAIL;
2450 break;
2451 }
2452 } else
2453 ifp = NULL;
2454 im6o->im6o_multicast_ifp = ifp;
2455 break;
2456
2457 case IPV6_MULTICAST_HOPS:
2458 {
2459 /*
2460 * Set the IP6 hoplimit for outgoing multicast packets.
2461 */
2462 int optval;
2463
2464 error = sockopt_getint(sopt, &optval);
2465 if (error != 0)
2466 break;
2467
2468 if (optval < -1 || optval >= 256)
2469 error = EINVAL;
2470 else if (optval == -1)
2471 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2472 else
2473 im6o->im6o_multicast_hlim = optval;
2474 break;
2475 }
2476
2477 case IPV6_MULTICAST_LOOP:
2478 /*
2479 * Set the loopback flag for outgoing multicast packets.
2480 * Must be zero or one.
2481 */
2482 error = sockopt_get(sopt, &loop, sizeof(loop));
2483 if (error != 0)
2484 break;
2485 if (loop > 1) {
2486 error = EINVAL;
2487 break;
2488 }
2489 im6o->im6o_multicast_loop = loop;
2490 break;
2491
2492 case IPV6_JOIN_GROUP:
2493 /*
2494 * Add a multicast group membership.
2495 * Group must be a valid IP6 multicast address.
2496 */
2497 error = sockopt_get(sopt, &mreq, sizeof(mreq));
2498 if (error != 0)
2499 break;
2500
2501 if (IN6_IS_ADDR_UNSPECIFIED(&mreq.ipv6mr_multiaddr)) {
2502 /*
2503 * We use the unspecified address to specify to accept
2504 * all multicast addresses. Only super user is allowed
2505 * to do this.
2506 */
2507 if (kauth_authorize_generic(l->l_cred,
2508 KAUTH_GENERIC_ISSUSER, NULL))
2509 {
2510 error = EACCES;
2511 break;
2512 }
2513 } else if (!IN6_IS_ADDR_MULTICAST(&mreq.ipv6mr_multiaddr)) {
2514 error = EINVAL;
2515 break;
2516 }
2517
2518 /*
2519 * If no interface was explicitly specified, choose an
2520 * appropriate one according to the given multicast address.
2521 */
2522 if (mreq.ipv6mr_interface == 0) {
2523 struct rtentry *rt;
2524 union {
2525 struct sockaddr dst;
2526 struct sockaddr_in6 dst6;
2527 } u;
2528
2529 /*
2530 * Look up the routing table for the
2531 * address, and choose the outgoing interface.
2532 * XXX: is it a good approach?
2533 */
2534 memset(&ro, 0, sizeof(ro));
2535 sockaddr_in6_init(&u.dst6, &mreq.ipv6mr_multiaddr, 0,
2536 0, 0);
2537 rtcache_setdst(&ro, &u.dst);
2538 ifp = (rt = rtcache_init(&ro)) != NULL ? rt->rt_ifp
2539 : NULL;
2540 rtcache_free(&ro);
2541 } else {
2542 /*
2543 * If the interface is specified, validate it.
2544 */
2545 if (if_indexlim <= mreq.ipv6mr_interface ||
2546 !ifindex2ifnet[mreq.ipv6mr_interface]) {
2547 error = ENXIO; /* XXX EINVAL? */
2548 break;
2549 }
2550 ifp = ifindex2ifnet[mreq.ipv6mr_interface];
2551 }
2552
2553 /*
2554 * See if we found an interface, and confirm that it
2555 * supports multicast
2556 */
2557 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2558 error = EADDRNOTAVAIL;
2559 break;
2560 }
2561
2562 if (in6_setscope(&mreq.ipv6mr_multiaddr, ifp, NULL)) {
2563 error = EADDRNOTAVAIL; /* XXX: should not happen */
2564 break;
2565 }
2566
2567 /*
2568 * See if the membership already exists.
2569 */
2570 for (imm = im6o->im6o_memberships.lh_first;
2571 imm != NULL; imm = imm->i6mm_chain.le_next)
2572 if (imm->i6mm_maddr->in6m_ifp == ifp &&
2573 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2574 &mreq.ipv6mr_multiaddr))
2575 break;
2576 if (imm != NULL) {
2577 error = EADDRINUSE;
2578 break;
2579 }
2580 /*
2581 * Everything looks good; add a new record to the multicast
2582 * address list for the given interface.
2583 */
2584 imm = in6_joingroup(ifp, &mreq.ipv6mr_multiaddr, &error, 0);
2585 if (imm == NULL)
2586 break;
2587 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
2588 break;
2589
2590 case IPV6_LEAVE_GROUP:
2591 /*
2592 * Drop a multicast group membership.
2593 * Group must be a valid IP6 multicast address.
2594 */
2595 error = sockopt_get(sopt, &mreq, sizeof(mreq));
2596 if (error != 0)
2597 break;
2598
2599 /*
2600 * If an interface address was specified, get a pointer
2601 * to its ifnet structure.
2602 */
2603 if (mreq.ipv6mr_interface != 0) {
2604 if (if_indexlim <= mreq.ipv6mr_interface ||
2605 !ifindex2ifnet[mreq.ipv6mr_interface]) {
2606 error = ENXIO; /* XXX EINVAL? */
2607 break;
2608 }
2609 ifp = ifindex2ifnet[mreq.ipv6mr_interface];
2610 } else
2611 ifp = NULL;
2612
2613 /* Fill in the scope zone ID */
2614 if (ifp) {
2615 if (in6_setscope(&mreq.ipv6mr_multiaddr, ifp, NULL)) {
2616 /* XXX: should not happen */
2617 error = EADDRNOTAVAIL;
2618 break;
2619 }
2620 } else if (mreq.ipv6mr_interface != 0) {
2621 /*
2622 * XXX: This case would happens when the (positive)
2623 * index is in the valid range, but the corresponding
2624 * interface has been detached dynamically. The above
2625 * check probably avoids such case to happen here, but
2626 * we check it explicitly for safety.
2627 */
2628 error = EADDRNOTAVAIL;
2629 break;
2630 } else { /* ipv6mr_interface == 0 */
2631 struct sockaddr_in6 sa6_mc;
2632
2633 /*
2634 * The API spec says as follows:
2635 * If the interface index is specified as 0, the
2636 * system may choose a multicast group membership to
2637 * drop by matching the multicast address only.
2638 * On the other hand, we cannot disambiguate the scope
2639 * zone unless an interface is provided. Thus, we
2640 * check if there's ambiguity with the default scope
2641 * zone as the last resort.
2642 */
2643 sockaddr_in6_init(&sa6_mc, &mreq.ipv6mr_multiaddr,
2644 0, 0, 0);
2645 error = sa6_embedscope(&sa6_mc, ip6_use_defzone);
2646 if (error != 0)
2647 break;
2648 mreq.ipv6mr_multiaddr = sa6_mc.sin6_addr;
2649 }
2650
2651 /*
2652 * Find the membership in the membership list.
2653 */
2654 for (imm = im6o->im6o_memberships.lh_first;
2655 imm != NULL; imm = imm->i6mm_chain.le_next) {
2656 if ((ifp == NULL || imm->i6mm_maddr->in6m_ifp == ifp) &&
2657 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2658 &mreq.ipv6mr_multiaddr))
2659 break;
2660 }
2661 if (imm == NULL) {
2662 /* Unable to resolve interface */
2663 error = EADDRNOTAVAIL;
2664 break;
2665 }
2666 /*
2667 * Give up the multicast address record to which the
2668 * membership points.
2669 */
2670 LIST_REMOVE(imm, i6mm_chain);
2671 in6_leavegroup(imm);
2672 break;
2673
2674 default:
2675 error = EOPNOTSUPP;
2676 break;
2677 }
2678
2679 /*
2680 * If all options have default values, no need to keep the mbuf.
2681 */
2682 if (im6o->im6o_multicast_ifp == NULL &&
2683 im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
2684 im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
2685 im6o->im6o_memberships.lh_first == NULL) {
2686 free(*im6op, M_IPMOPTS);
2687 *im6op = NULL;
2688 }
2689
2690 return (error);
2691 }
2692
2693 /*
2694 * Return the IP6 multicast options in response to user getsockopt().
2695 */
2696 static int
2697 ip6_getmoptions(struct sockopt *sopt, struct ip6_moptions *im6o)
2698 {
2699 u_int optval;
2700 int error;
2701
2702 switch (sopt->sopt_name) {
2703 case IPV6_MULTICAST_IF:
2704 if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
2705 optval = 0;
2706 else
2707 optval = im6o->im6o_multicast_ifp->if_index;
2708
2709 error = sockopt_set(sopt, &optval, sizeof(optval));
2710 break;
2711
2712 case IPV6_MULTICAST_HOPS:
2713 if (im6o == NULL)
2714 optval = ip6_defmcasthlim;
2715 else
2716 optval = im6o->im6o_multicast_hlim;
2717
2718 error = sockopt_set(sopt, &optval, sizeof(optval));
2719 break;
2720
2721 case IPV6_MULTICAST_LOOP:
2722 if (im6o == NULL)
2723 optval = ip6_defmcasthlim;
2724 else
2725 optval = im6o->im6o_multicast_loop;
2726
2727 error = sockopt_set(sopt, &optval, sizeof(optval));
2728 break;
2729
2730 default:
2731 error = EOPNOTSUPP;
2732 }
2733
2734 return (error);
2735 }
2736
2737 /*
2738 * Discard the IP6 multicast options.
2739 */
2740 void
2741 ip6_freemoptions(struct ip6_moptions *im6o)
2742 {
2743 struct in6_multi_mship *imm;
2744
2745 if (im6o == NULL)
2746 return;
2747
2748 while ((imm = im6o->im6o_memberships.lh_first) != NULL) {
2749 LIST_REMOVE(imm, i6mm_chain);
2750 in6_leavegroup(imm);
2751 }
2752 free(im6o, M_IPMOPTS);
2753 }
2754
2755 /*
2756 * Set IPv6 outgoing packet options based on advanced API.
2757 */
2758 int
2759 ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
2760 struct ip6_pktopts *stickyopt, kauth_cred_t cred, int uproto)
2761 {
2762 struct cmsghdr *cm = 0;
2763
2764 if (control == NULL || opt == NULL)
2765 return (EINVAL);
2766
2767 ip6_initpktopts(opt);
2768 if (stickyopt) {
2769 int error;
2770
2771 /*
2772 * If stickyopt is provided, make a local copy of the options
2773 * for this particular packet, then override them by ancillary
2774 * objects.
2775 * XXX: copypktopts() does not copy the cached route to a next
2776 * hop (if any). This is not very good in terms of efficiency,
2777 * but we can allow this since this option should be rarely
2778 * used.
2779 */
2780 if ((error = copypktopts(opt, stickyopt, M_NOWAIT)) != 0)
2781 return (error);
2782 }
2783
2784 /*
2785 * XXX: Currently, we assume all the optional information is stored
2786 * in a single mbuf.
2787 */
2788 if (control->m_next)
2789 return (EINVAL);
2790
2791 /* XXX if cm->cmsg_len is not aligned, control->m_len can become <0 */
2792 for (; control->m_len > 0; control->m_data += CMSG_ALIGN(cm->cmsg_len),
2793 control->m_len -= CMSG_ALIGN(cm->cmsg_len)) {
2794 int error;
2795
2796 if (control->m_len < CMSG_LEN(0))
2797 return (EINVAL);
2798
2799 cm = mtod(control, struct cmsghdr *);
2800 if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
2801 return (EINVAL);
2802 if (cm->cmsg_level != IPPROTO_IPV6)
2803 continue;
2804
2805 error = ip6_setpktopt(cm->cmsg_type, CMSG_DATA(cm),
2806 cm->cmsg_len - CMSG_LEN(0), opt, cred, 0, 1, uproto);
2807 if (error)
2808 return (error);
2809 }
2810
2811 return (0);
2812 }
2813
2814 /*
2815 * Set a particular packet option, as a sticky option or an ancillary data
2816 * item. "len" can be 0 only when it's a sticky option.
2817 * We have 4 cases of combination of "sticky" and "cmsg":
2818 * "sticky=0, cmsg=0": impossible
2819 * "sticky=0, cmsg=1": RFC2292 or RFC3542 ancillary data
2820 * "sticky=1, cmsg=0": RFC3542 socket option
2821 * "sticky=1, cmsg=1": RFC2292 socket option
2822 */
2823 static int
2824 ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
2825 kauth_cred_t cred, int sticky, int cmsg, int uproto)
2826 {
2827 int minmtupolicy;
2828 int error;
2829
2830 if (!sticky && !cmsg) {
2831 #ifdef DIAGNOSTIC
2832 printf("ip6_setpktopt: impossible case\n");
2833 #endif
2834 return (EINVAL);
2835 }
2836
2837 /*
2838 * IPV6_2292xxx is for backward compatibility to RFC2292, and should
2839 * not be specified in the context of RFC3542. Conversely,
2840 * RFC3542 types should not be specified in the context of RFC2292.
2841 */
2842 if (!cmsg) {
2843 switch (optname) {
2844 case IPV6_2292PKTINFO:
2845 case IPV6_2292HOPLIMIT:
2846 case IPV6_2292NEXTHOP:
2847 case IPV6_2292HOPOPTS:
2848 case IPV6_2292DSTOPTS:
2849 case IPV6_2292RTHDR:
2850 case IPV6_2292PKTOPTIONS:
2851 return (ENOPROTOOPT);
2852 }
2853 }
2854 if (sticky && cmsg) {
2855 switch (optname) {
2856 case IPV6_PKTINFO:
2857 case IPV6_HOPLIMIT:
2858 case IPV6_NEXTHOP:
2859 case IPV6_HOPOPTS:
2860 case IPV6_DSTOPTS:
2861 case IPV6_RTHDRDSTOPTS:
2862 case IPV6_RTHDR:
2863 case IPV6_USE_MIN_MTU:
2864 case IPV6_DONTFRAG:
2865 case IPV6_OTCLASS:
2866 case IPV6_TCLASS:
2867 return (ENOPROTOOPT);
2868 }
2869 }
2870
2871 switch (optname) {
2872 #ifdef RFC2292
2873 case IPV6_2292PKTINFO:
2874 #endif
2875 case IPV6_PKTINFO:
2876 {
2877 struct ifnet *ifp = NULL;
2878 struct in6_pktinfo *pktinfo;
2879
2880 if (len != sizeof(struct in6_pktinfo))
2881 return (EINVAL);
2882
2883 pktinfo = (struct in6_pktinfo *)buf;
2884
2885 /*
2886 * An application can clear any sticky IPV6_PKTINFO option by
2887 * doing a "regular" setsockopt with ipi6_addr being
2888 * in6addr_any and ipi6_ifindex being zero.
2889 * [RFC 3542, Section 6]
2890 */
2891 if (optname == IPV6_PKTINFO && opt->ip6po_pktinfo &&
2892 pktinfo->ipi6_ifindex == 0 &&
2893 IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
2894 ip6_clearpktopts(opt, optname);
2895 break;
2896 }
2897
2898 if (uproto == IPPROTO_TCP && optname == IPV6_PKTINFO &&
2899 sticky && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
2900 return (EINVAL);
2901 }
2902
2903 /* validate the interface index if specified. */
2904 if (pktinfo->ipi6_ifindex >= if_indexlim) {
2905 return (ENXIO);
2906 }
2907 if (pktinfo->ipi6_ifindex) {
2908 ifp = ifindex2ifnet[pktinfo->ipi6_ifindex];
2909 if (ifp == NULL)
2910 return (ENXIO);
2911 }
2912
2913 /*
2914 * We store the address anyway, and let in6_selectsrc()
2915 * validate the specified address. This is because ipi6_addr
2916 * may not have enough information about its scope zone, and
2917 * we may need additional information (such as outgoing
2918 * interface or the scope zone of a destination address) to
2919 * disambiguate the scope.
2920 * XXX: the delay of the validation may confuse the
2921 * application when it is used as a sticky option.
2922 */
2923 if (opt->ip6po_pktinfo == NULL) {
2924 opt->ip6po_pktinfo = malloc(sizeof(*pktinfo),
2925 M_IP6OPT, M_NOWAIT);
2926 if (opt->ip6po_pktinfo == NULL)
2927 return (ENOBUFS);
2928 }
2929 memcpy(opt->ip6po_pktinfo, pktinfo, sizeof(*pktinfo));
2930 break;
2931 }
2932
2933 #ifdef RFC2292
2934 case IPV6_2292HOPLIMIT:
2935 #endif
2936 case IPV6_HOPLIMIT:
2937 {
2938 int *hlimp;
2939
2940 /*
2941 * RFC 3542 deprecated the usage of sticky IPV6_HOPLIMIT
2942 * to simplify the ordering among hoplimit options.
2943 */
2944 if (optname == IPV6_HOPLIMIT && sticky)
2945 return (ENOPROTOOPT);
2946
2947 if (len != sizeof(int))
2948 return (EINVAL);
2949 hlimp = (int *)buf;
2950 if (*hlimp < -1 || *hlimp > 255)
2951 return (EINVAL);
2952
2953 opt->ip6po_hlim = *hlimp;
2954 break;
2955 }
2956
2957 case IPV6_OTCLASS:
2958 if (len != sizeof(u_int8_t))
2959 return (EINVAL);
2960
2961 opt->ip6po_tclass = *(u_int8_t *)buf;
2962 break;
2963
2964 case IPV6_TCLASS:
2965 {
2966 int tclass;
2967
2968 if (len != sizeof(int))
2969 return (EINVAL);
2970 tclass = *(int *)buf;
2971 if (tclass < -1 || tclass > 255)
2972 return (EINVAL);
2973
2974 opt->ip6po_tclass = tclass;
2975 break;
2976 }
2977
2978 #ifdef RFC2292
2979 case IPV6_2292NEXTHOP:
2980 #endif
2981 case IPV6_NEXTHOP:
2982 error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
2983 NULL);
2984 if (error)
2985 return (error);
2986
2987 if (len == 0) { /* just remove the option */
2988 ip6_clearpktopts(opt, IPV6_NEXTHOP);
2989 break;
2990 }
2991
2992 /* check if cmsg_len is large enough for sa_len */
2993 if (len < sizeof(struct sockaddr) || len < *buf)
2994 return (EINVAL);
2995
2996 switch (((struct sockaddr *)buf)->sa_family) {
2997 case AF_INET6:
2998 {
2999 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)buf;
3000
3001 if (sa6->sin6_len != sizeof(struct sockaddr_in6))
3002 return (EINVAL);
3003
3004 if (IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr) ||
3005 IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) {
3006 return (EINVAL);
3007 }
3008 if ((error = sa6_embedscope(sa6, ip6_use_defzone))
3009 != 0) {
3010 return (error);
3011 }
3012 break;
3013 }
3014 case AF_LINK: /* eventually be supported? */
3015 default:
3016 return (EAFNOSUPPORT);
3017 }
3018
3019 /* turn off the previous option, then set the new option. */
3020 ip6_clearpktopts(opt, IPV6_NEXTHOP);
3021 opt->ip6po_nexthop = malloc(*buf, M_IP6OPT, M_NOWAIT);
3022 if (opt->ip6po_nexthop == NULL)
3023 return (ENOBUFS);
3024 memcpy(opt->ip6po_nexthop, buf, *buf);
3025 break;
3026
3027 #ifdef RFC2292
3028 case IPV6_2292HOPOPTS:
3029 #endif
3030 case IPV6_HOPOPTS:
3031 {
3032 struct ip6_hbh *hbh;
3033 int hbhlen;
3034
3035 /*
3036 * XXX: We don't allow a non-privileged user to set ANY HbH
3037 * options, since per-option restriction has too much
3038 * overhead.
3039 */
3040 error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
3041 NULL);
3042 if (error)
3043 return (error);
3044
3045 if (len == 0) {
3046 ip6_clearpktopts(opt, IPV6_HOPOPTS);
3047 break; /* just remove the option */
3048 }
3049
3050 /* message length validation */
3051 if (len < sizeof(struct ip6_hbh))
3052 return (EINVAL);
3053 hbh = (struct ip6_hbh *)buf;
3054 hbhlen = (hbh->ip6h_len + 1) << 3;
3055 if (len != hbhlen)
3056 return (EINVAL);
3057
3058 /* turn off the previous option, then set the new option. */
3059 ip6_clearpktopts(opt, IPV6_HOPOPTS);
3060 opt->ip6po_hbh = malloc(hbhlen, M_IP6OPT, M_NOWAIT);
3061 if (opt->ip6po_hbh == NULL)
3062 return (ENOBUFS);
3063 memcpy(opt->ip6po_hbh, hbh, hbhlen);
3064
3065 break;
3066 }
3067
3068 #ifdef RFC2292
3069 case IPV6_2292DSTOPTS:
3070 #endif
3071 case IPV6_DSTOPTS:
3072 case IPV6_RTHDRDSTOPTS:
3073 {
3074 struct ip6_dest *dest, **newdest = NULL;
3075 int destlen;
3076
3077 /* XXX: see the comment for IPV6_HOPOPTS */
3078 error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
3079 NULL);
3080 if (error)
3081 return (error);
3082
3083 if (len == 0) {
3084 ip6_clearpktopts(opt, optname);
3085 break; /* just remove the option */
3086 }
3087
3088 /* message length validation */
3089 if (len < sizeof(struct ip6_dest))
3090 return (EINVAL);
3091 dest = (struct ip6_dest *)buf;
3092 destlen = (dest->ip6d_len + 1) << 3;
3093 if (len != destlen)
3094 return (EINVAL);
3095 /*
3096 * Determine the position that the destination options header
3097 * should be inserted; before or after the routing header.
3098 */
3099 switch (optname) {
3100 case IPV6_2292DSTOPTS:
3101 /*
3102 * The old advanced API is ambiguous on this point.
3103 * Our approach is to determine the position based
3104 * according to the existence of a routing header.
3105 * Note, however, that this depends on the order of the
3106 * extension headers in the ancillary data; the 1st
3107 * part of the destination options header must appear
3108 * before the routing header in the ancillary data,
3109 * too.
3110 * RFC3542 solved the ambiguity by introducing
3111 * separate ancillary data or option types.
3112 */
3113 if (opt->ip6po_rthdr == NULL)
3114 newdest = &opt->ip6po_dest1;
3115 else
3116 newdest = &opt->ip6po_dest2;
3117 break;
3118 case IPV6_RTHDRDSTOPTS:
3119 newdest = &opt->ip6po_dest1;
3120 break;
3121 case IPV6_DSTOPTS:
3122 newdest = &opt->ip6po_dest2;
3123 break;
3124 }
3125
3126 /* turn off the previous option, then set the new option. */
3127 ip6_clearpktopts(opt, optname);
3128 *newdest = malloc(destlen, M_IP6OPT, M_NOWAIT);
3129 if (*newdest == NULL)
3130 return (ENOBUFS);
3131 memcpy(*newdest, dest, destlen);
3132
3133 break;
3134 }
3135
3136 #ifdef RFC2292
3137 case IPV6_2292RTHDR:
3138 #endif
3139 case IPV6_RTHDR:
3140 {
3141 struct ip6_rthdr *rth;
3142 int rthlen;
3143
3144 if (len == 0) {
3145 ip6_clearpktopts(opt, IPV6_RTHDR);
3146 break; /* just remove the option */
3147 }
3148
3149 /* message length validation */
3150 if (len < sizeof(struct ip6_rthdr))
3151 return (EINVAL);
3152 rth = (struct ip6_rthdr *)buf;
3153 rthlen = (rth->ip6r_len + 1) << 3;
3154 if (len != rthlen)
3155 return (EINVAL);
3156 switch (rth->ip6r_type) {
3157 case IPV6_RTHDR_TYPE_0:
3158 if (rth->ip6r_len == 0) /* must contain one addr */
3159 return (EINVAL);
3160 if (rth->ip6r_len % 2) /* length must be even */
3161 return (EINVAL);
3162 if (rth->ip6r_len / 2 != rth->ip6r_segleft)
3163 return (EINVAL);
3164 break;
3165 default:
3166 return (EINVAL); /* not supported */
3167 }
3168 /* turn off the previous option */
3169 ip6_clearpktopts(opt, IPV6_RTHDR);
3170 opt->ip6po_rthdr = malloc(rthlen, M_IP6OPT, M_NOWAIT);
3171 if (opt->ip6po_rthdr == NULL)
3172 return (ENOBUFS);
3173 memcpy(opt->ip6po_rthdr, rth, rthlen);
3174 break;
3175 }
3176
3177 case IPV6_USE_MIN_MTU:
3178 if (len != sizeof(int))
3179 return (EINVAL);
3180 minmtupolicy = *(int *)buf;
3181 if (minmtupolicy != IP6PO_MINMTU_MCASTONLY &&
3182 minmtupolicy != IP6PO_MINMTU_DISABLE &&
3183 minmtupolicy != IP6PO_MINMTU_ALL) {
3184 return (EINVAL);
3185 }
3186 opt->ip6po_minmtu = minmtupolicy;
3187 break;
3188
3189 case IPV6_DONTFRAG:
3190 if (len != sizeof(int))
3191 return (EINVAL);
3192
3193 if (uproto == IPPROTO_TCP || *(int *)buf == 0) {
3194 /*
3195 * we ignore this option for TCP sockets.
3196 * (RFC3542 leaves this case unspecified.)
3197 */
3198 opt->ip6po_flags &= ~IP6PO_DONTFRAG;
3199 } else
3200 opt->ip6po_flags |= IP6PO_DONTFRAG;
3201 break;
3202
3203 default:
3204 return (ENOPROTOOPT);
3205 } /* end of switch */
3206
3207 return (0);
3208 }
3209
3210 /*
3211 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
3212 * packet to the input queue of a specified interface. Note that this
3213 * calls the output routine of the loopback "driver", but with an interface
3214 * pointer that might NOT be lo0ifp -- easier than replicating that code here.
3215 */
3216 void
3217 ip6_mloopback(struct ifnet *ifp, struct mbuf *m,
3218 const struct sockaddr_in6 *dst)
3219 {
3220 struct mbuf *copym;
3221 struct ip6_hdr *ip6;
3222
3223 copym = m_copy(m, 0, M_COPYALL);
3224 if (copym == NULL)
3225 return;
3226
3227 /*
3228 * Make sure to deep-copy IPv6 header portion in case the data
3229 * is in an mbuf cluster, so that we can safely override the IPv6
3230 * header portion later.
3231 */
3232 if ((copym->m_flags & M_EXT) != 0 ||
3233 copym->m_len < sizeof(struct ip6_hdr)) {
3234 copym = m_pullup(copym, sizeof(struct ip6_hdr));
3235 if (copym == NULL)
3236 return;
3237 }
3238
3239 #ifdef DIAGNOSTIC
3240 if (copym->m_len < sizeof(*ip6)) {
3241 m_freem(copym);
3242 return;
3243 }
3244 #endif
3245
3246 ip6 = mtod(copym, struct ip6_hdr *);
3247 /*
3248 * clear embedded scope identifiers if necessary.
3249 * in6_clearscope will touch the addresses only when necessary.
3250 */
3251 in6_clearscope(&ip6->ip6_src);
3252 in6_clearscope(&ip6->ip6_dst);
3253
3254 (void)looutput(ifp, copym, (const struct sockaddr *)dst, NULL);
3255 }
3256
3257 /*
3258 * Chop IPv6 header off from the payload.
3259 */
3260 static int
3261 ip6_splithdr(struct mbuf *m, struct ip6_exthdrs *exthdrs)
3262 {
3263 struct mbuf *mh;
3264 struct ip6_hdr *ip6;
3265
3266 ip6 = mtod(m, struct ip6_hdr *);
3267 if (m->m_len > sizeof(*ip6)) {
3268 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
3269 if (mh == 0) {
3270 m_freem(m);
3271 return ENOBUFS;
3272 }
3273 M_MOVE_PKTHDR(mh, m);
3274 MH_ALIGN(mh, sizeof(*ip6));
3275 m->m_len -= sizeof(*ip6);
3276 m->m_data += sizeof(*ip6);
3277 mh->m_next = m;
3278 m = mh;
3279 m->m_len = sizeof(*ip6);
3280 bcopy((void *)ip6, mtod(m, void *), sizeof(*ip6));
3281 }
3282 exthdrs->ip6e_ip6 = m;
3283 return 0;
3284 }
3285
3286 /*
3287 * Compute IPv6 extension header length.
3288 */
3289 int
3290 ip6_optlen(struct in6pcb *in6p)
3291 {
3292 int len;
3293
3294 if (!in6p->in6p_outputopts)
3295 return 0;
3296
3297 len = 0;
3298 #define elen(x) \
3299 (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
3300
3301 len += elen(in6p->in6p_outputopts->ip6po_hbh);
3302 len += elen(in6p->in6p_outputopts->ip6po_dest1);
3303 len += elen(in6p->in6p_outputopts->ip6po_rthdr);
3304 len += elen(in6p->in6p_outputopts->ip6po_dest2);
3305 return len;
3306 #undef elen
3307 }
3308