1 //==========================================================================
3 // src/sys/netinet6/ip6_output.c
5 //==========================================================================
6 //####BSDCOPYRIGHTBEGIN####
8 // -------------------------------------------
10 // Portions of this software may have been derived from OpenBSD,
11 // FreeBSD or other sources, and are covered by the appropriate
12 // copyright disclaimers included herein.
14 // Portions created by Red Hat are
15 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
17 // -------------------------------------------
19 //####BSDCOPYRIGHTEND####
20 //==========================================================================
22 /* $KAME: ip6_output.c,v 1.272 2001/12/26 01:03:28 jinmei Exp $ */
25 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
26 * All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. Neither the name of the project nor the names of its contributors
37 * may be used to endorse or promote products derived from this software
38 * without specific prior written permission.
40 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * Copyright (c) 1982, 1986, 1988, 1990, 1993
55 * The Regents of the University of California. All rights reserved.
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
88 #include <sys/param.h>
89 #include <sys/malloc.h>
91 #include <sys/errno.h>
92 #include <sys/protosw.h>
93 #include <sys/socket.h>
94 #include <sys/socketvar.h>
97 #include <net/route.h>
99 #include <netinet/in.h>
100 #include <netinet/in_var.h>
101 #include <netinet6/in6_var.h>
102 #include <netinet/ip6.h>
103 #include <netinet/icmp6.h>
104 #include <netinet6/ip6_var.h>
105 #include <netinet/in_pcb.h>
106 #include <netinet6/nd6.h>
107 #include <netinet6/ip6protosw.h>
108 #include <netinet6/scope6_var.h>
112 #include <netinet/ip_ah.h>
113 #include <netinet/ip_esp.h>
114 #include <netinet/udp.h>
115 #include <netinet/tcp.h>
116 #include <net/pfkeyv2.h>
118 extern u_int8_t get_sa_require __P((struct inpcb *));
120 extern int ipsec_auth_default_level;
121 extern int ipsec_esp_trans_default_level;
122 extern int ipsec_esp_network_default_level;
123 extern int ipsec_ipcomp_default_level;
125 #include <netinet6/ipsec.h>
126 #include <netkey/key.h>
130 #if defined(IPV6FIREWALL) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
131 #include <netinet6/ip6_fw.h>
135 #include <sys/syslog.h>
136 #include <netinet6/mip6.h>
140 struct mbuf *ip6e_ip6;
141 struct mbuf *ip6e_hbh;
142 struct mbuf *ip6e_dest1;
143 struct mbuf *ip6e_rthdr;
144 struct mbuf *ip6e_haddr; /* for MIP6 */
145 struct mbuf *ip6e_dest2;
148 static int ip6_pcbopt __P((int, u_char *, int, struct ip6_pktopts **, int));
149 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
150 static int ip6_pcbopts __P((struct ip6_pktopts **, struct mbuf *,
151 struct socket *, struct sockopt *));
152 static int ip6_getpcbopt __P((struct ip6_pktopts *, int, struct sockopt *));
154 static int ip6_pcbopts __P((struct ip6_pktopts **, struct mbuf *,
156 static int ip6_getpcbopt __P((struct ip6_pktopts *, int, struct mbuf **));
158 static int ip6_setpktoption __P((int, u_char *, int, struct ip6_pktopts *, int,
160 static int ip6_setmoptions __P((int, struct ip6_moptions **, struct mbuf *));
161 static int ip6_getmoptions __P((int, struct ip6_moptions *, struct mbuf **));
162 static int ip6_copyexthdr __P((struct mbuf **, caddr_t, int));
163 static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int,
164 struct ip6_frag **));
165 static int ip6_insert_jumboopt __P((struct ip6_exthdrs *, u_int32_t));
166 static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
167 #ifdef NEW_STRUCT_ROUTE
168 static int ip6_getpmtu __P((struct route *, struct route *, struct ifnet *,
169 struct in6_addr *, u_long *));
171 static int ip6_getpmtu __P((struct route *, struct route *, struct ifnet *,
172 struct in6_addr *, u_long *));
176 #if _BSDI_VERSION < 199802
177 extern struct ifnet loif;
179 extern struct ifnet *loifp;
182 #if defined(__NetBSD__)
183 extern struct ifnet loif[NLOOP];
188 * IP6 output. The packet in mbuf chain m contains a skeletal IP6
189 * header (with pri, len, nxt, hlim, src, dst).
190 * This function may modify ver and hlim only.
191 * The mbuf chain containing the packet will be freed.
192 * The mbuf opt, if present, will not be freed.
194 * type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and
195 * nd_ifinfo.linkmtu is u_int32_t. so we use u_long to hold largest one,
196 * which is rt_rmx.rmx_mtu.
199 ip6_output(m0, opt, ro, flags, im6o, ifpp)
201 struct ip6_pktopts *opt;
202 #ifdef NEW_STRUCT_ROUTE
205 struct route_in6 *ro;
208 struct ip6_moptions *im6o;
209 struct ifnet **ifpp; /* XXX: just for statistics */
211 struct ip6_hdr *ip6, *mhip6;
212 struct ifnet *ifp, *origifp;
214 int hlen, tlen, len, off;
215 #ifdef NEW_STRUCT_ROUTE
216 struct route ip6route;
218 struct route_in6 ip6route;
220 struct rtentry *rt = NULL;
221 struct sockaddr_in6 *dst;
223 struct in6_ifaddr *ia = NULL;
225 u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
226 struct ip6_exthdrs exthdrs;
227 struct in6_addr finaldst;
228 #ifdef NEW_STRUCT_ROUTE
229 struct route *ro_pmtu = NULL;
231 struct route_in6 *ro_pmtu = NULL;
239 #if defined(__NetBSD__) && defined(PFIL_HOOKS)
240 struct packet_filter_hook *pfh;
243 #endif /* PFIL_HOOKS */
244 #if defined(__bsdi__) && _BSDI_VERSION < 199802
245 struct ifnet *loifp = &loif;
248 struct mip6_pktopts mip6opt;
249 #ifdef NEW_STRUCT_ROUTE
250 struct route mip6_ip6route;
252 struct route_in6 mip6_ip6route;
258 union sockaddr_union sdst;
259 struct tdb_ident *tdbi;
265 inp = NULL; /* XXX */
266 if (inp && (inp->inp_flags & INP_IPV6) == 0)
267 panic("ip6_output: IPv4 pcb is passed");
269 int needipsectun = 0;
271 struct secpolicy *sp = NULL;
273 /* for AH processing. stupid to have "socket" variable in IP layer... */
274 so = ipsec_getsocket(m);
275 (void)ipsec_setsocket(m, NULL);
276 ip6 = mtod(m, struct ip6_hdr *);
280 #define MAKE_EXTHDR(hp, mp) \
283 struct ip6_ext *eh = (struct ip6_ext *)(hp); \
284 error = ip6_copyexthdr((mp), (caddr_t)(hp), \
285 ((eh)->ip6e_len + 1) << 3); \
291 bzero(&exthdrs, sizeof(exthdrs));
294 /* Hop-by-Hop options header */
295 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
296 /* Destination options header(1st part) */
297 if (opt->ip6po_rthdr) {
299 * Destination options header(1st part)
300 * This only makes sence with a routing header.
302 * draft-ietf-ipngwg-rfc2292bis-02.txt.
303 * Disabling this part just for MIP6 convenience is
304 * a bad idea. We need to think carefully about a
305 * way to make the advanced API coexist with MIP6
306 * options, which might automatically be inserted in
309 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
312 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
313 /* Destination options header(2nd part) */
314 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
317 bzero((caddr_t)&mip6opt, sizeof(mip6opt));
318 if ((flags & IPV6_FORWARDING) == 0) {
320 * XXX: reconsider the following routine.
323 * MIP6 extention headers handling.
324 * insert HA, BU, BA, BR options if necessary.
326 if (mip6_exthdr_create(m, opt, &mip6opt))
329 if (((opt != NULL) && (opt->ip6po_rthdr != NULL))
330 || (mip6opt.mip6po_rthdr != NULL)) {
331 m_freem(exthdrs.ip6e_rthdr);
332 if (mip6opt.mip6po_rthdr != NULL) {
334 * there is no rthdr specified in the
335 * ip6_pktopts. but mip6 create a
336 * rthdr for the router optimization
339 MAKE_EXTHDR(mip6opt.mip6po_rthdr,
340 &exthdrs.ip6e_rthdr);
343 * there is a rthdr specified in the
344 * ip6_pktopts. if mip6 require the
345 * route optimization, the rthdr for
346 * that purpose is already included in
347 * the ip6po_rthdr in the
348 * mip6_destopt_create().
350 MAKE_EXTHDR(opt->ip6po_rthdr,
351 &exthdrs.ip6e_rthdr);
354 * if a routing header exists dest1 must be
355 * inserted if it exists.
357 if ((opt != NULL) && (opt->ip6po_dest1)) {
358 m_freem(exthdrs.ip6e_dest1);
359 MAKE_EXTHDR(opt->ip6po_dest1,
360 &exthdrs.ip6e_dest1);
363 MAKE_EXTHDR(mip6opt.mip6po_haddr, &exthdrs.ip6e_haddr);
364 if (mip6opt.mip6po_dest2) {
365 m_freem(exthdrs.ip6e_dest2);
366 MAKE_EXTHDR(mip6opt.mip6po_dest2, &exthdrs.ip6e_dest2);
370 * this is the forwarding packet. do not modify any
379 * splnet is chosen over spltdb because we are not allowed to
380 * lower the level, and udp6_output calls us in splnet(). XXX check
385 * Check if there was an outgoing SA bound to the flow
386 * from a transport protocol.
388 ip6 = mtod(m, struct ip6_hdr *);
390 /* Do we have any pending SAs to apply ? */
391 mtag = m_tag_find(m, PACKET_TAG_IPSEC_PENDING_TDB, NULL);
394 if (mtag->m_tag_len != sizeof (struct tdb_ident))
395 panic("ip6_output: tag of length %d (should be %d",
396 mtag->m_tag_len, sizeof (struct tdb_ident));
398 tdbi = (struct tdb_ident *)(mtag + 1);
399 tdb = gettdb(tdbi->spi, &tdbi->dst, tdbi->proto);
402 m_tag_delete(m, mtag);
405 tdb = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
406 &error, IPSP_DIRECTION_OUT, NULL, inp);
413 * No IPsec processing required, we'll just send the
418 /* Fall through to routing/multicast handling */
421 * -EINVAL is used to indicate that the packet should
422 * be silently dropped, typically because we've asked
423 * key management for an SA.
425 if (error == -EINVAL) /* Should silently drop packet */
432 for (mtag = m_tag_first(m); mtag != NULL;
433 mtag = m_tag_next(m, mtag)) {
434 if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE &&
436 PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED)
438 tdbi = (struct tdb_ident *)(mtag + 1);
439 if (tdbi->spi == tdb->tdb_spi &&
440 tdbi->proto == tdb->tdb_sproto &&
441 !bcmp(&tdbi->dst, &tdb->tdb_dst,
442 sizeof(union sockaddr_union))) {
444 sproto = 0; /* mark as no-IPsec-needed */
449 /* We need to do IPsec */
450 bcopy(&tdb->tdb_dst, &sdst, sizeof(sdst));
452 sproto = tdb->tdb_sproto;
456 /* if we have any extension header, we cannot perform IPsec */
457 if (exthdrs.ip6e_hbh || exthdrs.ip6e_dest1 ||
459 exthdrs.ip6e_haddr ||
461 exthdrs.ip6e_rthdr || exthdrs.ip6e_dest2) {
462 error = EHOSTUNREACH;
468 /* Fall through to the routing/multicast handling code */
471 /* get a security policy for this packet */
473 sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
475 sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
478 ipsec6stat.out_inval++;
485 switch (sp->policy) {
486 case IPSEC_POLICY_DISCARD:
488 * This packet is just discarded.
490 ipsec6stat.out_polvio++;
493 case IPSEC_POLICY_BYPASS:
494 case IPSEC_POLICY_NONE:
495 /* no need to do IPsec. */
499 case IPSEC_POLICY_IPSEC:
500 if (sp->req == NULL) {
501 /* acquire a policy */
502 error = key_spdacquire(sp);
508 case IPSEC_POLICY_ENTRUST:
510 printf("ip6_output: Invalid policy found. %d\n", sp->policy);
516 * Calculate the total length of the extension header chain.
517 * Keep the length of the unfragmentable part for fragmentation.
520 if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
521 if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
522 if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
524 if (exthdrs.ip6e_haddr) optlen += exthdrs.ip6e_haddr->m_len;
526 unfragpartlen = optlen + sizeof(struct ip6_hdr);
527 /* NOTE: we don't add AH/ESP length here. do that later. */
528 if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
531 * If we need IPsec, or there is at least one extension header,
532 * separate IP6 header from the payload.
535 if ((sproto || optlen) && !hdrsplit)
537 if ((needipsec || optlen) && !hdrsplit)
540 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
544 m = exthdrs.ip6e_ip6;
549 ip6 = mtod(m, struct ip6_hdr *);
551 /* adjust mbuf packet header length */
552 m->m_pkthdr.len += optlen;
553 plen = m->m_pkthdr.len - sizeof(*ip6);
555 /* If this is a jumbo payload, insert a jumbo payload option. */
556 if (plen > IPV6_MAXPACKET) {
558 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
562 m = exthdrs.ip6e_ip6;
566 ip6 = mtod(m, struct ip6_hdr *);
567 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
571 ip6->ip6_plen = htons(plen);
574 * Concatenate headers and fill in next header fields.
575 * Here we have, on "m"
577 * and we insert headers accordingly. Finally, we should be getting:
578 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
580 * during the header composing process, "m" points to IPv6 header.
581 * "mprev" points to an extension header prior to esp.
584 u_char *nexthdrp = &ip6->ip6_nxt;
585 struct mbuf *mprev = m;
588 * we treat dest2 specially. this makes IPsec processing
589 * much easier. the goal here is to make mprev point the
590 * mbuf prior to dest2.
592 * result: IPv6 dest2 payload
593 * m and mprev will point to IPv6 header.
595 if (exthdrs.ip6e_dest2) {
597 panic("assumption failed: hdr not split");
598 exthdrs.ip6e_dest2->m_next = m->m_next;
599 m->m_next = exthdrs.ip6e_dest2;
600 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
601 ip6->ip6_nxt = IPPROTO_DSTOPTS;
604 #define MAKE_CHAIN(m, mp, p, i)\
608 panic("assumption failed: hdr not split"); \
609 *mtod((m), u_char *) = *(p);\
611 p = mtod((m), u_char *);\
612 (m)->m_next = (mp)->m_next;\
618 * result: IPv6 hbh dest1 rthdr dest2 payload
619 * m will point to IPv6 header. mprev will point to the
620 * extension header prior to dest2 (rthdr in the above case).
622 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev,
623 nexthdrp, IPPROTO_HOPOPTS);
624 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev,
625 nexthdrp, IPPROTO_DSTOPTS);
626 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev,
627 nexthdrp, IPPROTO_ROUTING);
631 * MIP6 homeaddress destination option must reside
632 * after rthdr and before ah/esp/frag hdr.
633 * this order is not recommended in the ipv6 spec of course.
634 * result: IPv6 hbh dest1 rthdr ha dest2 payload.
636 MAKE_CHAIN(exthdrs.ip6e_haddr, mprev,
637 nexthdrp, IPPROTO_DSTOPTS);
640 #if defined(IPSEC) && !defined(__OpenBSD__)
645 * pointers after IPsec headers are not valid any more.
646 * other pointers need a great care too.
647 * (IPsec routines should not mangle mbufs prior to AH/ESP)
649 exthdrs.ip6e_dest2 = NULL;
652 struct ip6_rthdr *rh = NULL;
654 struct ipsec_output_state state;
656 if (exthdrs.ip6e_rthdr) {
657 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
658 segleft_org = rh->ip6r_segleft;
659 rh->ip6r_segleft = 0;
662 bzero(&state, sizeof(state));
664 error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
668 /* mbuf is already reclaimed in ipsec6_output_trans. */
678 printf("ip6_output (ipsec): error code %d\n", error);
681 /* don't show these error codes to the user */
687 if (exthdrs.ip6e_rthdr) {
688 /* ah6_output doesn't modify mbuf chain */
689 rh->ip6r_segleft = segleft_org;
697 if ((flags & IPV6_FORWARDING) == 0) {
699 * After the IPsec processing the IPv6 header source
700 * address (this is the homeaddress of this node) and
701 * the address currently stored in the Home Address
702 * destination option (this is the coa of this node)
705 if ((error = mip6_addr_exchange(m, exthdrs.ip6e_haddr)) != 0) {
708 "addr exchange between haddr and "
710 __FILE__, __LINE__));
715 * this is the forwarding packet. The typical (and
716 * only ?) case is multicast packet forwarding. The
717 * swapping has been already done before (if
718 * necessary). we must not touch any extension
725 * If there is a routing header, replace destination address field
726 * with the first hop of the routing header.
728 if (exthdrs.ip6e_rthdr) {
729 struct ip6_rthdr *rh =
730 (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
731 struct ip6_rthdr *));
732 struct ip6_rthdr0 *rh0;
733 struct in6_addr *addr;
735 finaldst = ip6->ip6_dst;
736 switch (rh->ip6r_type) {
737 case IPV6_RTHDR_TYPE_0:
738 rh0 = (struct ip6_rthdr0 *)rh;
739 addr = (struct in6_addr *)(rh0 + 1);
741 ip6->ip6_dst = *addr;
742 bcopy((caddr_t)(addr + 1), (caddr_t)addr,
743 sizeof(struct in6_addr) * (rh0->ip6r0_segleft - 1)
745 *(addr + rh0->ip6r0_segleft - 1) = finaldst;
747 default: /* is it possible? */
753 /* Source address validation */
754 if (!(flags & IPV6_UNSPECSRC) &&
755 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
757 * XXX: we can probably assume validation in the caller, but
758 * we explicitly check the address here for safety.
761 ip6stat.ip6s_badscope++;
764 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
766 ip6stat.ip6s_badscope++;
770 ip6stat.ip6s_localout++;
777 bzero((caddr_t)ro, sizeof(*ro));
780 if (opt && opt->ip6po_rthdr)
781 ro = &opt->ip6po_route;
783 else if (exthdrs.ip6e_rthdr) {
784 struct sockaddr_in6 *firsthop;
786 = mtod(m, struct ip6_hdr *); /* needed ? */;
789 bzero((caddr_t)ro, sizeof(*ro));
790 firsthop = (struct sockaddr_in6 *)&ro->ro_dst;
791 bzero(firsthop, sizeof(*firsthop));
792 firsthop->sin6_family = AF_INET6;
793 firsthop->sin6_len = sizeof(struct sockaddr_in6);
794 firsthop->sin6_addr = ip6->ip6_dst;
797 dst = (struct sockaddr_in6 *)&ro->ro_dst;
802 * Check if the packet needs encapsulation.
803 * ipsp_process_packet will never come back to here.
808 /* fill in IPv6 header which would be filled later */
809 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
810 if (opt && opt->ip6po_hlim != -1)
811 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
814 ip6->ip6_hlim = im6o->im6o_multicast_hlim;
816 ip6->ip6_hlim = ip6_defmcasthlim;
817 if (opt && opt->ip6po_hlim != -1)
818 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
821 * XXX what should we do if ip6_hlim == 0 and the packet
826 tdb = gettdb(sspi, &sdst, sproto);
829 error = EHOSTUNREACH;
836 tdb_add_inp(tdb, inp, 0);
838 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
840 /* Callee frees mbuf */
841 error = ipsp_process_packet(m, tdb, AF_INET6, 0);
844 return error; /* Nothing more to be done */
847 if (needipsec && needipsectun) {
848 struct ipsec_output_state state;
851 * All the extension headers will become inaccessible
852 * (since they can be encrypted).
853 * Don't panic, we need no more updates to extension headers
854 * on inner IPv6 packet (since they are now encapsulated).
856 * IPv6 [ESP|AH] IPv6 [extension headers] payload
858 bzero(&exthdrs, sizeof(exthdrs));
859 exthdrs.ip6e_ip6 = m;
861 bzero(&state, sizeof(state));
863 state.ro = (struct route *)ro;
864 state.dst = (struct sockaddr *)dst;
866 error = ipsec6_output_tunnel(&state, sp, flags);
869 #ifdef NEW_STRUCT_ROUTE
872 ro = (struct route_in6 *)state.ro;
874 dst = (struct sockaddr_in6 *)state.dst;
876 /* mbuf is already reclaimed in ipsec6_output_tunnel. */
887 printf("ip6_output (ipsec): error code %d\n", error);
890 /* don't show these error codes to the user */
897 exthdrs.ip6e_ip6 = m;
902 /* if specified, fill in the traffic class field. */
904 ip6->ip6_flow &= ~htonl(0xff << 20);
905 if (opt->ip6po_tclass >= 0)
907 htonl((opt->ip6po_tclass & 0xff) << 20);
909 /* fill in or override the hop limit field, if necessary. */
910 if (opt && opt->ip6po_hlim != -1)
911 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
912 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
914 ip6->ip6_hlim = im6o->im6o_multicast_hlim;
916 ip6->ip6_hlim = ip6_defmcasthlim;
921 * XXX: using a block just to define a local variables is not
924 struct ifnet *ifp0 = NULL;
925 struct sockaddr_in6 src;
926 struct sockaddr_in6 dst0;
931 * XXX: sockaddr_in6 for the destination should be passed
932 * from the upper layer with a proper scope zone ID, in order
933 * to make a copy here.
935 bzero(&dst0, sizeof(dst0));
936 dst0.sin6_family = AF_INET6;
937 dst0.sin6_len = sizeof(dst0);
938 dst0.sin6_addr = ip6->ip6_dst;
940 /* XXX: in6_recoverscope will clear the embedded ID */
941 error = in6_recoverscope(&dst0, &dst0.sin6_addr, NULL);
943 ip6stat.ip6s_badscope++;
944 in6_ifstat_inc(ifp, ifs6_out_discard);
949 #if defined(__bsdi__) || defined(__FreeBSD__)
950 if (ro != &ip6route && !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
954 if ((error = in6_selectroute(&dst0, opt, im6o, ro,
955 &ifp, &rt, clone)) != 0) {
958 ip6stat.ip6s_noroute++;
962 break; /* XXX statistics? */
965 in6_ifstat_inc(ifp, ifs6_out_discard);
970 * If in6_selectroute() does not return a route entry,
971 * dst may not have been updated.
973 *dst = dst0; /* XXX */
977 * then rt (for unicast) and ifp must be non-NULL valid values.
979 if ((flags & IPV6_FORWARDING) == 0) {
980 /* XXX: the FORWARDING flag can be set for mrouting. */
981 in6_ifstat_inc(ifp, ifs6_out_request);
984 ia = (struct in6_ifaddr *)(rt->rt_ifa);
989 * The outgoing interface must be in the zone of source and
990 * destination addresses. We should use ia_ifp to support the
991 * case of sending packets to an address of our own.
993 if (ia != NULL && ia->ia_ifp)
997 /* XXX: we should not do this conversion for every packet. */
998 bzero(&src, sizeof(src));
999 src.sin6_family = AF_INET6;
1000 src.sin6_len = sizeof(src);
1001 src.sin6_addr = ip6->ip6_src;
1002 if ((error = in6_recoverscope(&src, &ip6->ip6_src, NULL))
1006 if ((zone = in6_addr2zoneid(ifp0, &src.sin6_addr)) < 0 ||
1007 zone != src.sin6_scope_id) {
1008 #ifdef SCOPEDEBUG /* will be removed shortly */
1009 printf("ip6 output: bad source scope %s for %s on %s\n",
1010 ip6_sprintf(&ip6->ip6_src),
1011 ip6_sprintf(&ip6->ip6_dst), if_name(ifp0));
1015 /* XXX: in6_recoverscope will clear the embedded ID */
1016 if ((error = in6_recoverscope(&dst0, &ip6->ip6_dst, NULL))
1020 if ((zone = in6_addr2zoneid(ifp0, &dst0.sin6_addr)) < 0 ||
1021 zone != dst0.sin6_scope_id) {
1022 #ifdef SCOPEDEBUG /* will be removed shortly */
1023 printf("ip6 output: bad dst scope %s on %s\n",
1024 ip6_sprintf(&dst0.sin6_addr), if_name(ifp0));
1029 /* scope check is done. */
1033 ip6stat.ip6s_badscope++;
1034 in6_ifstat_inc(ifp0, ifs6_out_discard);
1036 error = EHOSTUNREACH; /* XXX */
1042 if (opt && opt->ip6po_nextroute.ro_rt) {
1044 * The nexthop is explicitly specified by the
1045 * application. We assume the next hop is an IPv6
1048 dst = (struct sockaddr_in6 *)opt->ip6po_nexthop;
1050 else if ((rt->rt_flags & RTF_GATEWAY))
1051 dst = (struct sockaddr_in6 *)rt->rt_gateway;
1054 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
1055 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
1057 struct in6_multi *in6m;
1059 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
1061 in6_ifstat_inc(ifp, ifs6_out_mcast);
1064 * Confirm that the outgoing interface supports multicast.
1066 if (!(ifp->if_flags & IFF_MULTICAST)) {
1067 ip6stat.ip6s_noroute++;
1068 in6_ifstat_inc(ifp, ifs6_out_discard);
1069 error = ENETUNREACH;
1072 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
1074 (im6o == NULL || im6o->im6o_multicast_loop)) {
1076 * If we belong to the destination multicast group
1077 * on the outgoing interface, and the caller did not
1078 * forbid loopback, loop back a copy.
1080 ip6_mloopback(ifp, m, dst);
1083 * If we are acting as a multicast router, perform
1084 * multicast forwarding as if the packet had just
1085 * arrived on the interface to which we are about
1086 * to send. The multicast forwarding function
1087 * recursively calls this function, using the
1088 * IPV6_FORWARDING flag to prevent infinite recursion.
1090 * Multicasts that are looped back by ip6_mloopback(),
1091 * above, will be forwarded by the ip6_input() routine,
1094 if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
1096 * XXX: ip6_mforward expects that rcvif is NULL
1097 * when it is called from the originating path.
1098 * However, it is not always the case, since
1099 * some versions of MGETHDR() does not
1100 * initialize the field.
1102 m->m_pkthdr.rcvif = NULL;
1103 if (ip6_mforward(ip6, ifp, m) != 0) {
1110 * Multicasts with a hoplimit of zero may be looped back,
1111 * above, but must not be transmitted on a network.
1112 * Also, multicasts addressed to the loopback interface
1113 * are not sent -- the above call to ip6_mloopback() will
1114 * loop back a copy if this host actually belongs to the
1115 * destination group on the loopback interface.
1117 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
1118 IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
1125 * Fill the outgoing inteface to tell the upper layer
1126 * to increment per-interface statistics.
1132 * Upper-layer reachability confirmation
1134 if (opt && (opt->ip6po_flags & IP6PO_REACHCONF))
1135 nd6_nud_hint(rt, NULL, 0);
1137 /* Determine path MTU. */
1138 if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu)) != 0)
1142 * An advanced API option (IPV6_USE_MIN_MTU) overrides mtu setting.
1143 * We ignore the specified MTU if it is larger than the already-known
1146 if (mtu > IPV6_MMTU && opt && (opt->ip6po_flags & IP6PO_MINMTU))
1149 /* Fake scoped addresses */
1150 if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
1152 * If source or destination address is a scoped address, and
1153 * the packet is going to be sent to a loopback interface,
1154 * we should keep the original interface.
1158 * XXX: this is a very experimental and temporary solution.
1159 * We eventually have sockaddr_in6 and use the sin6_scope_id
1160 * field of the structure here.
1161 * We rely on the consistency between two scope zone ids
1162 * of source and destination, which should already be assured.
1163 * Larger scopes than link will be supported in the future.
1166 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
1167 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
1168 origifp = ifnet_byindex(ntohs(ip6->ip6_src.s6_addr16[1]));
1170 origifp = ifindex2ifnet[ntohs(ip6->ip6_src.s6_addr16[1])];
1172 } else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
1173 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
1174 origifp = ifnet_byindex(ntohs(ip6->ip6_dst.s6_addr16[1]));
1176 origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])];
1178 } else if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
1179 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
1180 origifp = ifnet_byindex(ntohs(ip6->ip6_dst.s6_addr16[1]));
1182 origifp = ifindex2ifnet[ntohs(ip6->ip6_dst.s6_addr16[1])];
1187 * XXX: origifp can be NULL even in those two cases above.
1188 * For example, if we remove the (only) link-local address
1189 * from the loopback interface, and try to send a link-local
1190 * address without link-id information. Then the source
1191 * address is ::1, and the destination address is the
1192 * link-local address with its s6_addr16[1] being zero.
1193 * What is worse, if the packet goes to the loopback interface
1194 * by a default rejected route, the null pointer would be
1195 * passed to looutput, and the kernel would hang.
1196 * The following last resort would prevent such disaster.
1198 if (origifp == NULL)
1203 #ifndef SCOPEDROUTING
1205 * clear embedded scope identifiers if necessary.
1206 * in6_clearscope will touch the addresses only when necessary.
1208 in6_clearscope(&ip6->ip6_src);
1209 in6_clearscope(&ip6->ip6_dst);
1212 #if defined(IPV6FIREWALL) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
1214 * Check with the firewall...
1216 #if defined(__FreeBSD__) && __FreeBSD__ >= 4
1217 if (ip6_fw_enable && ip6_fw_chk_ptr) {
1219 if (ip6_fw_chk_ptr) {
1221 m->m_pkthdr.rcvif = NULL; /* XXX */
1222 /* If ipfw says divert, we have to just drop packet */
1223 if ((*ip6_fw_chk_ptr)(&ip6, ifp, &m)) {
1235 * If the outgoing packet contains a hop-by-hop options header,
1236 * it must be examined and processed even by the source node.
1237 * (RFC 2460, section 4.)
1239 if (exthdrs.ip6e_hbh) {
1240 struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
1241 u_int32_t dummy; /* XXX unused */
1242 u_int32_t plen = 0; /* XXX: ip6_process will check the value */
1245 if ((hbh->ip6h_len + 1) << 3 > exthdrs.ip6e_hbh->m_len)
1246 panic("ip6e_hbh is not continuous");
1249 * XXX: if we have to send an ICMPv6 error to the sender,
1250 * we need the M_LOOP flag since icmp6_error() expects
1251 * the IPv6 and the hop-by-hop options header are
1252 * continuous unless the flag is set.
1254 m->m_flags |= M_LOOP;
1255 m->m_pkthdr.rcvif = ifp;
1256 if (ip6_process_hopopts(m,
1257 (u_int8_t *)(hbh + 1),
1258 ((hbh->ip6h_len + 1) << 3) -
1259 sizeof(struct ip6_hbh),
1260 &dummy, &plen) < 0) {
1261 /* m was already freed at this point */
1262 error = EINVAL;/* better error? */
1265 m->m_flags &= ~M_LOOP; /* XXX */
1266 m->m_pkthdr.rcvif = NULL;
1269 #if defined(__NetBSD__) && defined(PFIL_HOOKS)
1271 * Run through list of hooks for output packets.
1274 pfh = pfil_hook_get(PFIL_OUT, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
1275 for (; pfh; pfh = pfh->pfil_link.tqe_next)
1276 if (pfh->pfil_func) {
1277 rv = pfh->pfil_func(ip6, sizeof(*ip6), ifp, 1, &m1);
1279 error = EHOSTUNREACH;
1285 ip6 = mtod(m, struct ip6_hdr *);
1287 #endif /* PFIL_HOOKS */
1289 #if defined(__OpenBSD__) && NPF > 0
1290 if (pf_test6(PF_OUT, ifp, &m) != PF_PASS) {
1291 error = EHOSTUNREACH;
1295 ip6 = mtod(m, struct ip6_hdr *);
1299 * Send the packet to the outgoing interface.
1300 * If necessary, do IPv6 fragmentation before sending.
1302 tlen = m->m_pkthdr.len;
1304 * Even if the DONTFRAG option is specified, we cannot send the packet
1305 * when the data length is larger than the MTU of the outgoing
1307 * Notify the error by sending IPV6_PATHMTU ancillary data as well
1308 * as returning an error code (the latter is not described in the API
1311 if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG) && tlen > ifp->if_mtu
1313 && !(ifp->if_flags & IFF_FRAGMENTABLE)
1317 struct ip6ctlparam ip6cp;
1319 mtu32 = (u_int32_t)mtu;
1320 bzero(&ip6cp, sizeof(ip6cp));
1321 ip6cp.ip6c_cmdarg = (void *)&mtu32;
1322 pfctlinput2(PRC_MSGSIZE, &ro_pmtu->ro_dst, (void *)&ip6cp);
1327 if (tlen <= mtu || (opt && (opt->ip6po_flags & IP6PO_DONTFRAG))
1330 * On any link that cannot convey a 1280-octet packet in one piece,
1331 * link-specific fragmentation and reassembly must be provided at
1332 * a layer below IPv6. [RFC 2460, sec.5]
1333 * Thus if the interface has ability of link-level fragmentation,
1334 * we can just send the packet even if the packet size is
1335 * larger than the link's MTU.
1336 * XXX: IFF_FRAGMENTABLE (or such) flag has not been defined yet...
1339 || (ifp->if_flags & IFF_FRAGMENTABLE)
1343 struct in6_ifaddr *ia6;
1345 ip6 = mtod(m, struct ip6_hdr *);
1346 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
1348 /* Record statistics for this interface address. */
1349 #if defined(__NetBSD__) && defined(IFA_STATS)
1350 ia6->ia_ifa.ifa_data.ifad_outbytes +=
1352 #elif defined(__FreeBSD__) && __FreeBSD__ >= 4
1353 ia6->ia_ifa.if_opackets++;
1354 ia6->ia_ifa.if_obytes += m->m_pkthdr.len;
1355 #elif defined(__bsdi__) && _BSDI_VERSION >= 199802
1356 ia6->ia_ifa.ifa_opackets++;
1357 ia6->ia_ifa.ifa_obytes += m->m_pkthdr.len;
1360 #if defined(IPSEC) && !defined(__OpenBSD__)
1361 /* clean ipsec history once it goes out of the node */
1364 error = nd6_output(ifp, origifp, m, dst, rt);
1366 } else if (mtu < IPV6_MMTU) {
1368 * note that path MTU is never less than IPV6_MMTU
1369 * (see icmp6_input).
1372 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1374 } else if (ip6->ip6_plen == 0) { /* jumbo payload cannot be fragmented */
1376 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1379 struct mbuf **mnext, *m_frgpart;
1380 struct ip6_frag *ip6f;
1381 u_int32_t id = htonl(ip6_id++);
1383 struct ip6ctlparam ip6cp;
1387 * Too large for the destination or interface;
1388 * fragment if possible.
1389 * Must be able to put at least 8 bytes per fragment.
1391 hlen = unfragpartlen;
1392 if (mtu > IPV6_MAXPACKET)
1393 mtu = IPV6_MAXPACKET;
1395 /* Notify a proper path MTU to applications. */
1396 mtu32 = (u_int32_t)mtu;
1397 bzero(&ip6cp, sizeof(ip6cp));
1398 ip6cp.ip6c_cmdarg = (void *)&mtu32;
1399 pfctlinput2(PRC_MSGSIZE, &ro_pmtu->ro_dst, (void *)&ip6cp);
1401 len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
1404 in6_ifstat_inc(ifp, ifs6_out_fragfail);
1408 mnext = &m->m_nextpkt;
1411 * Change the next header field of the last header in the
1412 * unfragmentable part.
1415 if (exthdrs.ip6e_haddr) {
1416 nextproto = *mtod(exthdrs.ip6e_haddr, u_char *);
1417 *mtod(exthdrs.ip6e_haddr, u_char *) = IPPROTO_FRAGMENT;
1420 if (exthdrs.ip6e_rthdr) {
1421 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
1422 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
1423 } else if (exthdrs.ip6e_dest1) {
1424 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
1425 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
1426 } else if (exthdrs.ip6e_hbh) {
1427 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
1428 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
1430 nextproto = ip6->ip6_nxt;
1431 ip6->ip6_nxt = IPPROTO_FRAGMENT;
1435 * Loop through length of segment after first fragment,
1436 * make new header and copy data of each part and link onto
1440 for (off = hlen; off < tlen; off += len) {
1441 MGETHDR(m, M_DONTWAIT, MT_HEADER);
1444 ip6stat.ip6s_odropped++;
1447 m->m_pkthdr.rcvif = NULL;
1448 m->m_flags = m0->m_flags & M_COPYFLAGS;
1450 mnext = &m->m_nextpkt;
1451 m->m_data += max_linkhdr;
1452 mhip6 = mtod(m, struct ip6_hdr *);
1454 m->m_len = sizeof(*mhip6);
1455 error = ip6_insertfraghdr(m0, m, hlen, &ip6f);
1457 ip6stat.ip6s_odropped++;
1460 ip6f->ip6f_offlg = htons((u_short)((off - hlen) & ~7));
1461 if (off + len >= tlen)
1464 ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
1465 mhip6->ip6_plen = htons((u_short)(len + hlen +
1467 sizeof(struct ip6_hdr)));
1468 if ((m_frgpart = m_copy(m0, off, len)) == 0) {
1470 ip6stat.ip6s_odropped++;
1473 m_cat(m, m_frgpart);
1474 m->m_pkthdr.len = len + hlen + sizeof(*ip6f);
1475 m->m_pkthdr.rcvif = (struct ifnet *)0;
1476 ip6f->ip6f_reserved = 0;
1477 ip6f->ip6f_ident = id;
1478 ip6f->ip6f_nxt = nextproto;
1479 ip6stat.ip6s_ofragments++;
1480 in6_ifstat_inc(ifp, ifs6_out_fragcreat);
1483 in6_ifstat_inc(ifp, ifs6_out_fragok);
1487 * Remove leading garbages.
1493 for (m0 = m; m; m = m0) {
1497 struct in6_ifaddr *ia6;
1498 ip6 = mtod(m, struct ip6_hdr *);
1499 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
1502 * Record statistics for this interface
1505 #if defined(__NetBSD__) && defined(IFA_STATS)
1506 ia6->ia_ifa.ifa_data.ifad_outbytes +=
1508 #elif defined(__FreeBSD__) && __FreeBSD__ >= 4
1509 ia6->ia_ifa.if_opackets++;
1510 ia6->ia_ifa.if_obytes += m->m_pkthdr.len;
1511 #elif defined(__bsdi__) && _BSDI_VERSION >= 199802
1512 ia6->ia_ifa.ifa_opackets++;
1513 ia6->ia_ifa.ifa_obytes += m->m_pkthdr.len;
1516 #if defined(IPSEC) && !defined(__OpenBSD__)
1517 /* clean ipsec history once it goes out of the node */
1520 error = nd6_output(ifp, origifp, m, dst, rt);
1526 ip6stat.ip6s_fragmented++;
1529 if (ro == &ip6route && ro->ro_rt) { /* brace necessary for RTFREE */
1531 } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
1532 RTFREE(ro_pmtu->ro_rt);
1535 #if defined(IPSEC) && !defined(__OpenBSD__)
1541 mip6_destopt_discard(&mip6opt);
1548 mip6_destopt_discard(&mip6opt);
1550 m_freem(exthdrs.ip6e_hbh); /* m_freem will check if mbuf is 0 */
1551 m_freem(exthdrs.ip6e_dest1);
1552 m_freem(exthdrs.ip6e_rthdr);
1554 m_freem(exthdrs.ip6e_haddr);
1556 m_freem(exthdrs.ip6e_dest2);
1564 ip6_copyexthdr(mp, hdr, hlen)
1571 if (hlen > MCLBYTES)
1572 return(ENOBUFS); /* XXX */
1574 MGET(m, M_DONTWAIT, MT_DATA);
1579 MCLGET(m, M_DONTWAIT);
1580 if ((m->m_flags & M_EXT) == 0) {
1587 bcopy(hdr, mtod(m, caddr_t), hlen);
1594 * Insert jumbo payload option.
1597 ip6_insert_jumboopt(exthdrs, plen)
1598 struct ip6_exthdrs *exthdrs;
1605 #define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
1608 * If there is no hop-by-hop options header, allocate new one.
1609 * If there is one but it doesn't have enough space to store the
1610 * jumbo payload option, allocate a cluster to store the whole options.
1611 * Otherwise, use it to store the options.
1613 if (exthdrs->ip6e_hbh == 0) {
1614 MGET(mopt, M_DONTWAIT, MT_DATA);
1617 mopt->m_len = JUMBOOPTLEN;
1618 optbuf = mtod(mopt, u_char *);
1619 optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */
1620 exthdrs->ip6e_hbh = mopt;
1622 struct ip6_hbh *hbh;
1624 mopt = exthdrs->ip6e_hbh;
1625 if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
1628 * - exthdrs->ip6e_hbh is not referenced from places
1629 * other than exthdrs.
1630 * - exthdrs->ip6e_hbh is not an mbuf chain.
1632 int oldoptlen = mopt->m_len;
1636 * XXX: give up if the whole (new) hbh header does
1637 * not fit even in an mbuf cluster.
1639 if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
1643 * As a consequence, we must always prepare a cluster
1646 MGET(n, M_DONTWAIT, MT_DATA);
1648 MCLGET(n, M_DONTWAIT);
1649 if ((n->m_flags & M_EXT) == 0) {
1656 n->m_len = oldoptlen + JUMBOOPTLEN;
1657 bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
1659 optbuf = mtod(n, caddr_t) + oldoptlen;
1661 mopt = exthdrs->ip6e_hbh = n;
1663 optbuf = mtod(mopt, u_char *) + mopt->m_len;
1664 mopt->m_len += JUMBOOPTLEN;
1666 optbuf[0] = IP6OPT_PADN;
1670 * Adjust the header length according to the pad and
1671 * the jumbo payload option.
1673 hbh = mtod(mopt, struct ip6_hbh *);
1674 hbh->ip6h_len += (JUMBOOPTLEN >> 3);
1677 /* fill in the option. */
1678 optbuf[2] = IP6OPT_JUMBO;
1680 v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
1681 bcopy(&v, &optbuf[4], sizeof(u_int32_t));
1683 /* finally, adjust the packet header length */
1684 exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
1691 * Insert fragment header and copy unfragmentable header portions.
1694 ip6_insertfraghdr(m0, m, hlen, frghdrp)
1695 struct mbuf *m0, *m;
1697 struct ip6_frag **frghdrp;
1699 struct mbuf *n, *mlast;
1701 if (hlen > sizeof(struct ip6_hdr)) {
1702 n = m_copym(m0, sizeof(struct ip6_hdr),
1703 hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
1710 /* Search for the last mbuf of unfragmentable part. */
1711 for (mlast = n; mlast->m_next; mlast = mlast->m_next)
1714 if ((mlast->m_flags & M_EXT) == 0 &&
1715 M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) {
1716 /* use the trailing space of the last mbuf for the fragment hdr */
1718 (struct ip6_frag *)(mtod(mlast, caddr_t) + mlast->m_len);
1719 mlast->m_len += sizeof(struct ip6_frag);
1720 m->m_pkthdr.len += sizeof(struct ip6_frag);
1722 /* allocate a new mbuf for the fragment header */
1725 MGET(mfrg, M_DONTWAIT, MT_DATA);
1728 mfrg->m_len = sizeof(struct ip6_frag);
1729 *frghdrp = mtod(mfrg, struct ip6_frag *);
1730 mlast->m_next = mfrg;
1737 ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup)
1738 #ifdef NEW_STRUCT_ROUTE
1739 struct route *ro_pmtu, *ro;
1741 struct route_in6 *ro_pmtu, *ro;
1744 struct in6_addr *dst; /* XXX: should be sockaddr_in6 */
1750 if (ro_pmtu != ro) {
1751 /* The first hop and the final destination may differ. */
1752 struct sockaddr_in6 *sa6_dst =
1753 (struct sockaddr_in6 *)&ro_pmtu->ro_dst;
1754 if (ro_pmtu->ro_rt && ((ro_pmtu->ro_rt->rt_flags & RTF_UP)
1756 !IN6_ARE_ADDR_EQUAL(&sa6_dst->sin6_addr,
1758 RTFREE(ro_pmtu->ro_rt);
1759 ro_pmtu->ro_rt = (struct rtentry *)NULL;
1761 if (ro_pmtu->ro_rt == NULL) {
1762 bzero(sa6_dst, sizeof(*sa6_dst));
1763 sa6_dst->sin6_family = AF_INET6;
1764 sa6_dst->sin6_len = sizeof(struct sockaddr_in6);
1765 sa6_dst->sin6_addr = *dst;
1767 #ifdef __bsdi__ /* bsdi needs rtcalloc to clone a route. */
1768 rtcalloc((struct route *)ro_pmtu);
1770 rtalloc((struct route *)ro_pmtu);
1774 if (ro_pmtu->ro_rt) {
1778 ifp = ro_pmtu->ro_rt->rt_ifp;
1779 ifmtu = nd_ifinfo[ifp->if_index].linkmtu;
1780 mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
1781 if (mtu > ifmtu || mtu == 0) {
1783 * The MTU on the route is larger than the MTU on
1784 * the interface! This shouldn't happen, unless the
1785 * MTU of the interface has been changed after the
1786 * interface was brought up. Change the MTU in the
1787 * route to match the interface MTU (as long as the
1788 * field isn't locked).
1790 * if MTU on the route is 0, we need to fix the MTU.
1791 * this case happens with path MTU discovery timeouts.
1794 if ((ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU) == 0)
1795 ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; /* XXX */
1798 mtu = nd_ifinfo[ifp->if_index].linkmtu;
1800 error = EHOSTUNREACH; /* XXX */
1807 * IP6 socket option processing.
1809 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1811 ip6_ctloutput(so, sopt)
1813 struct sockopt *sopt;
1816 ip6_ctloutput(op, so, level, optname, mp)
1823 int privileged, optdatalen;
1825 struct ip6_recvpktopts *rcvopts;
1826 #if defined(IPSEC) && defined(__OpenBSD__)
1827 struct proc *p = curproc; /* XXX */
1829 struct tdb_ident *tdbip, tdbi;
1832 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1833 struct inpcb *in6p = sotoinpcb(so);
1835 int level, op, optname;
1840 panic("ip6_ctloutput: arg soopt is NULL");
1842 level = sopt->sopt_level;
1843 op = sopt->sopt_dir;
1844 optname = sopt->sopt_name;
1845 optlen = sopt->sopt_valsize;
1848 #ifdef HAVE_NRL_INPCB
1849 struct inpcb *inp = sotoinpcb(so);
1852 struct in6pcb *in6p = sotoin6pcb(so);
1853 #endif /* HAVE_NRL_INPCB */
1854 struct mbuf *m = *mp;
1857 #if defined(__NetBSD__) || (defined(__FreeBSD__) && __FreeBSD__ >= 3)
1858 struct proc *p = curproc; /* XXX */
1861 optlen = m ? m->m_len : 0;
1862 #endif /* FreeBSD >= 3 */
1866 rcvopts = in6p->in6p_inputopts;
1868 if (level == IPPROTO_IPV6) {
1871 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1877 case IPV6_2292PKTOPTIONS:
1878 #ifdef IPV6_PKTOPTIONS
1879 case IPV6_PKTOPTIONS:
1882 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1885 error = soopt_getm(sopt, &m); /* XXX */
1888 error = soopt_mcopyin(sopt, m); /* XXX */
1891 error = ip6_pcbopts(&in6p->in6p_outputopts,
1893 m_freem(m); /* XXX */
1895 error = ip6_pcbopts(&in6p->in6p_outputopts,
1897 #endif /* FreeBSD >= 3 */
1902 * Use of some Hop-by-Hop options or some
1903 * Destination options, might require special
1904 * privilege. That is, normal applications
1905 * (without special privilege) might be forbidden
1906 * from setting certain options in outgoing packets,
1907 * and might never see certain options in received
1908 * packets. [RFC 2292 Section 6]
1909 * KAME specific note:
1910 * KAME prevents non-privileged users from sending or
1911 * receiving ANY hbh/dst options in order to avoid
1912 * overhead of parsing options in the kernel.
1914 case IPV6_RECVHOPOPTS:
1915 case IPV6_RECVDSTOPTS:
1916 case IPV6_RECVRTHDRDSTOPTS:
1918 case IPV6_UNICAST_HOPS:
1922 case IPV6_RECVPKTINFO:
1923 case IPV6_RECVHOPLIMIT:
1924 case IPV6_RECVRTHDR:
1925 case IPV6_RECVPATHMTU:
1926 case IPV6_RECVTCLASS:
1928 case IPV6_AUTOFLOWLABEL:
1929 if (optlen != sizeof(int)) {
1933 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1934 error = sooptcopyin(sopt, &optval,
1935 sizeof optval, sizeof optval);
1939 optval = *mtod(m, int *);
1943 case IPV6_UNICAST_HOPS:
1944 if (optval < -1 || optval >= 256)
1947 /* -1 = kernel default */
1948 in6p->in6p_hops = optval;
1949 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
1950 if ((in6p->in6p_vflag &
1952 in6p->inp_ip_ttl = optval;
1956 #define OPTSET(bit) \
1959 in6p->in6p_flags |= (bit); \
1961 in6p->in6p_flags &= ~(bit); \
1963 #define OPTSET2292(bit) \
1965 in6p->in6p_flags |= IN6P_RFC2292; \
1967 in6p->in6p_flags |= (bit); \
1969 in6p->in6p_flags &= ~(bit); \
1971 #define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0)
1973 case IPV6_RECVPKTINFO:
1974 /* cannot mix with RFC2292 */
1975 if (OPTBIT(IN6P_RFC2292)) {
1979 OPTSET(IN6P_PKTINFO);
1980 if (OPTBIT(IN6P_PKTINFO) == 0)
1981 ip6_reset_rcvopt(rcvopts, IPV6_RECVPKTINFO);
1986 struct ip6_pktopts **optp;
1988 /* cannot mix with RFC2292 */
1989 if (OPTBIT(IN6P_RFC2292)) {
1993 optp = &in6p->in6p_outputopts;
1994 error = ip6_pcbopt(IPV6_HOPLIMIT,
2002 case IPV6_RECVHOPLIMIT:
2003 /* cannot mix with RFC2292 */
2004 if (OPTBIT(IN6P_RFC2292)) {
2008 OPTSET(IN6P_HOPLIMIT);
2009 if (OPTBIT(IN6P_HOPLIMIT) == 0)
2010 ip6_reset_rcvopt(rcvopts, IPV6_RECVHOPLIMIT);
2013 case IPV6_RECVHOPOPTS:
2014 /* cannot mix with RFC2292 */
2015 if (OPTBIT(IN6P_RFC2292)) {
2019 OPTSET(IN6P_HOPOPTS);
2020 if (OPTBIT(IN6P_HOPOPTS) == 0)
2021 ip6_reset_rcvopt(rcvopts, IPV6_RECVHOPOPTS);
2024 case IPV6_RECVDSTOPTS:
2025 /* cannot mix with RFC2292 */
2026 if (OPTBIT(IN6P_RFC2292)) {
2030 OPTSET(IN6P_DSTOPTS);
2031 if (OPTBIT(IN6P_DSTOPTS) == 0)
2032 ip6_reset_rcvopt(rcvopts, IPV6_RECVDSTOPTS);
2035 case IPV6_RECVRTHDRDSTOPTS:
2036 /* cannot mix with RFC2292 */
2037 if (OPTBIT(IN6P_RFC2292)) {
2041 OPTSET(IN6P_RTHDRDSTOPTS);
2042 if (OPTBIT(IN6P_RTHDRDSTOPTS) == 0)
2043 ip6_reset_rcvopt(rcvopts, IPV6_RECVRTHDRDSTOPTS);
2046 case IPV6_RECVRTHDR:
2047 /* cannot mix with RFC2292 */
2048 if (OPTBIT(IN6P_RFC2292)) {
2053 if (OPTBIT(IN6P_RTHDR) == 0)
2054 ip6_reset_rcvopt(rcvopts, IPV6_RECVRTHDR);
2061 case IPV6_RECVPATHMTU:
2067 * make setsockopt(IPV6_V6ONLY)
2068 * available only prior to bind(2).
2069 * see ipng mailing list, Jun 22 2001.
2071 if (in6p->in6p_lport ||
2072 !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr))
2078 #ifdef INET6_BINDV6ONLY
2082 OPTSET(IN6P_IPV6_V6ONLY);
2084 #elif (defined(__FreeBSD__) && __FreeBSD__ >= 3) || (defined(__bsdi__) && _BSDI_VERSION >= 199802)
2085 OPTSET(IN6P_IPV6_V6ONLY);
2087 if ((ip6_v6only && optval) ||
2088 (!ip6_v6only && !optval))
2094 case IPV6_RECVTCLASS:
2095 /* cannot mix with RFC2292 XXX */
2096 if (OPTBIT(IN6P_RFC2292)) {
2100 OPTSET(IN6P_TCLASS);
2102 case IPV6_AUTOFLOWLABEL:
2103 OPTSET(IN6P_AUTOFLOWLABEL);
2111 struct ip6_pktopts **optp;
2114 if (optlen != sizeof(tclass)) {
2118 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2119 error = sooptcopyin(sopt, &tclass,
2120 sizeof tclass, sizeof tclass);
2124 tclass = *mtod(m, u_int8_t *);
2126 optp = &in6p->in6p_outputopts;
2127 error = ip6_pcbopt(optname,
2137 case IPV6_USE_MIN_MTU:
2138 if (optlen != sizeof(optval)) {
2142 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2143 error = sooptcopyin(sopt, &optval,
2144 sizeof optval, sizeof optval);
2148 optval = *mtod(m, int *);
2151 struct ip6_pktopts **optp;
2152 optp = &in6p->in6p_outputopts;
2153 error = ip6_pcbopt(optname,
2161 case IPV6_2292PKTINFO:
2162 case IPV6_2292HOPLIMIT:
2163 case IPV6_2292HOPOPTS:
2164 case IPV6_2292DSTOPTS:
2165 case IPV6_2292RTHDR:
2167 if (optlen != sizeof(int)) {
2171 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2172 error = sooptcopyin(sopt, &optval,
2173 sizeof optval, sizeof optval);
2177 optval = *mtod(m, int *);
2180 case IPV6_2292PKTINFO:
2181 OPTSET2292(IN6P_PKTINFO);
2182 if (OPTBIT(IN6P_PKTINFO) == 0)
2183 ip6_reset_rcvopt(rcvopts, IPV6_RECVPKTINFO);
2185 case IPV6_2292HOPLIMIT:
2186 OPTSET2292(IN6P_HOPLIMIT);
2187 if (OPTBIT(IN6P_HOPLIMIT) == 0)
2188 ip6_reset_rcvopt(rcvopts, IPV6_RECVHOPLIMIT);
2190 case IPV6_2292HOPOPTS:
2192 * Check super-user privilege.
2193 * See comments for IPV6_RECVHOPOPTS.
2195 OPTSET2292(IN6P_HOPOPTS);
2196 if (OPTBIT(IN6P_HOPOPTS) == 0)
2197 ip6_reset_rcvopt(rcvopts, IPV6_RECVHOPOPTS);
2199 case IPV6_2292DSTOPTS:
2200 OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
2201 if (OPTBIT(IN6P_DSTOPTS) == 0) {
2202 ip6_reset_rcvopt(rcvopts, IPV6_RECVDSTOPTS);
2203 ip6_reset_rcvopt(rcvopts, IPV6_RECVRTHDRDSTOPTS);
2206 case IPV6_2292RTHDR:
2207 OPTSET2292(IN6P_RTHDR);
2208 if (OPTBIT(IN6P_RTHDR) == 0)
2209 ip6_reset_rcvopt(rcvopts, IPV6_RECVRTHDR);
2217 case IPV6_RTHDRDSTOPTS:
2220 /* new advanced API (2292bis) */
2223 struct ip6_pktopts **optp;
2225 /* cannot mix with RFC2292 */
2226 if (OPTBIT(IN6P_RFC2292)) {
2231 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2232 optbuf = sopt->sopt_val;
2233 optlen = sopt->sopt_valsize;
2235 if (m && m->m_next) {
2236 error = EINVAL; /* XXX */
2240 optbuf = mtod(m, u_char *);
2247 optp = &in6p->in6p_outputopts;
2248 error = ip6_pcbopt(optname,
2255 case IPV6_MULTICAST_IF:
2256 case IPV6_MULTICAST_HOPS:
2257 case IPV6_MULTICAST_LOOP:
2258 case IPV6_JOIN_GROUP:
2259 case IPV6_LEAVE_GROUP:
2260 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2263 if (sopt->sopt_valsize > MLEN) {
2268 MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
2273 m->m_len = sopt->sopt_valsize;
2274 error = sooptcopyin(sopt, mtod(m, char *),
2275 m->m_len, m->m_len);
2276 error = ip6_setmoptions(sopt->sopt_name,
2277 &in6p->in6p_moptions,
2282 error = ip6_setmoptions(optname,
2283 &in6p->in6p_moptions,
2285 #if defined(__bsdi__) && _BSDI_VERSION >= 199802
2286 if (in6p->in6p_moptions != NULL)
2287 in6p->in6p_flags |= INP_IPV6_MCAST; /* XXX */
2293 case IPV6_PORTRANGE:
2294 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2295 error = sooptcopyin(sopt, &optval,
2296 sizeof optval, sizeof optval);
2300 optval = *mtod(m, int *);
2304 case IPV6_PORTRANGE_DEFAULT:
2305 in6p->in6p_flags &= ~(IN6P_LOWPORT);
2306 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
2309 case IPV6_PORTRANGE_HIGH:
2310 in6p->in6p_flags &= ~(IN6P_LOWPORT);
2311 in6p->in6p_flags |= IN6P_HIGHPORT;
2314 case IPV6_PORTRANGE_LOW:
2315 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
2316 in6p->in6p_flags |= IN6P_LOWPORT;
2332 if (m == 0 || m->m_len != sizeof(struct tdb_ident)) {
2335 tdbip = mtod(m, struct tdb_ident *);
2336 tdb = gettdb(tdbip->spi, &tdbip->dst,
2341 tdb_add_inp(tdb, inp, 0);
2347 case IPV6_AUTH_LEVEL:
2348 case IPV6_ESP_TRANS_LEVEL:
2349 case IPV6_ESP_NETWORK_LEVEL:
2350 case IPV6_IPCOMP_LEVEL:
2354 if (m == 0 || m->m_len != sizeof(int)) {
2358 optval = *mtod(m, int *);
2360 if (optval < IPSEC_LEVEL_BYPASS ||
2361 optval > IPSEC_LEVEL_UNIQUE) {
2367 case IPV6_AUTH_LEVEL:
2368 inp->inp_seclevel[SL_AUTH] = optval;
2371 case IPV6_ESP_TRANS_LEVEL:
2372 inp->inp_seclevel[SL_ESP_TRANS] = optval;
2375 case IPV6_ESP_NETWORK_LEVEL:
2376 inp->inp_seclevel[SL_ESP_NETWORK] = optval;
2379 case IPV6_IPCOMP_LEVEL:
2380 inp->inp_seclevel[SL_IPCOMP] = optval;
2384 inp->inp_secrequire = get_sa_require(inp);
2387 #endif /* OpenBSD */
2389 #if defined(IPSEC) && !defined(__OpenBSD__)
2390 case IPV6_IPSEC_POLICY:
2394 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2398 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2399 if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
2401 if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
2405 req = mtod(m, caddr_t);
2408 error = ipsec6_set_policy(in6p, optname, req,
2410 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2415 #endif /* KAME IPSEC */
2417 #if defined(IPV6FIREWALL) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
2423 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2425 struct mbuf **mp = &m;
2428 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2429 if (ip6_fw_ctl_ptr == NULL)
2432 if ((error = soopt_getm(sopt, &m)) != 0)
2435 if ((error = soopt_mcopyin(sopt, m)) != 0)
2438 if (ip6_fw_ctl_ptr == NULL) {
2439 if (m) (void)m_free(m);
2443 error = (*ip6_fw_ctl_ptr)(optname, mp);
2450 error = ENOPROTOOPT;
2453 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
2459 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2466 case IPV6_2292PKTOPTIONS:
2467 #ifdef IPV6_PKTOPTIONS
2468 case IPV6_PKTOPTIONS:
2470 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2471 if (in6p->in6p_inputopts &&
2472 in6p->in6p_inputopts->head) {
2474 m = m_copym(in6p->in6p_inputopts->head,
2475 0, M_COPYALL, M_WAIT);
2476 error = soopt_mcopyout(sopt, m);
2480 sopt->sopt_valsize = 0;
2482 if (in6p->in6p_inputopts &&
2483 in6p->in6p_inputopts->head) {
2484 *mp = m_copym(in6p->in6p_inputopts->head,
2485 0, M_COPYALL, M_WAIT);
2487 *mp = m_get(M_WAIT, MT_SOOPTS);
2493 case IPV6_RECVHOPOPTS:
2494 case IPV6_RECVDSTOPTS:
2495 case IPV6_RECVRTHDRDSTOPTS:
2496 case IPV6_UNICAST_HOPS:
2497 case IPV6_RECVPKTINFO:
2498 case IPV6_RECVHOPLIMIT:
2499 case IPV6_RECVRTHDR:
2500 case IPV6_USE_MIN_MTU:
2501 case IPV6_RECVPATHMTU:
2507 case IPV6_PORTRANGE:
2509 case IPV6_RECVTCLASS:
2510 case IPV6_AUTOFLOWLABEL:
2513 case IPV6_UNICAST_HOPS:
2514 optval = in6p->in6p_hops;
2517 case IPV6_RECVPKTINFO:
2518 optval = OPTBIT(IN6P_PKTINFO);
2521 case IPV6_RECVHOPLIMIT:
2522 optval = OPTBIT(IN6P_HOPLIMIT);
2525 case IPV6_RECVHOPOPTS:
2526 optval = OPTBIT(IN6P_HOPOPTS);
2529 case IPV6_RECVDSTOPTS:
2530 optval = OPTBIT(IN6P_DSTOPTS);
2533 case IPV6_RECVRTHDRDSTOPTS:
2534 optval = OPTBIT(IN6P_RTHDRDSTOPTS);
2537 case IPV6_RECVPATHMTU:
2538 optval = OPTBIT(IN6P_MTU);
2542 optval = OPTBIT(IN6P_FAITH);
2546 #if (defined(__FreeBSD__) && __FreeBSD__ >= 3) || defined(__NetBSD__) || (defined(__bsdi__) && _BSDI_VERSION >= 199802)
2547 optval = OPTBIT(IN6P_IPV6_V6ONLY);
2549 optval = (ip6_v6only != 0); /* XXX */
2554 case IPV6_PORTRANGE:
2557 flags = in6p->in6p_flags;
2558 if (flags & IN6P_HIGHPORT)
2559 optval = IPV6_PORTRANGE_HIGH;
2560 else if (flags & IN6P_LOWPORT)
2561 optval = IPV6_PORTRANGE_LOW;
2567 case IPV6_RECVTCLASS:
2568 optval = OPTBIT(IN6P_TCLASS);
2571 case IPV6_AUTOFLOWLABEL:
2572 optval = OPTBIT(IN6P_AUTOFLOWLABEL);
2575 #define PKTOPTBIT(bit) ((in6p->in6p_outputopts && \
2576 (in6p->in6p_outputopts->ip6po_flags & (bit))) ? 1 : 0)
2578 optval = PKTOPTBIT(IP6PO_DONTFRAG);
2581 case IPV6_USE_MIN_MTU:
2582 optval = PKTOPTBIT(IP6PO_MINMTU);
2588 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2589 error = sooptcopyout(sopt, &optval,
2592 *mp = m = m_get(M_WAIT, MT_SOOPTS);
2593 m->m_len = sizeof(int);
2594 *mtod(m, int *) = optval;
2601 struct ip6_mtuinfo mtuinfo;
2602 #ifdef NEW_STRUCT_ROUTE
2603 struct route *ro = &in6p->in6p_route;
2605 struct route_in6 *ro = (struct route_in6 *)&in6p->in6p_route;
2608 if (!(so->so_state & SS_ISCONNECTED))
2611 * XXX: we dot not consider the case of source
2612 * routing, nor optional information to specify
2613 * the outgoing interface.
2615 error = ip6_getpmtu(ro, NULL, NULL,
2616 &in6p->in6p_faddr, &pmtu);
2619 if (pmtu > IPV6_MAXPACKET)
2620 pmtu = IPV6_MAXPACKET;
2622 bzero(&mtuinfo, sizeof(mtuinfo));
2623 mtuinfo.ip6m_mtu = (u_int32_t)pmtu;
2624 optdata = (void *)&mtuinfo;
2625 optdatalen = sizeof(mtuinfo);
2626 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2627 error = sooptcopyout(sopt, optdata,
2629 #else /* !FreeBSD3 */
2630 if (optdatalen > MCLBYTES)
2631 return(EMSGSIZE); /* XXX */
2632 *mp = m = m_get(M_WAIT, MT_SOOPTS);
2633 if (optdatalen > MLEN)
2635 m->m_len = optdatalen;
2636 bcopy(optdata, mtod(m, void *),
2638 #endif /* FreeBSD3 */
2642 case IPV6_2292PKTINFO:
2643 case IPV6_2292HOPLIMIT:
2644 case IPV6_2292HOPOPTS:
2645 case IPV6_2292RTHDR:
2646 case IPV6_2292DSTOPTS:
2647 if (optname == IPV6_2292HOPOPTS ||
2648 optname == IPV6_2292DSTOPTS ||
2652 case IPV6_2292PKTINFO:
2653 optval = OPTBIT(IN6P_PKTINFO);
2655 case IPV6_2292HOPLIMIT:
2656 optval = OPTBIT(IN6P_HOPLIMIT);
2658 case IPV6_2292HOPOPTS:
2659 optval = OPTBIT(IN6P_HOPOPTS);
2661 case IPV6_2292RTHDR:
2662 optval = OPTBIT(IN6P_RTHDR);
2664 case IPV6_2292DSTOPTS:
2665 optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS);
2668 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2669 error = sooptcopyout(sopt, &optval,
2672 *mp = m = m_get(M_WAIT, MT_SOOPTS);
2673 m->m_len = sizeof(int);
2674 *mtod(m, int *) = optval;
2675 #endif /* FreeBSD3 */
2681 case IPV6_RTHDRDSTOPTS:
2685 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2686 error = ip6_getpcbopt(in6p->in6p_outputopts,
2689 error = ip6_getpcbopt(in6p->in6p_outputopts,
2694 case IPV6_MULTICAST_IF:
2695 case IPV6_MULTICAST_HOPS:
2696 case IPV6_MULTICAST_LOOP:
2697 case IPV6_JOIN_GROUP:
2698 case IPV6_LEAVE_GROUP:
2699 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2702 error = ip6_getmoptions(sopt->sopt_name,
2703 in6p->in6p_moptions, &m);
2705 error = sooptcopyout(sopt,
2706 mtod(m, char *), m->m_len);
2710 error = ip6_getmoptions(optname, in6p->in6p_moptions, mp);
2720 if (inp->inp_tdb_out == NULL) {
2723 tdbi.spi = inp->inp_tdb_out->tdb_spi;
2724 tdbi.dst = inp->inp_tdb_out->tdb_dst;
2725 tdbi.proto = inp->inp_tdb_out->tdb_sproto;
2726 *mp = m = m_get(M_WAIT, MT_SOOPTS);
2727 m->m_len = sizeof(tdbi);
2728 bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
2729 (unsigned)m->m_len);
2735 case IPV6_AUTH_LEVEL:
2736 case IPV6_ESP_TRANS_LEVEL:
2737 case IPV6_ESP_NETWORK_LEVEL:
2738 case IPV6_IPCOMP_LEVEL:
2740 m->m_len = sizeof(int);
2741 *mtod(m, int *) = IPSEC_LEVEL_NONE;
2743 m->m_len = sizeof(int);
2745 case IPV6_AUTH_LEVEL:
2746 optval = inp->inp_seclevel[SL_AUTH];
2749 case IPV6_ESP_TRANS_LEVEL:
2751 inp->inp_seclevel[SL_ESP_TRANS];
2754 case IPV6_ESP_NETWORK_LEVEL:
2756 inp->inp_seclevel[SL_ESP_NETWORK];
2759 case IPV6_IPCOMP_LEVEL:
2760 optval = inp->inp_seclevel[SL_IPCOMP];
2763 *mtod(m, int *) = optval;
2766 #endif /* OpenBSD */
2768 #if defined(IPSEC) && !defined(__OpenBSD__)
2769 case IPV6_IPSEC_POLICY:
2773 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2774 struct mbuf *m = NULL;
2775 struct mbuf **mp = &m;
2777 error = soopt_getm(sopt, &m); /* XXX */
2780 error = soopt_mcopyin(sopt, m); /* XXX */
2785 req = mtod(m, caddr_t);
2788 error = ipsec6_get_policy(in6p, req, len, mp);
2789 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2791 error = soopt_mcopyout(sopt, m); /* XXX */
2792 if (error == 0 && m)
2797 #endif /* KAME IPSEC */
2799 #if defined(IPV6FIREWALL) || (defined(__FreeBSD__) && __FreeBSD__ >= 4)
2802 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2804 struct mbuf **mp = &m;
2807 if (ip6_fw_ctl_ptr == NULL)
2809 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
2815 error = (*ip6_fw_ctl_ptr)(optname, mp);
2816 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2818 error = soopt_mcopyout(sopt, m); /* XXX */
2819 if (error == 0 && m)
2827 error = ENOPROTOOPT;
2832 } else { /* level != IPPROTO_IPV6 */
2834 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
2835 if (op == PRCO_SETOPT && *mp)
2843 #define offsetof(type, member) ((size_t)(&((type *)0)->member)) /* XXX */
2845 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2847 ip6_raw_ctloutput(so, sopt)
2849 struct sockopt *sopt;
2852 ip6_raw_ctloutput(op, so, level, optname, mp)
2859 int error = 0, optval, optlen;
2860 const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
2861 #ifdef HAVE_NRL_INPCB
2862 struct inpcb *inp = sotoinpcb(so);
2864 struct in6pcb *in6p = sotoin6pcb(so);
2866 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2867 int level, op, optname;
2870 struct mbuf *m = *mp;
2871 #endif /* FreeBSD >= 3 */
2873 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2875 panic("ip6_ctloutput: arg soopt is NULL");
2877 level = sopt->sopt_level;
2878 op = sopt->sopt_dir;
2879 optname = sopt->sopt_name;
2880 optlen = sopt->sopt_valsize;
2883 optlen = m ? m->m_len : 0;
2884 #endif /* FreeBSD >= 3 */
2886 if (level != IPPROTO_IPV6) {
2887 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
2888 if (op == PRCO_SETOPT && *mp)
2897 * For ICMPv6 sockets, no modification allowed for checksum
2898 * offset, permit "no change" values to help existing apps.
2900 * XXX 2292bis says: "An attempt to set IPV6_CHECKSUM
2901 * for an ICMPv6 socket will fail."
2902 * The current behavior does not meet 2292bis.
2905 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2910 if (optlen != sizeof(int)) {
2914 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2915 error = sooptcopyin(sopt, &optval, sizeof(optval),
2920 optval = *mtod(m, int *);
2922 if ((optval % 2) != 0) {
2923 /* the API assumes even offset values */
2925 } else if (so->so_proto->pr_protocol ==
2927 if (optval != icmp6off)
2930 in6p->in6p_cksum = optval;
2933 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2938 if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
2941 optval = in6p->in6p_cksum;
2943 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2944 error = sooptcopyout(sopt, &optval, sizeof(optval));
2946 *mp = m = m_get(M_WAIT, MT_SOOPTS);
2947 m->m_len = sizeof(int);
2948 *mtod(m, int *) = optval;
2949 #endif /* FreeBSD3 */
2957 error = ENOPROTOOPT;
2961 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
2962 if (op == PRCO_SETOPT && m)
2969 #ifdef HAVE_NRL_INPCB
2974 * Set up IP6 options in pcb for insertion in output packets or
2975 * specifying behavior of outgoing packets.
2978 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2979 ip6_pcbopts(pktopt, m, so, sopt)
2981 ip6_pcbopts(pktopt, m, so)
2983 struct ip6_pktopts **pktopt;
2986 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
2987 struct sockopt *sopt;
2990 struct ip6_pktopts *opt = *pktopt;
2994 /* turn off any old options. */
2997 if (opt->ip6po_pktinfo || opt->ip6po_nexthop ||
2998 opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 ||
2999 opt->ip6po_rhinfo.ip6po_rhi_rthdr)
3000 printf("ip6_pcbopts: all specified options are cleared.\n");
3002 ip6_clearpktopts(opt, -1);
3004 opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK);
3007 if (!m || m->m_len == 0) {
3009 * Only turning off any previous options.
3012 free(opt, M_IP6OPT);
3016 if ((error = ip6_setpktoptions(m, opt, NULL, priv, 1)) != 0) {
3017 ip6_clearpktopts(opt, -1); /* XXX: discard all options */
3025 * initialize ip6_pktopts. beware that there are non-zero default values in
3029 init_ip6pktopts(opt)
3030 struct ip6_pktopts *opt;
3033 bzero(opt, sizeof(*opt));
3034 opt->ip6po_hlim = -1; /* -1 means default hop limit */
3035 opt->ip6po_tclass = -1; /* -1 means default traffic class */
3038 #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) /* XXX */
3040 ip6_pcbopt(optname, buf, len, pktopt, priv)
3041 int optname, len, priv;
3043 struct ip6_pktopts **pktopt;
3045 struct ip6_pktopts *opt;
3047 if (*pktopt == NULL) {
3048 *pktopt = malloc(sizeof(struct ip6_pktopts), M_IP6OPT,
3050 init_ip6pktopts(*pktopt);
3051 (*pktopt)->needfree = 1;
3055 return(ip6_setpktoption(optname, buf, len, opt, priv, 1, 0));
3058 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
3060 ip6_getpcbopt(pktopt, optname, sopt)
3061 struct ip6_pktopts *pktopt;
3062 struct sockopt *sopt;
3066 ip6_getpcbopt(pktopt, optname, mp)
3067 struct ip6_pktopts *pktopt;
3072 void *optdata = NULL;
3074 struct ip6_ext *ip6e;
3076 struct in6_pktinfo null_pktinfo;
3078 #if !(defined(__FreeBSD__) && __FreeBSD__ >= 3)
3084 if (pktopt && pktopt->ip6po_pktinfo)
3085 optdata = (void *)pktopt->ip6po_pktinfo;
3087 /* XXX: we don't have to do this every time... */
3088 bzero(&null_pktinfo, sizeof(null_pktinfo));
3089 optdata = (void *)&null_pktinfo;
3091 optdatalen = sizeof(struct in6_pktinfo);
3097 if (pktopt && pktopt->ip6po_tclass >= 0)
3098 optdata = (void *)&pktopt->ip6po_tclass;
3100 optdata = (void *)&deftclass;
3101 optdatalen = sizeof(int);
3104 if (pktopt && pktopt->ip6po_hbh) {
3105 optdata = (void *)pktopt->ip6po_hbh;
3106 ip6e = (struct ip6_ext *)pktopt->ip6po_hbh;
3107 optdatalen = (ip6e->ip6e_len + 1) << 3;
3111 if (pktopt && pktopt->ip6po_rthdr) {
3112 optdata = (void *)pktopt->ip6po_rthdr;
3113 ip6e = (struct ip6_ext *)pktopt->ip6po_rthdr;
3114 optdatalen = (ip6e->ip6e_len + 1) << 3;
3117 case IPV6_RTHDRDSTOPTS:
3118 if (pktopt && pktopt->ip6po_dest1) {
3119 optdata = (void *)pktopt->ip6po_dest1;
3120 ip6e = (struct ip6_ext *)pktopt->ip6po_dest1;
3121 optdatalen = (ip6e->ip6e_len + 1) << 3;
3125 if (pktopt && pktopt->ip6po_dest2) {
3126 optdata = (void *)pktopt->ip6po_dest2;
3127 ip6e = (struct ip6_ext *)pktopt->ip6po_dest2;
3128 optdatalen = (ip6e->ip6e_len + 1) << 3;
3132 if (pktopt && pktopt->ip6po_nexthop) {
3133 optdata = (void *)pktopt->ip6po_nexthop;
3134 optdatalen = pktopt->ip6po_nexthop->sa_len;
3137 default: /* should not happen */
3138 printf("ip6_getpcbopt: unexpected option: %d\n", optname);
3139 return(ENOPROTOOPT);
3142 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
3143 error = sooptcopyout(sopt, optdata, optdatalen);
3144 #else /* !FreeBSD3 */
3145 if (optdatalen > MCLBYTES)
3146 return(EMSGSIZE); /* XXX */
3147 *mp = m = m_get(M_WAIT, MT_SOOPTS);
3148 if (optdatalen > MLEN)
3150 m->m_len = optdatalen;
3152 bcopy(optdata, mtod(m, void *), optdatalen);
3153 #endif /* FreeBSD3 */
3159 ip6_clearpktopts(pktopt, optname)
3160 struct ip6_pktopts *pktopt;
3163 int needfree = pktopt->needfree;
3168 if (optname == -1 || optname == IPV6_PKTINFO) {
3169 if (needfree && pktopt->ip6po_pktinfo)
3170 free(pktopt->ip6po_pktinfo, M_IP6OPT);
3171 pktopt->ip6po_pktinfo = NULL;
3173 if (optname == -1 || optname == IPV6_HOPLIMIT)
3174 pktopt->ip6po_hlim = -1;
3175 if (optname == -1 || optname == IPV6_TCLASS)
3176 pktopt->ip6po_tclass = -1;
3177 if (optname == -1 || optname == IPV6_NEXTHOP) {
3178 if (pktopt->ip6po_nextroute.ro_rt) {
3179 RTFREE(pktopt->ip6po_nextroute.ro_rt);
3180 pktopt->ip6po_nextroute.ro_rt = NULL;
3182 if (needfree && pktopt->ip6po_nexthop)
3183 free(pktopt->ip6po_nexthop, M_IP6OPT);
3184 pktopt->ip6po_nexthop = NULL;
3186 if (optname == -1 || optname == IPV6_HOPOPTS) {
3187 if (needfree && pktopt->ip6po_hbh)
3188 free(pktopt->ip6po_hbh, M_IP6OPT);
3189 pktopt->ip6po_hbh = NULL;
3191 if (optname == -1 || optname == IPV6_RTHDRDSTOPTS) {
3192 if (needfree && pktopt->ip6po_dest1)
3193 free(pktopt->ip6po_dest1, M_IP6OPT);
3194 pktopt->ip6po_dest1 = NULL;
3196 if (optname == -1 || optname == IPV6_RTHDR) {
3197 if (needfree && pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
3198 free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
3199 pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
3200 if (pktopt->ip6po_route.ro_rt) {
3201 RTFREE(pktopt->ip6po_route.ro_rt);
3202 pktopt->ip6po_route.ro_rt = NULL;
3205 if (optname == -1 || optname == IPV6_DSTOPTS) {
3206 if (needfree && pktopt->ip6po_dest2)
3207 free(pktopt->ip6po_dest2, M_IP6OPT);
3208 pktopt->ip6po_dest2 = NULL;
3212 #define PKTOPT_EXTHDRCPY(type) \
3216 (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
3217 dst->type = malloc(hlen, M_IP6OPT, canwait);\
3218 if (dst->type == NULL && canwait == M_NOWAIT)\
3220 bcopy(src->type, dst->type, hlen);\
3224 struct ip6_pktopts *
3225 ip6_copypktopts(src, canwait)
3226 struct ip6_pktopts *src;
3229 struct ip6_pktopts *dst;
3232 printf("ip6_clearpktopts: invalid argument\n");
3236 dst = malloc(sizeof(*dst), M_IP6OPT, canwait);
3237 if (dst == NULL && canwait == M_NOWAIT)
3239 bzero(dst, sizeof(*dst));
3242 dst->ip6po_hlim = src->ip6po_hlim;
3243 dst->ip6po_tclass = src->ip6po_tclass;
3244 dst->ip6po_flags = src->ip6po_flags;
3245 if (src->ip6po_pktinfo) {
3246 dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo),
3248 if (dst->ip6po_pktinfo == NULL && canwait == M_NOWAIT)
3250 *dst->ip6po_pktinfo = *src->ip6po_pktinfo;
3252 if (src->ip6po_nexthop) {
3253 dst->ip6po_nexthop = malloc(src->ip6po_nexthop->sa_len,
3255 if (dst->ip6po_nexthop == NULL && canwait == M_NOWAIT)
3257 bcopy(src->ip6po_nexthop, dst->ip6po_nexthop,
3258 src->ip6po_nexthop->sa_len);
3260 PKTOPT_EXTHDRCPY(ip6po_hbh);
3261 PKTOPT_EXTHDRCPY(ip6po_dest1);
3262 PKTOPT_EXTHDRCPY(ip6po_dest2);
3263 PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
3267 printf("ip6_copypktopts: copy failed");
3268 if (dst->ip6po_pktinfo) free(dst->ip6po_pktinfo, M_IP6OPT);
3269 if (dst->ip6po_nexthop) free(dst->ip6po_nexthop, M_IP6OPT);
3270 if (dst->ip6po_hbh) free(dst->ip6po_hbh, M_IP6OPT);
3271 if (dst->ip6po_dest1) free(dst->ip6po_dest1, M_IP6OPT);
3272 if (dst->ip6po_dest2) free(dst->ip6po_dest2, M_IP6OPT);
3273 if (dst->ip6po_rthdr) free(dst->ip6po_rthdr, M_IP6OPT);
3276 #undef PKTOPT_EXTHDRCPY
3279 ip6_freepcbopts(pktopt)
3280 struct ip6_pktopts *pktopt;
3285 ip6_clearpktopts(pktopt, -1);
3287 free(pktopt, M_IP6OPT);
3291 * Set the IP6 multicast options in response to user setsockopt().
3294 ip6_setmoptions(optname, im6op, m)
3296 struct ip6_moptions **im6op;
3300 u_int loop, ifindex;
3301 struct ipv6_mreq *mreq;
3303 struct ip6_moptions *im6o = *im6op;
3305 struct sockaddr_in6 *dst;
3306 struct in6_multi_mship *imm;
3310 * No multicast option buffer attached to the pcb;
3311 * allocate one and initialize to default values.
3313 im6o = (struct ip6_moptions *)
3314 malloc(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
3316 im6o->im6o_multicast_ifp = NULL;
3317 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
3318 im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
3319 LIST_INIT(&im6o->im6o_memberships);
3324 case IPV6_MULTICAST_IF:
3326 * Select the interface for outgoing multicast packets.
3328 if (m == NULL || m->m_len != sizeof(u_int)) {
3332 bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
3333 if (ifindex < 0 || if_index < ifindex) {
3334 error = ENXIO; /* XXX EINVAL? */
3337 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
3338 ifp = ifnet_byindex(ifindex);
3340 ifp = ifindex2ifnet[ifindex];
3342 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
3343 error = EADDRNOTAVAIL;
3346 im6o->im6o_multicast_ifp = ifp;
3349 case IPV6_MULTICAST_HOPS:
3352 * Set the IP6 hoplimit for outgoing multicast packets.
3355 if (m == NULL || m->m_len != sizeof(int)) {
3359 bcopy(mtod(m, u_int *), &optval, sizeof(optval));
3360 if (optval < -1 || optval >= 256)
3362 else if (optval == -1)
3363 im6o->im6o_multicast_hlim = ip6_defmcasthlim;
3365 im6o->im6o_multicast_hlim = optval;
3369 case IPV6_MULTICAST_LOOP:
3371 * Set the loopback flag for outgoing multicast packets.
3372 * Must be zero or one.
3374 if (m == NULL || m->m_len != sizeof(u_int)) {
3378 bcopy(mtod(m, u_int *), &loop, sizeof(loop));
3383 im6o->im6o_multicast_loop = loop;
3386 case IPV6_JOIN_GROUP:
3388 * Add a multicast group membership.
3389 * Group must be a valid IP6 multicast address.
3391 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
3395 mreq = mtod(m, struct ipv6_mreq *);
3396 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
3398 * We use the unspecified address to specify to accept
3399 * all multicast addresses. Only super user is allowed
3402 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
3408 * If the interface is specified, validate it.
3410 if (mreq->ipv6mr_interface < 0
3411 || if_index < mreq->ipv6mr_interface) {
3412 error = ENXIO; /* XXX EINVAL? */
3416 * If no interface was explicitly specified, choose an
3417 * appropriate one according to the given multicast address.
3419 if (mreq->ipv6mr_interface == 0) {
3421 * Look up the routing table for the
3422 * address, and choose the outgoing interface.
3423 * XXX: is it a good approach?
3426 dst = (struct sockaddr_in6 *)&ro.ro_dst;
3427 bzero(dst, sizeof(*dst));
3428 dst->sin6_len = sizeof(struct sockaddr_in6);
3429 dst->sin6_family = AF_INET6;
3430 dst->sin6_addr = mreq->ipv6mr_multiaddr;
3431 rtalloc((struct route *)&ro);
3432 if (ro.ro_rt == NULL) {
3433 error = EADDRNOTAVAIL;
3436 ifp = ro.ro_rt->rt_ifp;
3439 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
3440 ifp = ifnet_byindex(mreq->ipv6mr_interface);
3442 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
3447 * See if we found an interface, and confirm that it
3448 * supports multicast
3450 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
3451 error = EADDRNOTAVAIL;
3455 * Put interface index into the multicast address,
3456 * if the address has interface/link-local scope.
3457 * XXX: the embedded form is a KAME-local hack.
3459 if (IN6_IS_ADDR_MC_INTFACELOCAL(&mreq->ipv6mr_multiaddr) ||
3460 IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
3461 mreq->ipv6mr_multiaddr.s6_addr16[1]
3462 = htons(mreq->ipv6mr_interface);
3465 * See if the membership already exists.
3467 for (imm = im6o->im6o_memberships.lh_first;
3468 imm != NULL; imm = imm->i6mm_chain.le_next)
3469 if (imm->i6mm_maddr->in6m_ifp == ifp &&
3470 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
3471 &mreq->ipv6mr_multiaddr))
3478 * Everything looks good; add a new record to the multicast
3479 * address list for the given interface.
3481 imm = in6_joingroup(ifp, &mreq->ipv6mr_multiaddr, &error);
3484 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
3487 case IPV6_LEAVE_GROUP:
3489 * Drop a multicast group membership.
3490 * Group must be a valid IP6 multicast address.
3492 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
3496 mreq = mtod(m, struct ipv6_mreq *);
3497 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
3498 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
3503 * If an interface address was specified, get a pointer
3504 * to its ifnet structure.
3506 if (mreq->ipv6mr_interface < 0
3507 || if_index < mreq->ipv6mr_interface) {
3508 error = ENXIO; /* XXX EINVAL? */
3511 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
3512 ifp = ifnet_byindex(mreq->ipv6mr_interface);
3514 ifp = ifindex2ifnet[mreq->ipv6mr_interface];
3517 * Put interface index into the multicast address,
3518 * if the address has interface/link-local scope.
3520 if (IN6_IS_ADDR_MC_INTFACELOCAL(&mreq->ipv6mr_multiaddr) ||
3521 IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
3522 mreq->ipv6mr_multiaddr.s6_addr16[1]
3523 = htons(mreq->ipv6mr_interface);
3526 * Find the membership in the membership list.
3528 for (imm = im6o->im6o_memberships.lh_first;
3529 imm != NULL; imm = imm->i6mm_chain.le_next) {
3531 imm->i6mm_maddr->in6m_ifp == ifp) &&
3532 IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
3533 &mreq->ipv6mr_multiaddr))
3537 /* Unable to resolve interface */
3538 error = EADDRNOTAVAIL;
3542 * Give up the multicast address record to which the
3543 * membership points.
3545 LIST_REMOVE(imm, i6mm_chain);
3546 in6_leavegroup(imm);
3555 * If all options have default values, no need to keep the mbuf.
3557 if (im6o->im6o_multicast_ifp == NULL &&
3558 im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
3559 im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
3560 im6o->im6o_memberships.lh_first == NULL) {
3561 free(*im6op, M_IPMOPTS);
3569 * Return the IP6 multicast options in response to user getsockopt().
3572 ip6_getmoptions(optname, im6o, mp)
3574 struct ip6_moptions *im6o;
3577 u_int *hlim, *loop, *ifindex;
3580 *mp = m_get(M_WAIT, MT_HEADER); /* XXX */
3582 *mp = m_get(M_WAIT, MT_SOOPTS);
3587 case IPV6_MULTICAST_IF:
3588 ifindex = mtod(*mp, u_int *);
3589 (*mp)->m_len = sizeof(u_int);
3590 if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
3593 *ifindex = im6o->im6o_multicast_ifp->if_index;
3596 case IPV6_MULTICAST_HOPS:
3597 hlim = mtod(*mp, u_int *);
3598 (*mp)->m_len = sizeof(u_int);
3600 *hlim = ip6_defmcasthlim;
3602 *hlim = im6o->im6o_multicast_hlim;
3605 case IPV6_MULTICAST_LOOP:
3606 loop = mtod(*mp, u_int *);
3607 (*mp)->m_len = sizeof(u_int);
3609 *loop = ip6_defmcasthlim;
3611 *loop = im6o->im6o_multicast_loop;
3620 * Discard the IP6 multicast options.
3623 ip6_freemoptions(im6o)
3624 struct ip6_moptions *im6o;
3626 struct in6_multi_mship *imm;
3631 while ((imm = im6o->im6o_memberships.lh_first) != NULL) {
3632 LIST_REMOVE(imm, i6mm_chain);
3633 in6_leavegroup(imm);
3635 free(im6o, M_IPMOPTS);
3639 * Set IPv6 outgoing packet options based on advanced API.
3642 ip6_setpktoptions(control, opt, stickyopt, priv, needcopy)
3643 struct mbuf *control;
3644 struct ip6_pktopts *opt, *stickyopt;
3647 struct cmsghdr *cm = 0;
3649 if (control == 0 || opt == 0)
3654 * If stickyopt is provided, make a local copy of the options
3655 * for this particular packet, then override them by ancillary
3657 * XXX: need to gain a reference for the cached route of the
3658 * next hop in case of the overriding.
3661 if (opt->ip6po_nextroute.ro_rt)
3662 opt->ip6po_nextroute.ro_rt->rt_refcnt++;
3664 init_ip6pktopts(opt);
3665 opt->needfree = needcopy;
3668 * XXX: Currently, we assume all the optional information is stored
3671 if (control->m_next)
3674 for (; control->m_len; control->m_data += CMSG_ALIGN(cm->cmsg_len),
3675 control->m_len -= CMSG_ALIGN(cm->cmsg_len)) {
3678 if (control->m_len < CMSG_LEN(0))
3681 cm = mtod(control, struct cmsghdr *);
3682 if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
3684 if (cm->cmsg_level != IPPROTO_IPV6)
3687 error = ip6_setpktoption(cm->cmsg_type, CMSG_DATA(cm),
3688 cm->cmsg_len - CMSG_LEN(0),
3689 opt, priv, needcopy, 1);
3698 * Set a particular packet option, as a sticky option or an ancillary data
3699 * item. "len" can be 0 only when it's a sticky option.
3700 * We have 4 cases of combination of "sticky" and "cmsg":
3701 * "sticky=0, cmsg=0": impossible
3702 * "sticky=0, cmsg=1": RFC2292 or rfc2292bis ancillary data
3703 * "sticky=1, cmsg=0": rfc2292bis socket option
3704 * "sticky=1, cmsg=1": RFC2292 socket option
3707 ip6_setpktoption(optname, buf, len, opt, priv, sticky, cmsg)
3708 int optname, len, priv, cmsg;
3710 struct ip6_pktopts *opt;
3713 if (!sticky && !cmsg) {
3715 printf("ip6_setpktoption: impossible case\n");
3721 * IPV6_2292xxx is for backward compatibility to RFC2292, and should
3722 * not be specified in the context of rfc2292bis. Conversely,
3723 * rfc2292bis types should not be specified in the context of RFC2292.
3728 case IPV6_2292PKTINFO:
3729 case IPV6_2292HOPLIMIT:
3730 case IPV6_2292NEXTHOP:
3731 case IPV6_2292HOPOPTS:
3732 case IPV6_2292DSTOPTS:
3733 case IPV6_2292RTHDR:
3734 case IPV6_2292PKTOPTIONS:
3735 return(ENOPROTOOPT);
3738 if (sticky && cmsg) {
3745 case IPV6_RTHDRDSTOPTS:
3747 case IPV6_REACHCONF:
3748 case IPV6_USE_MIN_MTU:
3752 return(ENOPROTOOPT);
3757 case IPV6_2292PKTINFO:
3760 struct ifnet *ifp = NULL;
3761 struct in6_pktinfo *pktinfo;
3763 if (len != sizeof(struct in6_pktinfo))
3766 pktinfo = (struct in6_pktinfo *)buf;
3769 * An application can clear any sticky IPV6_PKTINFO option by
3770 * doing a "regular" setsockopt with ipi6_addr being
3771 * in6addr_any and ipi6_ifindex being zero.
3772 * [rfc2292bis-02, Section 6]
3774 if (optname == IPV6_PKTINFO && opt->ip6po_pktinfo) {
3775 if (pktinfo->ipi6_ifindex == 0 &&
3776 IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
3777 ip6_clearpktopts(opt, optname);
3782 /* validate the interface index if specified. */
3783 if (pktinfo->ipi6_ifindex > if_index ||
3784 pktinfo->ipi6_ifindex < 0) {
3787 if (pktinfo->ipi6_ifindex) {
3788 #if defined(__FreeBSD__) && __FreeBSD__ >= 5
3789 ifp = ifnet_byindex(pktinfo->ipi6_ifindex);
3791 ifp = ifindex2ifnet[pktinfo->ipi6_ifindex];
3798 * We store the address anyway, and let in6_selectsrc()
3799 * validate the specified address. This is because ipi6_addr
3800 * may not have enough information about its scope zone, and
3801 * we may need additional information (such as outgoing
3802 * interface or the scope zone of a destination address) to
3803 * disambiguate the scope.
3804 * XXX: the delay of the validation may confuse the
3805 * application when it is used as a sticky option.
3808 if (opt->ip6po_pktinfo == NULL) {
3809 opt->ip6po_pktinfo = malloc(sizeof(*pktinfo),
3813 bcopy(pktinfo, opt->ip6po_pktinfo, sizeof(*pktinfo));
3815 opt->ip6po_pktinfo = pktinfo;
3819 case IPV6_2292HOPLIMIT:
3825 * rfc2292bis-03 obsoleted the usage of sticky IPV6_HOPLIMIT
3826 * to simplify the ordering among hoplimit options.
3828 if (optname == IPV6_HOPLIMIT && sticky)
3829 return(ENOPROTOOPT);
3831 if (len != sizeof(int))
3834 if (*hlimp < -1 || *hlimp > 255)
3837 opt->ip6po_hlim = *hlimp;
3842 if (len != sizeof(u_int8_t))
3845 opt->ip6po_tclass = *(u_int8_t *)buf;
3852 if (len != sizeof(int))
3854 tclass = *(int *)buf;
3855 if (tclass < -1 || tclass > 255)
3858 opt->ip6po_tclass = tclass;
3862 case IPV6_2292NEXTHOP:
3865 if (len == 0) { /* just remove the option */
3866 ip6_clearpktopts(opt, IPV6_NEXTHOP);
3870 /* check if cmsg_len is large enough for sa_len */
3871 if (len < sizeof(struct sockaddr) || len < *buf)
3874 switch (((struct sockaddr *)buf)->sa_family) {
3877 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)buf;
3880 if (sa6->sin6_len != sizeof(struct sockaddr_in6))
3883 if (IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr) ||
3884 IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) {
3887 if ((error = scope6_check_id(sa6, ip6_use_defzone))
3891 #ifndef SCOPEDROUTING
3892 sa6->sin6_scope_id = 0; /* XXX */
3896 case AF_LINK: /* should eventually be supported */
3898 return(EAFNOSUPPORT);
3901 /* turn off the previous option, then set the new option. */
3902 ip6_clearpktopts(opt, IPV6_NEXTHOP);
3904 opt->ip6po_nexthop = malloc(*buf, M_IP6OPT, M_WAITOK);
3905 bcopy(buf, opt->ip6po_nexthop, *buf);
3907 opt->ip6po_nexthop = (struct sockaddr *)buf;
3910 case IPV6_2292HOPOPTS:
3913 struct ip6_hbh *hbh;
3917 * XXX: We don't allow a non-privileged user to set ANY HbH
3918 * options, since per-option restriction has too much
3923 ip6_clearpktopts(opt, IPV6_HOPOPTS);
3924 break; /* just remove the option */
3927 /* message length validation */
3928 if (len < sizeof(struct ip6_hbh))
3930 hbh = (struct ip6_hbh *)buf;
3931 hbhlen = (hbh->ip6h_len + 1) << 3;
3935 /* turn off the previous option, then set the new option. */
3936 ip6_clearpktopts(opt, IPV6_HOPOPTS);
3938 opt->ip6po_hbh = malloc(hbhlen, M_IP6OPT, M_WAITOK);
3939 bcopy(hbh, opt->ip6po_hbh, hbhlen);
3941 opt->ip6po_hbh = hbh;
3946 case IPV6_2292DSTOPTS:
3948 case IPV6_RTHDRDSTOPTS:
3950 struct ip6_dest *dest, **newdest = NULL;
3955 ip6_clearpktopts(opt, optname);
3956 break; /* just remove the option */
3959 /* message length validation */
3960 if (len < sizeof(struct ip6_dest))
3962 dest = (struct ip6_dest *)buf;
3963 destlen = (dest->ip6d_len + 1) << 3;
3968 * Determine the position that the destination options header
3969 * should be inserted; before or after the routing header.
3972 case IPV6_2292DSTOPTS:
3974 * The old advacned API is ambiguous on this point.
3975 * Our approach is to determine the position based
3976 * according to the existence of a routing header.
3977 * Note, however, that this depends on the order of the
3978 * extension headers in the ancillary data; the 1st
3979 * part of the destination options header must appear
3980 * before the routing header in the ancillary data,
3982 * RFC2292bis solved the ambiguity by introducing
3983 * separate ancillary data or option types.
3985 if (opt->ip6po_rthdr == NULL)
3986 newdest = &opt->ip6po_dest1;
3988 newdest = &opt->ip6po_dest2;
3990 case IPV6_RTHDRDSTOPTS:
3991 newdest = &opt->ip6po_dest1;
3994 newdest = &opt->ip6po_dest2;
3998 /* turn off the previous option, then set the new option. */
3999 ip6_clearpktopts(opt, optname);
4001 *newdest = malloc(destlen, M_IP6OPT, M_WAITOK);
4002 bcopy(dest, *newdest, destlen);
4009 case IPV6_2292RTHDR:
4012 struct ip6_rthdr *rth;
4016 ip6_clearpktopts(opt, IPV6_RTHDR);
4017 break; /* just remove the option */
4020 /* message length validation */
4021 if (len < sizeof(struct ip6_rthdr))
4023 rth = (struct ip6_rthdr *)buf;
4024 rthlen = (rth->ip6r_len + 1) << 3;
4028 switch (rth->ip6r_type) {
4029 case IPV6_RTHDR_TYPE_0:
4030 if (rth->ip6r_len == 0) /* must contain one addr */
4032 if (rth->ip6r_len % 2) /* length must be even */
4034 if (rth->ip6r_len / 2 != rth->ip6r_segleft)
4038 return(EINVAL); /* not supported */
4041 /* turn off the previous option */
4042 ip6_clearpktopts(opt, IPV6_RTHDR);
4044 opt->ip6po_rthdr = malloc(rthlen, M_IP6OPT, M_WAITOK);
4045 bcopy(rth, opt->ip6po_rthdr, rthlen);
4047 opt->ip6po_rthdr = rth;
4052 case IPV6_REACHCONF:
4054 return(ENOPROTOOPT);
4058 * it looks dangerous to allow IPV6_REACHCONF to
4059 * normal user. it affects the ND state (system state)
4060 * and can affect communication by others - jinmei
4066 * we limit max # of subsequent userland reachability
4067 * conformation by using ln->ln_byhint.
4072 opt->ip6po_flags |= IP6PO_REACHCONF;
4075 case IPV6_USE_MIN_MTU:
4080 if (len != sizeof(int))
4085 case IPV6_USE_MIN_MTU:
4086 flag = IP6PO_MINMTU;
4089 flag = IP6PO_DONTFRAG;
4094 opt->ip6po_flags |= flag;
4096 opt->ip6po_flags &= ~flag;
4101 return(ENOPROTOOPT);
4102 } /* end of switch */
4108 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
4109 * packet to the input queue of a specified interface. Note that this
4110 * calls the output routine of the loopback "driver", but with an interface
4111 * pointer that might NOT be &loif -- easier than replicating that code here.
4114 ip6_mloopback(ifp, m, dst)
4117 struct sockaddr_in6 *dst;
4120 struct ip6_hdr *ip6;
4122 copym = m_copy(m, 0, M_COPYALL);
4127 * Make sure to deep-copy IPv6 header portion in case the data
4128 * is in an mbuf cluster, so that we can safely override the IPv6
4129 * header portion later.
4131 if ((copym->m_flags & M_EXT) != 0 ||
4132 copym->m_len < sizeof(struct ip6_hdr)) {
4133 copym = m_pullup(copym, sizeof(struct ip6_hdr));
4139 if (copym->m_len < sizeof(*ip6)) {
4145 ip6 = mtod(copym, struct ip6_hdr *);
4146 #ifndef SCOPEDROUTING
4148 * clear embedded scope identifiers if necessary.
4149 * in6_clearscope will touch the addresses only when necessary.
4151 in6_clearscope(&ip6->ip6_src);
4152 in6_clearscope(&ip6->ip6_dst);
4155 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
4156 #if (__FreeBSD_version >= 410000)
4157 (void)if_simloop(ifp, copym, dst->sin6_family, (int)NULL);
4159 (void)if_simloop(ifp, copym, (struct sockaddr *)dst, NULL);
4162 (void)looutput(ifp, copym, (struct sockaddr *)dst, NULL);
4167 * Chop IPv6 header off from the payload.
4170 ip6_splithdr(m, exthdrs)
4172 struct ip6_exthdrs *exthdrs;
4175 struct ip6_hdr *ip6;
4177 ip6 = mtod(m, struct ip6_hdr *);
4178 if (m->m_len > sizeof(*ip6)) {
4179 MGETHDR(mh, M_DONTWAIT, MT_HEADER);
4185 M_MOVE_PKTHDR(mh, m);
4187 M_COPY_PKTHDR(mh, m);
4189 MH_ALIGN(mh, sizeof(*ip6));
4190 m->m_flags &= ~M_PKTHDR;
4191 m->m_len -= sizeof(*ip6);
4192 m->m_data += sizeof(*ip6);
4195 m->m_len = sizeof(*ip6);
4196 bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
4198 exthdrs->ip6e_ip6 = m;
4203 * Compute IPv6 extension header length.
4205 #ifdef HAVE_NRL_INPCB
4206 # define in6pcb inpcb
4207 # define in6p_outputopts inp_outputopts6
4211 struct in6pcb *in6p;
4215 if (!in6p->in6p_outputopts)
4220 (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
4222 len += elen(in6p->in6p_outputopts->ip6po_hbh);
4223 if (in6p->in6p_outputopts->ip6po_rthdr)
4224 /* dest1 is valid with rthdr only */
4225 len += elen(in6p->in6p_outputopts->ip6po_dest1);
4226 len += elen(in6p->in6p_outputopts->ip6po_rthdr);
4227 len += elen(in6p->in6p_outputopts->ip6po_dest2);
4231 #ifdef HAVE_NRL_INPCB
4233 # undef in6p_outputopts