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