ip6_output.c revision 120913
1/*	$FreeBSD: head/sys/netinet6/ip6_output.c 120913 2003-10-08 18:26:08Z ume $	*/
2/*	$KAME: ip6_output.c,v 1.279 2002/01/26 06:12:30 jinmei 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. All advertising materials mentioning features or use of this software
46 *    must display the following acknowledgement:
47 *	This product includes software developed by the University of
48 *	California, Berkeley and its contributors.
49 * 4. Neither the name of the University nor the names of its contributors
50 *    may be used to endorse or promote products derived from this software
51 *    without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE.
64 *
65 *	@(#)ip_output.c	8.3 (Berkeley) 1/21/94
66 */
67
68#include "opt_ip6fw.h"
69#include "opt_inet.h"
70#include "opt_inet6.h"
71#include "opt_ipsec.h"
72#include "opt_pfil_hooks.h"
73#include "opt_random_ip_id.h"
74
75#include <sys/param.h>
76#include <sys/malloc.h>
77#include <sys/mbuf.h>
78#include <sys/proc.h>
79#include <sys/errno.h>
80#include <sys/protosw.h>
81#include <sys/socket.h>
82#include <sys/socketvar.h>
83#include <sys/systm.h>
84#include <sys/kernel.h>
85
86#include <net/if.h>
87#include <net/route.h>
88#ifdef PFIL_HOOKS
89#include <net/pfil.h>
90#endif
91
92#include <netinet/in.h>
93#include <netinet/in_var.h>
94#include <netinet6/in6_var.h>
95#include <netinet/ip6.h>
96#include <netinet/icmp6.h>
97#include <netinet6/ip6_var.h>
98#include <netinet/in_pcb.h>
99#include <netinet6/nd6.h>
100
101#ifdef IPSEC
102#include <netinet6/ipsec.h>
103#ifdef INET6
104#include <netinet6/ipsec6.h>
105#endif
106#include <netkey/key.h>
107#endif /* IPSEC */
108
109#ifdef FAST_IPSEC
110#include <netipsec/ipsec.h>
111#include <netipsec/ipsec6.h>
112#include <netipsec/key.h>
113#endif /* FAST_IPSEC */
114
115#include <netinet6/ip6_fw.h>
116
117#include <net/net_osdep.h>
118
119#include <netinet6/ip6protosw.h>
120
121static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options");
122
123struct ip6_exthdrs {
124	struct mbuf *ip6e_ip6;
125	struct mbuf *ip6e_hbh;
126	struct mbuf *ip6e_dest1;
127	struct mbuf *ip6e_rthdr;
128	struct mbuf *ip6e_dest2;
129};
130
131static int ip6_pcbopts __P((struct ip6_pktopts **, struct mbuf *,
132	struct socket *, struct sockopt *));
133static int ip6_setmoptions __P((int, struct ip6_moptions **, struct mbuf *));
134static int ip6_getmoptions __P((int, struct ip6_moptions *, struct mbuf **));
135static int ip6_copyexthdr __P((struct mbuf **, caddr_t, int));
136static int ip6_insertfraghdr __P((struct mbuf *, struct mbuf *, int,
137	struct ip6_frag **));
138static int ip6_insert_jumboopt __P((struct ip6_exthdrs *, u_int32_t));
139static int ip6_splithdr __P((struct mbuf *, struct ip6_exthdrs *));
140
141
142/*
143 * IP6 output. The packet in mbuf chain m contains a skeletal IP6
144 * header (with pri, len, nxt, hlim, src, dst).
145 * This function may modify ver and hlim only.
146 * The mbuf chain containing the packet will be freed.
147 * The mbuf opt, if present, will not be freed.
148 *
149 * type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and
150 * nd_ifinfo.linkmtu is u_int32_t.  so we use u_long to hold largest one,
151 * which is rt_rmx.rmx_mtu.
152 */
153int
154ip6_output(m0, opt, ro, flags, im6o, ifpp, inp)
155	struct mbuf *m0;
156	struct ip6_pktopts *opt;
157	struct route_in6 *ro;
158	int flags;
159	struct ip6_moptions *im6o;
160	struct ifnet **ifpp;		/* XXX: just for statistics */
161	struct inpcb *inp;
162{
163	struct ip6_hdr *ip6, *mhip6;
164	struct ifnet *ifp, *origifp;
165	struct mbuf *m = m0;
166	int hlen, tlen, len, off;
167	struct route_in6 ip6route;
168	struct sockaddr_in6 *dst;
169	int error = 0;
170	struct in6_ifaddr *ia = NULL;
171	u_long mtu;
172	u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
173	struct ip6_exthdrs exthdrs;
174	struct in6_addr finaldst;
175	struct route_in6 *ro_pmtu = NULL;
176	int hdrsplit = 0;
177	int needipsec = 0;
178#ifdef IPSEC
179	int needipsectun = 0;
180	struct secpolicy *sp = NULL;
181
182	ip6 = mtod(m, struct ip6_hdr *);
183#endif /* IPSEC */
184#ifdef FAST_IPSEC
185	int needipsectun = 0;
186	struct secpolicy *sp = NULL;
187
188	ip6 = mtod(m, struct ip6_hdr *);
189#endif /* FAST_IPSEC */
190
191#define MAKE_EXTHDR(hp, mp)						\
192    do {								\
193	if (hp) {							\
194		struct ip6_ext *eh = (struct ip6_ext *)(hp);		\
195		error = ip6_copyexthdr((mp), (caddr_t)(hp),		\
196		    ((eh)->ip6e_len + 1) << 3);				\
197		if (error)						\
198			goto freehdrs;					\
199	}								\
200    } while (/*CONSTCOND*/ 0)
201
202	bzero(&exthdrs, sizeof(exthdrs));
203
204	if (opt) {
205		/* Hop-by-Hop options header */
206		MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
207		/* Destination options header(1st part) */
208		MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
209		/* Routing header */
210		MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
211		/* Destination options header(2nd part) */
212		MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
213	}
214
215#ifdef IPSEC
216	/* get a security policy for this packet */
217	if (inp == NULL)
218		sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
219	else
220		sp = ipsec6_getpolicybypcb(m, IPSEC_DIR_OUTBOUND, inp, &error);
221
222	if (sp == NULL) {
223		ipsec6stat.out_inval++;
224		goto freehdrs;
225	}
226
227	error = 0;
228
229	/* check policy */
230	switch (sp->policy) {
231	case IPSEC_POLICY_DISCARD:
232		/*
233		 * This packet is just discarded.
234		 */
235		ipsec6stat.out_polvio++;
236		goto freehdrs;
237
238	case IPSEC_POLICY_BYPASS:
239	case IPSEC_POLICY_NONE:
240		/* no need to do IPsec. */
241		needipsec = 0;
242		break;
243
244	case IPSEC_POLICY_IPSEC:
245		if (sp->req == NULL) {
246			/* acquire a policy */
247			error = key_spdacquire(sp);
248			goto freehdrs;
249		}
250		needipsec = 1;
251		break;
252
253	case IPSEC_POLICY_ENTRUST:
254	default:
255		printf("ip6_output: Invalid policy found. %d\n", sp->policy);
256	}
257#endif /* IPSEC */
258#ifdef FAST_IPSEC
259	/* get a security policy for this packet */
260	if (inp == NULL)
261		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error);
262	else
263		sp = ipsec_getpolicybysock(m, IPSEC_DIR_OUTBOUND, inp, &error);
264
265	if (sp == NULL) {
266		newipsecstat.ips_out_inval++;
267		goto freehdrs;
268	}
269
270	error = 0;
271
272	/* check policy */
273	switch (sp->policy) {
274	case IPSEC_POLICY_DISCARD:
275		/*
276		 * This packet is just discarded.
277		 */
278		newipsecstat.ips_out_polvio++;
279		goto freehdrs;
280
281	case IPSEC_POLICY_BYPASS:
282	case IPSEC_POLICY_NONE:
283		/* no need to do IPsec. */
284		needipsec = 0;
285		break;
286
287	case IPSEC_POLICY_IPSEC:
288		if (sp->req == NULL) {
289			/* acquire a policy */
290			error = key_spdacquire(sp);
291			goto freehdrs;
292		}
293		needipsec = 1;
294		break;
295
296	case IPSEC_POLICY_ENTRUST:
297	default:
298		printf("ip6_output: Invalid policy found. %d\n", sp->policy);
299	}
300#endif /* FAST_IPSEC */
301
302	/*
303	 * Calculate the total length of the extension header chain.
304	 * Keep the length of the unfragmentable part for fragmentation.
305	 */
306	optlen = 0;
307	if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
308	if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
309	if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
310	unfragpartlen = optlen + sizeof(struct ip6_hdr);
311	/* NOTE: we don't add AH/ESP length here. do that later. */
312	if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
313
314	/*
315	 * If we need IPsec, or there is at least one extension header,
316	 * separate IP6 header from the payload.
317	 */
318	if ((needipsec || optlen) && !hdrsplit) {
319		if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
320			m = NULL;
321			goto freehdrs;
322		}
323		m = exthdrs.ip6e_ip6;
324		hdrsplit++;
325	}
326
327	/* adjust pointer */
328	ip6 = mtod(m, struct ip6_hdr *);
329
330	/* adjust mbuf packet header length */
331	m->m_pkthdr.len += optlen;
332	plen = m->m_pkthdr.len - sizeof(*ip6);
333
334	/* If this is a jumbo payload, insert a jumbo payload option. */
335	if (plen > IPV6_MAXPACKET) {
336		if (!hdrsplit) {
337			if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
338				m = NULL;
339				goto freehdrs;
340			}
341			m = exthdrs.ip6e_ip6;
342			hdrsplit++;
343		}
344		/* adjust pointer */
345		ip6 = mtod(m, struct ip6_hdr *);
346		if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
347			goto freehdrs;
348		ip6->ip6_plen = 0;
349	} else
350		ip6->ip6_plen = htons(plen);
351
352	/*
353	 * Concatenate headers and fill in next header fields.
354	 * Here we have, on "m"
355	 *	IPv6 payload
356	 * and we insert headers accordingly.  Finally, we should be getting:
357	 *	IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
358	 *
359	 * during the header composing process, "m" points to IPv6 header.
360	 * "mprev" points to an extension header prior to esp.
361	 */
362	{
363		u_char *nexthdrp = &ip6->ip6_nxt;
364		struct mbuf *mprev = m;
365
366		/*
367		 * we treat dest2 specially.  this makes IPsec processing
368		 * much easier.  the goal here is to make mprev point the
369		 * mbuf prior to dest2.
370		 *
371		 * result: IPv6 dest2 payload
372		 * m and mprev will point to IPv6 header.
373		 */
374		if (exthdrs.ip6e_dest2) {
375			if (!hdrsplit)
376				panic("assumption failed: hdr not split");
377			exthdrs.ip6e_dest2->m_next = m->m_next;
378			m->m_next = exthdrs.ip6e_dest2;
379			*mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
380			ip6->ip6_nxt = IPPROTO_DSTOPTS;
381		}
382
383#define MAKE_CHAIN(m, mp, p, i)\
384    do {\
385	if (m) {\
386		if (!hdrsplit) \
387			panic("assumption failed: hdr not split"); \
388		*mtod((m), u_char *) = *(p);\
389		*(p) = (i);\
390		p = mtod((m), u_char *);\
391		(m)->m_next = (mp)->m_next;\
392		(mp)->m_next = (m);\
393		(mp) = (m);\
394	}\
395    } while (/*CONSTCOND*/ 0)
396		/*
397		 * result: IPv6 hbh dest1 rthdr dest2 payload
398		 * m will point to IPv6 header.  mprev will point to the
399		 * extension header prior to dest2 (rthdr in the above case).
400		 */
401		MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
402		MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
403		    IPPROTO_DSTOPTS);
404		MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
405		    IPPROTO_ROUTING);
406
407#if defined(IPSEC) || defined(FAST_IPSEC)
408		if (!needipsec)
409			goto skip_ipsec2;
410
411		/*
412		 * pointers after IPsec headers are not valid any more.
413		 * other pointers need a great care too.
414		 * (IPsec routines should not mangle mbufs prior to AH/ESP)
415		 */
416		exthdrs.ip6e_dest2 = NULL;
417
418	    {
419		struct ip6_rthdr *rh = NULL;
420		int segleft_org = 0;
421		struct ipsec_output_state state;
422
423		if (exthdrs.ip6e_rthdr) {
424			rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
425			segleft_org = rh->ip6r_segleft;
426			rh->ip6r_segleft = 0;
427		}
428
429		bzero(&state, sizeof(state));
430		state.m = m;
431		error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags,
432		    &needipsectun);
433		m = state.m;
434		if (error) {
435			/* mbuf is already reclaimed in ipsec6_output_trans. */
436			m = NULL;
437			switch (error) {
438			case EHOSTUNREACH:
439			case ENETUNREACH:
440			case EMSGSIZE:
441			case ENOBUFS:
442			case ENOMEM:
443				break;
444			default:
445				printf("ip6_output (ipsec): error code %d\n", error);
446				/* FALLTHROUGH */
447			case ENOENT:
448				/* don't show these error codes to the user */
449				error = 0;
450				break;
451			}
452			goto bad;
453		}
454		if (exthdrs.ip6e_rthdr) {
455			/* ah6_output doesn't modify mbuf chain */
456			rh->ip6r_segleft = segleft_org;
457		}
458	    }
459skip_ipsec2:;
460#endif
461	}
462
463	/*
464	 * If there is a routing header, replace the destination address field
465	 * with the first hop of the routing header.
466	 */
467	if (exthdrs.ip6e_rthdr) {
468		struct ip6_rthdr *rh =
469			(struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
470						  struct ip6_rthdr *));
471		struct ip6_rthdr0 *rh0;
472
473		finaldst = ip6->ip6_dst;
474		switch (rh->ip6r_type) {
475		case IPV6_RTHDR_TYPE_0:
476			 rh0 = (struct ip6_rthdr0 *)rh;
477			 ip6->ip6_dst = rh0->ip6r0_addr[0];
478			 bcopy((caddr_t)&rh0->ip6r0_addr[1],
479			       (caddr_t)&rh0->ip6r0_addr[0],
480			       sizeof(struct in6_addr)*(rh0->ip6r0_segleft - 1)
481				 );
482			 rh0->ip6r0_addr[rh0->ip6r0_segleft - 1] = finaldst;
483			 break;
484		default:	/* is it possible? */
485			 error = EINVAL;
486			 goto bad;
487		}
488	}
489
490	/* Source address validation */
491	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
492	    (flags & IPV6_DADOUTPUT) == 0) {
493		error = EOPNOTSUPP;
494		ip6stat.ip6s_badscope++;
495		goto bad;
496	}
497	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
498		error = EOPNOTSUPP;
499		ip6stat.ip6s_badscope++;
500		goto bad;
501	}
502
503	ip6stat.ip6s_localout++;
504
505	/*
506	 * Route packet.
507	 */
508	if (ro == 0) {
509		ro = &ip6route;
510		bzero((caddr_t)ro, sizeof(*ro));
511	}
512	ro_pmtu = ro;
513	if (opt && opt->ip6po_rthdr)
514		ro = &opt->ip6po_route;
515	dst = (struct sockaddr_in6 *)&ro->ro_dst;
516
517	/*
518	 * If there is a cached route,
519	 * check that it is to the same destination
520	 * and is still up. If not, free it and try again.
521	 */
522	if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
523			 dst->sin6_family != AF_INET6 ||
524			 !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) {
525		RTFREE(ro->ro_rt);
526		ro->ro_rt = (struct rtentry *)0;
527	}
528	if (ro->ro_rt == 0) {
529		bzero(dst, sizeof(*dst));
530		dst->sin6_family = AF_INET6;
531		dst->sin6_len = sizeof(struct sockaddr_in6);
532		dst->sin6_addr = ip6->ip6_dst;
533#ifdef SCOPEDROUTING
534		/* XXX: sin6_scope_id should already be fixed at this point */
535		if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
536			dst->sin6_scope_id = ntohs(dst->sin6_addr.s6_addr16[1]);
537#endif
538	}
539#if defined(IPSEC) || defined(FAST_IPSEC)
540	if (needipsec && needipsectun) {
541		struct ipsec_output_state state;
542
543		/*
544		 * All the extension headers will become inaccessible
545		 * (since they can be encrypted).
546		 * Don't panic, we need no more updates to extension headers
547		 * on inner IPv6 packet (since they are now encapsulated).
548		 *
549		 * IPv6 [ESP|AH] IPv6 [extension headers] payload
550		 */
551		bzero(&exthdrs, sizeof(exthdrs));
552		exthdrs.ip6e_ip6 = m;
553
554		bzero(&state, sizeof(state));
555		state.m = m;
556		state.ro = (struct route *)ro;
557		state.dst = (struct sockaddr *)dst;
558
559		error = ipsec6_output_tunnel(&state, sp, flags);
560
561		m = state.m;
562		ro = (struct route_in6 *)state.ro;
563		dst = (struct sockaddr_in6 *)state.dst;
564		if (error) {
565			/* mbuf is already reclaimed in ipsec6_output_tunnel. */
566			m0 = m = NULL;
567			m = NULL;
568			switch (error) {
569			case EHOSTUNREACH:
570			case ENETUNREACH:
571			case EMSGSIZE:
572			case ENOBUFS:
573			case ENOMEM:
574				break;
575			default:
576				printf("ip6_output (ipsec): error code %d\n", error);
577				/* FALLTHROUGH */
578			case ENOENT:
579				/* don't show these error codes to the user */
580				error = 0;
581				break;
582			}
583			goto bad;
584		}
585
586		exthdrs.ip6e_ip6 = m;
587	}
588#endif /* IPSEC */
589
590	if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
591		/* Unicast */
592
593#define ifatoia6(ifa)	((struct in6_ifaddr *)(ifa))
594#define sin6tosa(sin6)	((struct sockaddr *)(sin6))
595		/* xxx
596		 * interface selection comes here
597		 * if an interface is specified from an upper layer,
598		 * ifp must point it.
599		 */
600		if (ro->ro_rt == 0) {
601			/*
602			 * non-bsdi always clone routes, if parent is
603			 * PRF_CLONING.
604			 */
605			rtalloc((struct route *)ro);
606		}
607		if (ro->ro_rt == 0) {
608			ip6stat.ip6s_noroute++;
609			error = EHOSTUNREACH;
610			/* XXX in6_ifstat_inc(ifp, ifs6_out_discard); */
611			goto bad;
612		}
613		/* XXX rt not locked */
614		ia = ifatoia6(ro->ro_rt->rt_ifa);
615		ifp = ro->ro_rt->rt_ifp;
616		ro->ro_rt->rt_use++;
617		if (ro->ro_rt->rt_flags & RTF_GATEWAY)
618			dst = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
619		m->m_flags &= ~(M_BCAST | M_MCAST);	/* just in case */
620
621		in6_ifstat_inc(ifp, ifs6_out_request);
622
623		/*
624		 * Check if the outgoing interface conflicts with
625		 * the interface specified by ifi6_ifindex (if specified).
626		 * Note that loopback interface is always okay.
627		 * (this may happen when we are sending a packet to one of
628		 *  our own addresses.)
629		 */
630		if (opt && opt->ip6po_pktinfo
631		 && opt->ip6po_pktinfo->ipi6_ifindex) {
632			if (!(ifp->if_flags & IFF_LOOPBACK)
633			 && ifp->if_index != opt->ip6po_pktinfo->ipi6_ifindex) {
634				ip6stat.ip6s_noroute++;
635				in6_ifstat_inc(ifp, ifs6_out_discard);
636				error = EHOSTUNREACH;
637				goto bad;
638			}
639		}
640
641		if (opt && opt->ip6po_hlim != -1)
642			ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
643	} else {
644		/* Multicast */
645		struct	in6_multi *in6m;
646
647		m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
648
649		/*
650		 * See if the caller provided any multicast options
651		 */
652		ifp = NULL;
653		if (im6o != NULL) {
654			ip6->ip6_hlim = im6o->im6o_multicast_hlim;
655			if (im6o->im6o_multicast_ifp != NULL)
656				ifp = im6o->im6o_multicast_ifp;
657		} else
658			ip6->ip6_hlim = ip6_defmcasthlim;
659
660		/*
661		 * See if the caller provided the outgoing interface
662		 * as an ancillary data.
663		 * Boundary check for ifindex is assumed to be already done.
664		 */
665		if (opt && opt->ip6po_pktinfo && opt->ip6po_pktinfo->ipi6_ifindex)
666			ifp = ifnet_byindex(opt->ip6po_pktinfo->ipi6_ifindex);
667
668		/*
669		 * If the destination is a node-local scope multicast,
670		 * the packet should be loop-backed only.
671		 */
672		if (IN6_IS_ADDR_MC_NODELOCAL(&ip6->ip6_dst)) {
673			/*
674			 * If the outgoing interface is already specified,
675			 * it should be a loopback interface.
676			 */
677			if (ifp && (ifp->if_flags & IFF_LOOPBACK) == 0) {
678				ip6stat.ip6s_badscope++;
679				error = ENETUNREACH; /* XXX: better error? */
680				/* XXX correct ifp? */
681				in6_ifstat_inc(ifp, ifs6_out_discard);
682				goto bad;
683			} else {
684				ifp = &loif[0];
685			}
686		}
687
688		if (opt && opt->ip6po_hlim != -1)
689			ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
690
691		/*
692		 * If caller did not provide an interface lookup a
693		 * default in the routing table.  This is either a
694		 * default for the speicfied group (i.e. a host
695		 * route), or a multicast default (a route for the
696		 * ``net'' ff00::/8).
697		 */
698		if (ifp == NULL) {
699			if (ro->ro_rt == 0)
700				ro->ro_rt = rtalloc1((struct sockaddr *)
701						&ro->ro_dst, 0, 0UL);
702			else
703				RT_LOCK(ro->ro_rt);
704			if (ro->ro_rt == 0) {
705				ip6stat.ip6s_noroute++;
706				error = EHOSTUNREACH;
707				/* XXX in6_ifstat_inc(ifp, ifs6_out_discard) */
708				goto bad;
709			}
710			ia = ifatoia6(ro->ro_rt->rt_ifa);
711			ifp = ro->ro_rt->rt_ifp;
712			ro->ro_rt->rt_use++;
713			RT_UNLOCK(ro->ro_rt);
714		}
715
716		if ((flags & IPV6_FORWARDING) == 0)
717			in6_ifstat_inc(ifp, ifs6_out_request);
718		in6_ifstat_inc(ifp, ifs6_out_mcast);
719
720		/*
721		 * Confirm that the outgoing interface supports multicast.
722		 */
723		if ((ifp->if_flags & IFF_MULTICAST) == 0) {
724			ip6stat.ip6s_noroute++;
725			in6_ifstat_inc(ifp, ifs6_out_discard);
726			error = ENETUNREACH;
727			goto bad;
728		}
729		IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m);
730		if (in6m != NULL &&
731		   (im6o == NULL || im6o->im6o_multicast_loop)) {
732			/*
733			 * If we belong to the destination multicast group
734			 * on the outgoing interface, and the caller did not
735			 * forbid loopback, loop back a copy.
736			 */
737			ip6_mloopback(ifp, m, dst);
738		} else {
739			/*
740			 * If we are acting as a multicast router, perform
741			 * multicast forwarding as if the packet had just
742			 * arrived on the interface to which we are about
743			 * to send.  The multicast forwarding function
744			 * recursively calls this function, using the
745			 * IPV6_FORWARDING flag to prevent infinite recursion.
746			 *
747			 * Multicasts that are looped back by ip6_mloopback(),
748			 * above, will be forwarded by the ip6_input() routine,
749			 * if necessary.
750			 */
751			if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
752				if (ip6_mforward(ip6, ifp, m) != 0) {
753					m_freem(m);
754					goto done;
755				}
756			}
757		}
758		/*
759		 * Multicasts with a hoplimit of zero may be looped back,
760		 * above, but must not be transmitted on a network.
761		 * Also, multicasts addressed to the loopback interface
762		 * are not sent -- the above call to ip6_mloopback() will
763		 * loop back a copy if this host actually belongs to the
764		 * destination group on the loopback interface.
765		 */
766		if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK)) {
767			m_freem(m);
768			goto done;
769		}
770	}
771
772	/*
773	 * Fill the outgoing inteface to tell the upper layer
774	 * to increment per-interface statistics.
775	 */
776	if (ifpp)
777		*ifpp = ifp;
778
779	/*
780	 * Determine path MTU.
781	 */
782	if (ro_pmtu != ro) {
783		/* The first hop and the final destination may differ. */
784		struct sockaddr_in6 *sin6_fin =
785			(struct sockaddr_in6 *)&ro_pmtu->ro_dst;
786		if (ro_pmtu->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
787				       !IN6_ARE_ADDR_EQUAL(&sin6_fin->sin6_addr,
788							   &finaldst))) {
789			RTFREE(ro_pmtu->ro_rt);
790			ro_pmtu->ro_rt = (struct rtentry *)0;
791		}
792		if (ro_pmtu->ro_rt == 0) {
793			bzero(sin6_fin, sizeof(*sin6_fin));
794			sin6_fin->sin6_family = AF_INET6;
795			sin6_fin->sin6_len = sizeof(struct sockaddr_in6);
796			sin6_fin->sin6_addr = finaldst;
797
798			rtalloc((struct route *)ro_pmtu);
799		}
800	}
801	if (ro_pmtu->ro_rt != NULL) {
802		u_int32_t ifmtu = nd_ifinfo[ifp->if_index].linkmtu;
803
804		mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
805		if (mtu > ifmtu || mtu == 0) {
806			/*
807			 * The MTU on the route is larger than the MTU on
808			 * the interface!  This shouldn't happen, unless the
809			 * MTU of the interface has been changed after the
810			 * interface was brought up.  Change the MTU in the
811			 * route to match the interface MTU (as long as the
812			 * field isn't locked).
813			 *
814			 * if MTU on the route is 0, we need to fix the MTU.
815			 * this case happens with path MTU discovery timeouts.
816			 */
817			 mtu = ifmtu;
818			 if ((ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU) == 0)
819				 ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; /* XXX */
820		}
821	} else {
822		mtu = nd_ifinfo[ifp->if_index].linkmtu;
823	}
824
825	/*
826	 * advanced API (IPV6_USE_MIN_MTU) overrides mtu setting
827	 */
828	if ((flags & IPV6_MINMTU) != 0 && mtu > IPV6_MMTU)
829		mtu = IPV6_MMTU;
830
831	/* Fake scoped addresses */
832	if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
833		/*
834		 * If source or destination address is a scoped address, and
835		 * the packet is going to be sent to a loopback interface,
836		 * we should keep the original interface.
837		 */
838
839		/*
840		 * XXX: this is a very experimental and temporary solution.
841		 * We eventually have sockaddr_in6 and use the sin6_scope_id
842		 * field of the structure here.
843		 * We rely on the consistency between two scope zone ids
844		 * of source and destination, which should already be assured.
845		 * Larger scopes than link will be supported in the future.
846		 */
847		origifp = NULL;
848		if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
849			origifp = ifnet_byindex(ntohs(ip6->ip6_src.s6_addr16[1]));
850		else if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
851			origifp = ifnet_byindex(ntohs(ip6->ip6_dst.s6_addr16[1]));
852		/*
853		 * XXX: origifp can be NULL even in those two cases above.
854		 * For example, if we remove the (only) link-local address
855		 * from the loopback interface, and try to send a link-local
856		 * address without link-id information.  Then the source
857		 * address is ::1, and the destination address is the
858		 * link-local address with its s6_addr16[1] being zero.
859		 * What is worse, if the packet goes to the loopback interface
860		 * by a default rejected route, the null pointer would be
861		 * passed to looutput, and the kernel would hang.
862		 * The following last resort would prevent such disaster.
863		 */
864		if (origifp == NULL)
865			origifp = ifp;
866	}
867	else
868		origifp = ifp;
869#ifndef SCOPEDROUTING
870	/*
871	 * clear embedded scope identifiers if necessary.
872	 * in6_clearscope will touch the addresses only when necessary.
873	 */
874	in6_clearscope(&ip6->ip6_src);
875	in6_clearscope(&ip6->ip6_dst);
876#endif
877
878	/*
879	 * Check with the firewall...
880	 */
881	if (ip6_fw_enable && ip6_fw_chk_ptr) {
882		u_short port = 0;
883		m->m_pkthdr.rcvif = NULL;	/* XXX */
884		/* If ipfw says divert, we have to just drop packet */
885		if ((*ip6_fw_chk_ptr)(&ip6, ifp, &port, &m)) {
886			m_freem(m);
887			goto done;
888		}
889		if (!m) {
890			error = EACCES;
891			goto done;
892		}
893	}
894
895	/*
896	 * If the outgoing packet contains a hop-by-hop options header,
897	 * it must be examined and processed even by the source node.
898	 * (RFC 2460, section 4.)
899	 */
900	if (exthdrs.ip6e_hbh) {
901		struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
902		u_int32_t dummy1; /* XXX unused */
903		u_int32_t dummy2; /* XXX unused */
904
905#ifdef DIAGNOSTIC
906		if ((hbh->ip6h_len + 1) << 3 > exthdrs.ip6e_hbh->m_len)
907			panic("ip6e_hbh is not continuous");
908#endif
909		/*
910		 *  XXX: if we have to send an ICMPv6 error to the sender,
911		 *       we need the M_LOOP flag since icmp6_error() expects
912		 *       the IPv6 and the hop-by-hop options header are
913		 *       continuous unless the flag is set.
914		 */
915		m->m_flags |= M_LOOP;
916		m->m_pkthdr.rcvif = ifp;
917		if (ip6_process_hopopts(m, (u_int8_t *)(hbh + 1),
918		    ((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh),
919		    &dummy1, &dummy2) < 0) {
920			/* m was already freed at this point */
921			error = EINVAL;/* better error? */
922			goto done;
923		}
924		m->m_flags &= ~M_LOOP; /* XXX */
925		m->m_pkthdr.rcvif = NULL;
926	}
927
928#ifdef PFIL_HOOKS
929	/*
930	 * Run through list of hooks for output packets.
931	 */
932	error = pfil_run_hooks(&inet6_pfil_hook, &m, ifp, PFIL_OUT);
933	if (error != 0 || m == NULL)
934		goto done;
935	ip6 = mtod(m, struct ip6_hdr *);
936#endif /* PFIL_HOOKS */
937
938	/*
939	 * Send the packet to the outgoing interface.
940	 * If necessary, do IPv6 fragmentation before sending.
941	 */
942	tlen = m->m_pkthdr.len;
943	if (tlen <= mtu
944#ifdef notyet
945	    /*
946	     * On any link that cannot convey a 1280-octet packet in one piece,
947	     * link-specific fragmentation and reassembly must be provided at
948	     * a layer below IPv6. [RFC 2460, sec.5]
949	     * Thus if the interface has ability of link-level fragmentation,
950	     * we can just send the packet even if the packet size is
951	     * larger than the link's MTU.
952	     * XXX: IFF_FRAGMENTABLE (or such) flag has not been defined yet...
953	     */
954
955	    || ifp->if_flags & IFF_FRAGMENTABLE
956#endif
957	    )
958	{
959 		/* Record statistics for this interface address. */
960 		if (ia && !(flags & IPV6_FORWARDING)) {
961 			ia->ia_ifa.if_opackets++;
962 			ia->ia_ifa.if_obytes += m->m_pkthdr.len;
963 		}
964#ifdef IPSEC
965		/* clean ipsec history once it goes out of the node */
966		ipsec_delaux(m);
967#endif
968		error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
969		goto done;
970	} else if (mtu < IPV6_MMTU) {
971		/*
972		 * note that path MTU is never less than IPV6_MMTU
973		 * (see icmp6_input).
974		 */
975		error = EMSGSIZE;
976		in6_ifstat_inc(ifp, ifs6_out_fragfail);
977		goto bad;
978	} else if (ip6->ip6_plen == 0) {
979		/* jumbo payload cannot be fragmented */
980		error = EMSGSIZE;
981		in6_ifstat_inc(ifp, ifs6_out_fragfail);
982		goto bad;
983	} else {
984		struct mbuf **mnext, *m_frgpart;
985		struct ip6_frag *ip6f;
986#ifdef RANDOM_IP_ID
987		u_int32_t id = htonl(ip6_randomid());
988#else
989		u_int32_t id = htonl(ip6_id++);
990#endif
991		u_char nextproto;
992
993		/*
994		 * Too large for the destination or interface;
995		 * fragment if possible.
996		 * Must be able to put at least 8 bytes per fragment.
997		 */
998		hlen = unfragpartlen;
999		if (mtu > IPV6_MAXPACKET)
1000			mtu = IPV6_MAXPACKET;
1001
1002		len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
1003		if (len < 8) {
1004			error = EMSGSIZE;
1005			in6_ifstat_inc(ifp, ifs6_out_fragfail);
1006			goto bad;
1007		}
1008
1009		mnext = &m->m_nextpkt;
1010
1011		/*
1012		 * Change the next header field of the last header in the
1013		 * unfragmentable part.
1014		 */
1015		if (exthdrs.ip6e_rthdr) {
1016			nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
1017			*mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
1018		} else if (exthdrs.ip6e_dest1) {
1019			nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
1020			*mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
1021		} else if (exthdrs.ip6e_hbh) {
1022			nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
1023			*mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
1024		} else {
1025			nextproto = ip6->ip6_nxt;
1026			ip6->ip6_nxt = IPPROTO_FRAGMENT;
1027		}
1028
1029		/*
1030		 * Loop through length of segment after first fragment,
1031		 * make new header and copy data of each part and link onto
1032		 * chain.
1033		 */
1034		m0 = m;
1035		for (off = hlen; off < tlen; off += len) {
1036			MGETHDR(m, M_DONTWAIT, MT_HEADER);
1037			if (!m) {
1038				error = ENOBUFS;
1039				ip6stat.ip6s_odropped++;
1040				goto sendorfree;
1041			}
1042			m->m_pkthdr.rcvif = NULL;
1043			m->m_flags = m0->m_flags & M_COPYFLAGS;
1044			*mnext = m;
1045			mnext = &m->m_nextpkt;
1046			m->m_data += max_linkhdr;
1047			mhip6 = mtod(m, struct ip6_hdr *);
1048			*mhip6 = *ip6;
1049			m->m_len = sizeof(*mhip6);
1050			error = ip6_insertfraghdr(m0, m, hlen, &ip6f);
1051			if (error) {
1052				ip6stat.ip6s_odropped++;
1053				goto sendorfree;
1054			}
1055			ip6f->ip6f_offlg = htons((u_short)((off - hlen) & ~7));
1056			if (off + len >= tlen)
1057				len = tlen - off;
1058			else
1059				ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
1060			mhip6->ip6_plen = htons((u_short)(len + hlen +
1061			    sizeof(*ip6f) - sizeof(struct ip6_hdr)));
1062			if ((m_frgpart = m_copy(m0, off, len)) == 0) {
1063				error = ENOBUFS;
1064				ip6stat.ip6s_odropped++;
1065				goto sendorfree;
1066			}
1067			m_cat(m, m_frgpart);
1068			m->m_pkthdr.len = len + hlen + sizeof(*ip6f);
1069			m->m_pkthdr.rcvif = (struct ifnet *)0;
1070			ip6f->ip6f_reserved = 0;
1071			ip6f->ip6f_ident = id;
1072			ip6f->ip6f_nxt = nextproto;
1073			ip6stat.ip6s_ofragments++;
1074			in6_ifstat_inc(ifp, ifs6_out_fragcreat);
1075		}
1076
1077		in6_ifstat_inc(ifp, ifs6_out_fragok);
1078	}
1079
1080	/*
1081	 * Remove leading garbages.
1082	 */
1083sendorfree:
1084	m = m0->m_nextpkt;
1085	m0->m_nextpkt = 0;
1086	m_freem(m0);
1087	for (m0 = m; m; m = m0) {
1088		m0 = m->m_nextpkt;
1089		m->m_nextpkt = 0;
1090		if (error == 0) {
1091 			/* Record statistics for this interface address. */
1092 			if (ia) {
1093 				ia->ia_ifa.if_opackets++;
1094 				ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1095 			}
1096#ifdef IPSEC
1097			/* clean ipsec history once it goes out of the node */
1098			ipsec_delaux(m);
1099#endif
1100			error = nd6_output(ifp, origifp, m, dst, ro->ro_rt);
1101		} else
1102			m_freem(m);
1103	}
1104
1105	if (error == 0)
1106		ip6stat.ip6s_fragmented++;
1107
1108done:
1109	if (ro == &ip6route && ro->ro_rt) { /* brace necessary for RTFREE */
1110		RTFREE(ro->ro_rt);
1111	} else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
1112		RTFREE(ro_pmtu->ro_rt);
1113	}
1114
1115#ifdef IPSEC
1116	if (sp != NULL)
1117		key_freesp(sp);
1118#endif /* IPSEC */
1119#ifdef FAST_IPSEC
1120	if (sp != NULL)
1121		KEY_FREESP(&sp);
1122#endif /* FAST_IPSEC */
1123
1124	return (error);
1125
1126freehdrs:
1127	m_freem(exthdrs.ip6e_hbh);	/* m_freem will check if mbuf is 0 */
1128	m_freem(exthdrs.ip6e_dest1);
1129	m_freem(exthdrs.ip6e_rthdr);
1130	m_freem(exthdrs.ip6e_dest2);
1131	/* FALLTHROUGH */
1132bad:
1133	m_freem(m);
1134	goto done;
1135}
1136
1137static int
1138ip6_copyexthdr(mp, hdr, hlen)
1139	struct mbuf **mp;
1140	caddr_t hdr;
1141	int hlen;
1142{
1143	struct mbuf *m;
1144
1145	if (hlen > MCLBYTES)
1146		return (ENOBUFS); /* XXX */
1147
1148	MGET(m, M_DONTWAIT, MT_DATA);
1149	if (!m)
1150		return (ENOBUFS);
1151
1152	if (hlen > MLEN) {
1153		MCLGET(m, M_DONTWAIT);
1154		if ((m->m_flags & M_EXT) == 0) {
1155			m_free(m);
1156			return (ENOBUFS);
1157		}
1158	}
1159	m->m_len = hlen;
1160	if (hdr)
1161		bcopy(hdr, mtod(m, caddr_t), hlen);
1162
1163	*mp = m;
1164	return (0);
1165}
1166
1167/*
1168 * Insert jumbo payload option.
1169 */
1170static int
1171ip6_insert_jumboopt(exthdrs, plen)
1172	struct ip6_exthdrs *exthdrs;
1173	u_int32_t plen;
1174{
1175	struct mbuf *mopt;
1176	u_char *optbuf;
1177	u_int32_t v;
1178
1179#define JUMBOOPTLEN	8	/* length of jumbo payload option and padding */
1180
1181	/*
1182	 * If there is no hop-by-hop options header, allocate new one.
1183	 * If there is one but it doesn't have enough space to store the
1184	 * jumbo payload option, allocate a cluster to store the whole options.
1185	 * Otherwise, use it to store the options.
1186	 */
1187	if (exthdrs->ip6e_hbh == 0) {
1188		MGET(mopt, M_DONTWAIT, MT_DATA);
1189		if (mopt == 0)
1190			return (ENOBUFS);
1191		mopt->m_len = JUMBOOPTLEN;
1192		optbuf = mtod(mopt, u_char *);
1193		optbuf[1] = 0;	/* = ((JUMBOOPTLEN) >> 3) - 1 */
1194		exthdrs->ip6e_hbh = mopt;
1195	} else {
1196		struct ip6_hbh *hbh;
1197
1198		mopt = exthdrs->ip6e_hbh;
1199		if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
1200			/*
1201			 * XXX assumption:
1202			 * - exthdrs->ip6e_hbh is not referenced from places
1203			 *   other than exthdrs.
1204			 * - exthdrs->ip6e_hbh is not an mbuf chain.
1205			 */
1206			int oldoptlen = mopt->m_len;
1207			struct mbuf *n;
1208
1209			/*
1210			 * XXX: give up if the whole (new) hbh header does
1211			 * not fit even in an mbuf cluster.
1212			 */
1213			if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
1214				return (ENOBUFS);
1215
1216			/*
1217			 * As a consequence, we must always prepare a cluster
1218			 * at this point.
1219			 */
1220			MGET(n, M_DONTWAIT, MT_DATA);
1221			if (n) {
1222				MCLGET(n, M_DONTWAIT);
1223				if ((n->m_flags & M_EXT) == 0) {
1224					m_freem(n);
1225					n = NULL;
1226				}
1227			}
1228			if (!n)
1229				return (ENOBUFS);
1230			n->m_len = oldoptlen + JUMBOOPTLEN;
1231			bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
1232			    oldoptlen);
1233			optbuf = mtod(n, caddr_t) + oldoptlen;
1234			m_freem(mopt);
1235			mopt = exthdrs->ip6e_hbh = n;
1236		} else {
1237			optbuf = mtod(mopt, u_char *) + mopt->m_len;
1238			mopt->m_len += JUMBOOPTLEN;
1239		}
1240		optbuf[0] = IP6OPT_PADN;
1241		optbuf[1] = 1;
1242
1243		/*
1244		 * Adjust the header length according to the pad and
1245		 * the jumbo payload option.
1246		 */
1247		hbh = mtod(mopt, struct ip6_hbh *);
1248		hbh->ip6h_len += (JUMBOOPTLEN >> 3);
1249	}
1250
1251	/* fill in the option. */
1252	optbuf[2] = IP6OPT_JUMBO;
1253	optbuf[3] = 4;
1254	v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
1255	bcopy(&v, &optbuf[4], sizeof(u_int32_t));
1256
1257	/* finally, adjust the packet header length */
1258	exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
1259
1260	return (0);
1261#undef JUMBOOPTLEN
1262}
1263
1264/*
1265 * Insert fragment header and copy unfragmentable header portions.
1266 */
1267static int
1268ip6_insertfraghdr(m0, m, hlen, frghdrp)
1269	struct mbuf *m0, *m;
1270	int hlen;
1271	struct ip6_frag **frghdrp;
1272{
1273	struct mbuf *n, *mlast;
1274
1275	if (hlen > sizeof(struct ip6_hdr)) {
1276		n = m_copym(m0, sizeof(struct ip6_hdr),
1277		    hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
1278		if (n == 0)
1279			return (ENOBUFS);
1280		m->m_next = n;
1281	} else
1282		n = m;
1283
1284	/* Search for the last mbuf of unfragmentable part. */
1285	for (mlast = n; mlast->m_next; mlast = mlast->m_next)
1286		;
1287
1288	if ((mlast->m_flags & M_EXT) == 0 &&
1289	    M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) {
1290		/* use the trailing space of the last mbuf for the fragment hdr */
1291		*frghdrp = (struct ip6_frag *)(mtod(mlast, caddr_t) +
1292		    mlast->m_len);
1293		mlast->m_len += sizeof(struct ip6_frag);
1294		m->m_pkthdr.len += sizeof(struct ip6_frag);
1295	} else {
1296		/* allocate a new mbuf for the fragment header */
1297		struct mbuf *mfrg;
1298
1299		MGET(mfrg, M_DONTWAIT, MT_DATA);
1300		if (mfrg == 0)
1301			return (ENOBUFS);
1302		mfrg->m_len = sizeof(struct ip6_frag);
1303		*frghdrp = mtod(mfrg, struct ip6_frag *);
1304		mlast->m_next = mfrg;
1305	}
1306
1307	return (0);
1308}
1309
1310/*
1311 * IP6 socket option processing.
1312 */
1313int
1314ip6_ctloutput(so, sopt)
1315	struct socket *so;
1316	struct sockopt *sopt;
1317{
1318	int privileged;
1319	struct inpcb *in6p = sotoinpcb(so);
1320	int error, optval;
1321	int level, op, optname;
1322	int optlen;
1323	struct thread *td;
1324
1325	if (sopt) {
1326		level = sopt->sopt_level;
1327		op = sopt->sopt_dir;
1328		optname = sopt->sopt_name;
1329		optlen = sopt->sopt_valsize;
1330		td = sopt->sopt_td;
1331	} else {
1332		panic("ip6_ctloutput: arg soopt is NULL");
1333	}
1334	error = optval = 0;
1335
1336	privileged = (td == 0 || suser(td)) ? 0 : 1;
1337
1338	if (level == IPPROTO_IPV6) {
1339		switch (op) {
1340
1341		case SOPT_SET:
1342			switch (optname) {
1343			case IPV6_PKTOPTIONS:
1344			{
1345				struct mbuf *m;
1346
1347				error = soopt_getm(sopt, &m); /* XXX */
1348				if (error != NULL)
1349					break;
1350				error = soopt_mcopyin(sopt, m); /* XXX */
1351				if (error != NULL)
1352					break;
1353				error = ip6_pcbopts(&in6p->in6p_outputopts,
1354						    m, so, sopt);
1355				m_freem(m); /* XXX */
1356				break;
1357			}
1358
1359			/*
1360			 * Use of some Hop-by-Hop options or some
1361			 * Destination options, might require special
1362			 * privilege.  That is, normal applications
1363			 * (without special privilege) might be forbidden
1364			 * from setting certain options in outgoing packets,
1365			 * and might never see certain options in received
1366			 * packets. [RFC 2292 Section 6]
1367			 * KAME specific note:
1368			 *  KAME prevents non-privileged users from sending or
1369			 *  receiving ANY hbh/dst options in order to avoid
1370			 *  overhead of parsing options in the kernel.
1371			 */
1372			case IPV6_UNICAST_HOPS:
1373			case IPV6_CHECKSUM:
1374			case IPV6_FAITH:
1375
1376			case IPV6_V6ONLY:
1377				if (optlen != sizeof(int)) {
1378					error = EINVAL;
1379					break;
1380				}
1381				error = sooptcopyin(sopt, &optval,
1382					sizeof optval, sizeof optval);
1383				if (error)
1384					break;
1385				switch (optname) {
1386
1387				case IPV6_UNICAST_HOPS:
1388					if (optval < -1 || optval >= 256)
1389						error = EINVAL;
1390					else {
1391						/* -1 = kernel default */
1392						in6p->in6p_hops = optval;
1393						if ((in6p->in6p_vflag &
1394						     INP_IPV4) != 0)
1395							in6p->inp_ip_ttl = optval;
1396					}
1397					break;
1398#define OPTSET(bit) \
1399do { \
1400	if (optval) \
1401		in6p->in6p_flags |= (bit); \
1402	else \
1403		in6p->in6p_flags &= ~(bit); \
1404} while (/*CONSTCOND*/ 0)
1405#define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0)
1406
1407				case IPV6_CHECKSUM:
1408					in6p->in6p_cksum = optval;
1409					break;
1410
1411				case IPV6_FAITH:
1412					OPTSET(IN6P_FAITH);
1413					break;
1414
1415				case IPV6_V6ONLY:
1416					/*
1417					 * make setsockopt(IPV6_V6ONLY)
1418					 * available only prior to bind(2).
1419					 * see ipng mailing list, Jun 22 2001.
1420					 */
1421					if (in6p->in6p_lport ||
1422					    !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
1423						error = EINVAL;
1424						break;
1425					}
1426					OPTSET(IN6P_IPV6_V6ONLY);
1427					if (optval)
1428						in6p->in6p_vflag &= ~INP_IPV4;
1429					else
1430						in6p->in6p_vflag |= INP_IPV4;
1431					break;
1432				}
1433				break;
1434
1435			case IPV6_PKTINFO:
1436			case IPV6_HOPLIMIT:
1437			case IPV6_HOPOPTS:
1438			case IPV6_DSTOPTS:
1439			case IPV6_RTHDR:
1440				/* RFC 2292 */
1441				if (optlen != sizeof(int)) {
1442					error = EINVAL;
1443					break;
1444				}
1445				error = sooptcopyin(sopt, &optval,
1446					sizeof optval, sizeof optval);
1447				if (error)
1448					break;
1449				switch (optname) {
1450				case IPV6_PKTINFO:
1451					OPTSET(IN6P_PKTINFO);
1452					break;
1453				case IPV6_HOPLIMIT:
1454					OPTSET(IN6P_HOPLIMIT);
1455					break;
1456				case IPV6_HOPOPTS:
1457					/*
1458					 * Check super-user privilege.
1459					 * See comments for IPV6_RECVHOPOPTS.
1460					 */
1461					if (!privileged)
1462						return (EPERM);
1463					OPTSET(IN6P_HOPOPTS);
1464					break;
1465				case IPV6_DSTOPTS:
1466					if (!privileged)
1467						return (EPERM);
1468					OPTSET(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
1469					break;
1470				case IPV6_RTHDR:
1471					OPTSET(IN6P_RTHDR);
1472					break;
1473				}
1474				break;
1475#undef OPTSET
1476
1477			case IPV6_MULTICAST_IF:
1478			case IPV6_MULTICAST_HOPS:
1479			case IPV6_MULTICAST_LOOP:
1480			case IPV6_JOIN_GROUP:
1481			case IPV6_LEAVE_GROUP:
1482			    {
1483				struct mbuf *m;
1484
1485				if (sopt->sopt_valsize > MLEN) {
1486					error = EMSGSIZE;
1487					break;
1488				}
1489				/* XXX */
1490				MGET(m, sopt->sopt_td ? M_TRYWAIT : M_DONTWAIT, MT_HEADER);
1491				if (m == 0) {
1492					error = ENOBUFS;
1493					break;
1494				}
1495				m->m_len = sopt->sopt_valsize;
1496				error = sooptcopyin(sopt, mtod(m, char *),
1497						    m->m_len, m->m_len);
1498				error =	ip6_setmoptions(sopt->sopt_name,
1499							&in6p->in6p_moptions,
1500							m);
1501				(void)m_free(m);
1502			    }
1503				break;
1504
1505			case IPV6_PORTRANGE:
1506				error = sooptcopyin(sopt, &optval,
1507				    sizeof optval, sizeof optval);
1508				if (error)
1509					break;
1510
1511				switch (optval) {
1512				case IPV6_PORTRANGE_DEFAULT:
1513					in6p->in6p_flags &= ~(IN6P_LOWPORT);
1514					in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1515					break;
1516
1517				case IPV6_PORTRANGE_HIGH:
1518					in6p->in6p_flags &= ~(IN6P_LOWPORT);
1519					in6p->in6p_flags |= IN6P_HIGHPORT;
1520					break;
1521
1522				case IPV6_PORTRANGE_LOW:
1523					in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1524					in6p->in6p_flags |= IN6P_LOWPORT;
1525					break;
1526
1527				default:
1528					error = EINVAL;
1529					break;
1530				}
1531				break;
1532
1533#if defined(IPSEC) || defined(FAST_IPSEC)
1534			case IPV6_IPSEC_POLICY:
1535			    {
1536				caddr_t req = NULL;
1537				size_t len = 0;
1538				struct mbuf *m;
1539
1540				if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
1541					break;
1542				if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
1543					break;
1544				if (m) {
1545					req = mtod(m, caddr_t);
1546					len = m->m_len;
1547				}
1548				error = ipsec6_set_policy(in6p, optname, req,
1549							  len, privileged);
1550				m_freem(m);
1551			    }
1552				break;
1553#endif /* KAME IPSEC */
1554
1555			case IPV6_FW_ADD:
1556			case IPV6_FW_DEL:
1557			case IPV6_FW_FLUSH:
1558			case IPV6_FW_ZERO:
1559			    {
1560				struct mbuf *m;
1561				struct mbuf **mp = &m;
1562
1563				if (ip6_fw_ctl_ptr == NULL)
1564					return EINVAL;
1565				/* XXX */
1566				if ((error = soopt_getm(sopt, &m)) != 0)
1567					break;
1568				/* XXX */
1569				if ((error = soopt_mcopyin(sopt, m)) != 0)
1570					break;
1571				error = (*ip6_fw_ctl_ptr)(optname, mp);
1572				m = *mp;
1573			    }
1574				break;
1575
1576			default:
1577				error = ENOPROTOOPT;
1578				break;
1579			}
1580			break;
1581
1582		case SOPT_GET:
1583			switch (optname) {
1584
1585			case IPV6_PKTOPTIONS:
1586				if (in6p->in6p_options) {
1587					struct mbuf *m;
1588					m = m_copym(in6p->in6p_options,
1589					    0, M_COPYALL, M_TRYWAIT);
1590					error = soopt_mcopyout(sopt, m);
1591					if (error == 0)
1592						m_freem(m);
1593				} else
1594					sopt->sopt_valsize = 0;
1595				break;
1596
1597			case IPV6_UNICAST_HOPS:
1598			case IPV6_CHECKSUM:
1599
1600			case IPV6_FAITH:
1601			case IPV6_V6ONLY:
1602			case IPV6_PORTRANGE:
1603				switch (optname) {
1604
1605				case IPV6_UNICAST_HOPS:
1606					optval = in6p->in6p_hops;
1607					break;
1608
1609				case IPV6_CHECKSUM:
1610					optval = in6p->in6p_cksum;
1611					break;
1612
1613				case IPV6_FAITH:
1614					optval = OPTBIT(IN6P_FAITH);
1615					break;
1616
1617				case IPV6_V6ONLY:
1618					optval = OPTBIT(IN6P_IPV6_V6ONLY);
1619					break;
1620
1621				case IPV6_PORTRANGE:
1622				    {
1623					int flags;
1624					flags = in6p->in6p_flags;
1625					if (flags & IN6P_HIGHPORT)
1626						optval = IPV6_PORTRANGE_HIGH;
1627					else if (flags & IN6P_LOWPORT)
1628						optval = IPV6_PORTRANGE_LOW;
1629					else
1630						optval = 0;
1631					break;
1632				    }
1633				}
1634				error = sooptcopyout(sopt, &optval,
1635					sizeof optval);
1636				break;
1637
1638			case IPV6_PKTINFO:
1639			case IPV6_HOPLIMIT:
1640			case IPV6_HOPOPTS:
1641			case IPV6_RTHDR:
1642			case IPV6_DSTOPTS:
1643				if (optname == IPV6_HOPOPTS ||
1644				    optname == IPV6_DSTOPTS ||
1645				    !privileged)
1646					return (EPERM);
1647				switch (optname) {
1648				case IPV6_PKTINFO:
1649					optval = OPTBIT(IN6P_PKTINFO);
1650					break;
1651				case IPV6_HOPLIMIT:
1652					optval = OPTBIT(IN6P_HOPLIMIT);
1653					break;
1654				case IPV6_HOPOPTS:
1655					if (!privileged)
1656						return (EPERM);
1657					optval = OPTBIT(IN6P_HOPOPTS);
1658					break;
1659				case IPV6_RTHDR:
1660					optval = OPTBIT(IN6P_RTHDR);
1661					break;
1662				case IPV6_DSTOPTS:
1663					if (!privileged)
1664						return (EPERM);
1665					optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS);
1666					break;
1667				}
1668				error = sooptcopyout(sopt, &optval,
1669					sizeof optval);
1670				break;
1671
1672			case IPV6_MULTICAST_IF:
1673			case IPV6_MULTICAST_HOPS:
1674			case IPV6_MULTICAST_LOOP:
1675			case IPV6_JOIN_GROUP:
1676			case IPV6_LEAVE_GROUP:
1677			    {
1678				struct mbuf *m;
1679				error = ip6_getmoptions(sopt->sopt_name,
1680				    in6p->in6p_moptions, &m);
1681				if (error == 0)
1682					error = sooptcopyout(sopt,
1683					    mtod(m, char *), m->m_len);
1684				m_freem(m);
1685			    }
1686				break;
1687
1688#if defined(IPSEC) || defined(FAST_IPSEC)
1689			case IPV6_IPSEC_POLICY:
1690			  {
1691				caddr_t req = NULL;
1692				size_t len = 0;
1693				struct mbuf *m = NULL;
1694				struct mbuf **mp = &m;
1695
1696				error = soopt_getm(sopt, &m); /* XXX */
1697				if (error != NULL)
1698					break;
1699				error = soopt_mcopyin(sopt, m); /* XXX */
1700				if (error != NULL)
1701					break;
1702				if (m) {
1703					req = mtod(m, caddr_t);
1704					len = m->m_len;
1705				}
1706				error = ipsec6_get_policy(in6p, req, len, mp);
1707				if (error == 0)
1708					error = soopt_mcopyout(sopt, m); /* XXX */
1709				if (error == 0 && m)
1710					m_freem(m);
1711				break;
1712			  }
1713#endif /* KAME IPSEC */
1714
1715			case IPV6_FW_GET:
1716			  {
1717				struct mbuf *m;
1718				struct mbuf **mp = &m;
1719
1720				if (ip6_fw_ctl_ptr == NULL)
1721			        {
1722					return EINVAL;
1723				}
1724				error = (*ip6_fw_ctl_ptr)(optname, mp);
1725				if (error == 0)
1726					error = soopt_mcopyout(sopt, m); /* XXX */
1727				if (error == 0 && m)
1728					m_freem(m);
1729			  }
1730				break;
1731
1732			default:
1733				error = ENOPROTOOPT;
1734				break;
1735			}
1736			break;
1737		}
1738	} else {
1739		error = EINVAL;
1740	}
1741	return (error);
1742}
1743
1744/*
1745 * Set up IP6 options in pcb for insertion in output packets or
1746 * specifying behavior of outgoing packets.
1747 */
1748static int
1749ip6_pcbopts(pktopt, m, so, sopt)
1750	struct ip6_pktopts **pktopt;
1751	struct mbuf *m;
1752	struct socket *so;
1753	struct sockopt *sopt;
1754{
1755	struct ip6_pktopts *opt = *pktopt;
1756	int error = 0;
1757	struct thread *td = sopt->sopt_td;
1758	int priv = 0;
1759
1760	/* turn off any old options. */
1761	if (opt) {
1762#ifdef DIAGNOSTIC
1763		if (opt->ip6po_pktinfo || opt->ip6po_nexthop ||
1764		    opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 ||
1765		    opt->ip6po_rhinfo.ip6po_rhi_rthdr)
1766			printf("ip6_pcbopts: all specified options are cleared.\n");
1767#endif
1768		ip6_clearpktopts(opt, 1, -1);
1769	} else
1770		opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK);
1771	*pktopt = NULL;
1772
1773	if (!m || m->m_len == 0) {
1774		/*
1775		 * Only turning off any previous options, regardless of
1776		 * whether the opt is just created or given.
1777		 */
1778		free(opt, M_IP6OPT);
1779		return (0);
1780	}
1781
1782	/*  set options specified by user. */
1783	if (td && !suser(td))
1784		priv = 1;
1785	if ((error = ip6_setpktoptions(m, opt, priv, 1)) != 0) {
1786		ip6_clearpktopts(opt, 1, -1); /* XXX: discard all options */
1787		free(opt, M_IP6OPT);
1788		return (error);
1789	}
1790	*pktopt = opt;
1791	return (0);
1792}
1793
1794/*
1795 * initialize ip6_pktopts.  beware that there are non-zero default values in
1796 * the struct.
1797 */
1798void
1799init_ip6pktopts(opt)
1800	struct ip6_pktopts *opt;
1801{
1802
1803	bzero(opt, sizeof(*opt));
1804	opt->ip6po_hlim = -1;	/* -1 means default hop limit */
1805}
1806
1807void
1808ip6_clearpktopts(pktopt, needfree, optname)
1809	struct ip6_pktopts *pktopt;
1810	int needfree, optname;
1811{
1812	if (pktopt == NULL)
1813		return;
1814
1815	if (optname == -1) {
1816		if (needfree && pktopt->ip6po_pktinfo)
1817			free(pktopt->ip6po_pktinfo, M_IP6OPT);
1818		pktopt->ip6po_pktinfo = NULL;
1819	}
1820	if (optname == -1)
1821		pktopt->ip6po_hlim = -1;
1822	if (optname == -1) {
1823		if (needfree && pktopt->ip6po_nexthop)
1824			free(pktopt->ip6po_nexthop, M_IP6OPT);
1825		pktopt->ip6po_nexthop = NULL;
1826	}
1827	if (optname == -1) {
1828		if (needfree && pktopt->ip6po_hbh)
1829			free(pktopt->ip6po_hbh, M_IP6OPT);
1830		pktopt->ip6po_hbh = NULL;
1831	}
1832	if (optname == -1) {
1833		if (needfree && pktopt->ip6po_dest1)
1834			free(pktopt->ip6po_dest1, M_IP6OPT);
1835		pktopt->ip6po_dest1 = NULL;
1836	}
1837	if (optname == -1) {
1838		if (needfree && pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
1839			free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
1840		pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
1841		if (pktopt->ip6po_route.ro_rt) {
1842			RTFREE(pktopt->ip6po_route.ro_rt);
1843			pktopt->ip6po_route.ro_rt = NULL;
1844		}
1845	}
1846	if (optname == -1) {
1847		if (needfree && pktopt->ip6po_dest2)
1848			free(pktopt->ip6po_dest2, M_IP6OPT);
1849		pktopt->ip6po_dest2 = NULL;
1850	}
1851}
1852
1853#define PKTOPT_EXTHDRCPY(type) \
1854do {\
1855	if (src->type) {\
1856		int hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
1857		dst->type = malloc(hlen, M_IP6OPT, canwait);\
1858		if (dst->type == NULL && canwait == M_NOWAIT)\
1859			goto bad;\
1860		bcopy(src->type, dst->type, hlen);\
1861	}\
1862} while (/*CONSTCOND*/ 0)
1863
1864struct ip6_pktopts *
1865ip6_copypktopts(src, canwait)
1866	struct ip6_pktopts *src;
1867	int canwait;
1868{
1869	struct ip6_pktopts *dst;
1870
1871	if (src == NULL) {
1872		printf("ip6_clearpktopts: invalid argument\n");
1873		return (NULL);
1874	}
1875
1876	dst = malloc(sizeof(*dst), M_IP6OPT, canwait);
1877	if (dst == NULL && canwait == M_NOWAIT)
1878		return (NULL);
1879	bzero(dst, sizeof(*dst));
1880
1881	dst->ip6po_hlim = src->ip6po_hlim;
1882	if (src->ip6po_pktinfo) {
1883		dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo),
1884		    M_IP6OPT, canwait);
1885		if (dst->ip6po_pktinfo == NULL && canwait == M_NOWAIT)
1886			goto bad;
1887		*dst->ip6po_pktinfo = *src->ip6po_pktinfo;
1888	}
1889	if (src->ip6po_nexthop) {
1890		dst->ip6po_nexthop = malloc(src->ip6po_nexthop->sa_len,
1891		    M_IP6OPT, canwait);
1892		if (dst->ip6po_nexthop == NULL && canwait == M_NOWAIT)
1893			goto bad;
1894		bcopy(src->ip6po_nexthop, dst->ip6po_nexthop,
1895		    src->ip6po_nexthop->sa_len);
1896	}
1897	PKTOPT_EXTHDRCPY(ip6po_hbh);
1898	PKTOPT_EXTHDRCPY(ip6po_dest1);
1899	PKTOPT_EXTHDRCPY(ip6po_dest2);
1900	PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
1901	return (dst);
1902
1903  bad:
1904	if (dst->ip6po_pktinfo) free(dst->ip6po_pktinfo, M_IP6OPT);
1905	if (dst->ip6po_nexthop) free(dst->ip6po_nexthop, M_IP6OPT);
1906	if (dst->ip6po_hbh) free(dst->ip6po_hbh, M_IP6OPT);
1907	if (dst->ip6po_dest1) free(dst->ip6po_dest1, M_IP6OPT);
1908	if (dst->ip6po_dest2) free(dst->ip6po_dest2, M_IP6OPT);
1909	if (dst->ip6po_rthdr) free(dst->ip6po_rthdr, M_IP6OPT);
1910	free(dst, M_IP6OPT);
1911	return (NULL);
1912}
1913#undef PKTOPT_EXTHDRCPY
1914
1915void
1916ip6_freepcbopts(pktopt)
1917	struct ip6_pktopts *pktopt;
1918{
1919	if (pktopt == NULL)
1920		return;
1921
1922	ip6_clearpktopts(pktopt, 1, -1);
1923
1924	free(pktopt, M_IP6OPT);
1925}
1926
1927/*
1928 * Set the IP6 multicast options in response to user setsockopt().
1929 */
1930static int
1931ip6_setmoptions(optname, im6op, m)
1932	int optname;
1933	struct ip6_moptions **im6op;
1934	struct mbuf *m;
1935{
1936	int error = 0;
1937	u_int loop, ifindex;
1938	struct ipv6_mreq *mreq;
1939	struct ifnet *ifp;
1940	struct ip6_moptions *im6o = *im6op;
1941	struct route_in6 ro;
1942	struct sockaddr_in6 *dst;
1943	struct in6_multi_mship *imm;
1944	struct thread *td = curthread;
1945
1946	if (im6o == NULL) {
1947		/*
1948		 * No multicast option buffer attached to the pcb;
1949		 * allocate one and initialize to default values.
1950		 */
1951		im6o = (struct ip6_moptions *)
1952			malloc(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
1953
1954		if (im6o == NULL)
1955			return (ENOBUFS);
1956		*im6op = im6o;
1957		im6o->im6o_multicast_ifp = NULL;
1958		im6o->im6o_multicast_hlim = ip6_defmcasthlim;
1959		im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP;
1960		LIST_INIT(&im6o->im6o_memberships);
1961	}
1962
1963	switch (optname) {
1964
1965	case IPV6_MULTICAST_IF:
1966		/*
1967		 * Select the interface for outgoing multicast packets.
1968		 */
1969		if (m == NULL || m->m_len != sizeof(u_int)) {
1970			error = EINVAL;
1971			break;
1972		}
1973		bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
1974		if (ifindex < 0 || if_index < ifindex) {
1975			error = ENXIO;	/* XXX EINVAL? */
1976			break;
1977		}
1978		ifp = ifnet_byindex(ifindex);
1979		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1980			error = EADDRNOTAVAIL;
1981			break;
1982		}
1983		im6o->im6o_multicast_ifp = ifp;
1984		break;
1985
1986	case IPV6_MULTICAST_HOPS:
1987	    {
1988		/*
1989		 * Set the IP6 hoplimit for outgoing multicast packets.
1990		 */
1991		int optval;
1992		if (m == NULL || m->m_len != sizeof(int)) {
1993			error = EINVAL;
1994			break;
1995		}
1996		bcopy(mtod(m, u_int *), &optval, sizeof(optval));
1997		if (optval < -1 || optval >= 256)
1998			error = EINVAL;
1999		else if (optval == -1)
2000			im6o->im6o_multicast_hlim = ip6_defmcasthlim;
2001		else
2002			im6o->im6o_multicast_hlim = optval;
2003		break;
2004	    }
2005
2006	case IPV6_MULTICAST_LOOP:
2007		/*
2008		 * Set the loopback flag for outgoing multicast packets.
2009		 * Must be zero or one.
2010		 */
2011		if (m == NULL || m->m_len != sizeof(u_int)) {
2012			error = EINVAL;
2013			break;
2014		}
2015		bcopy(mtod(m, u_int *), &loop, sizeof(loop));
2016		if (loop > 1) {
2017			error = EINVAL;
2018			break;
2019		}
2020		im6o->im6o_multicast_loop = loop;
2021		break;
2022
2023	case IPV6_JOIN_GROUP:
2024		/*
2025		 * Add a multicast group membership.
2026		 * Group must be a valid IP6 multicast address.
2027		 */
2028		if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2029			error = EINVAL;
2030			break;
2031		}
2032		mreq = mtod(m, struct ipv6_mreq *);
2033		if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2034			/*
2035			 * We use the unspecified address to specify to accept
2036			 * all multicast addresses. Only super user is allowed
2037			 * to do this.
2038			 */
2039			if (suser(td)) {
2040				error = EACCES;
2041				break;
2042			}
2043		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2044			error = EINVAL;
2045			break;
2046		}
2047
2048		/*
2049		 * If the interface is specified, validate it.
2050		 */
2051		if (mreq->ipv6mr_interface < 0
2052		 || if_index < mreq->ipv6mr_interface) {
2053			error = ENXIO;	/* XXX EINVAL? */
2054			break;
2055		}
2056		/*
2057		 * If no interface was explicitly specified, choose an
2058		 * appropriate one according to the given multicast address.
2059		 */
2060		if (mreq->ipv6mr_interface == 0) {
2061			/*
2062			 * If the multicast address is in node-local scope,
2063			 * the interface should be a loopback interface.
2064			 * Otherwise, look up the routing table for the
2065			 * address, and choose the outgoing interface.
2066			 *   XXX: is it a good approach?
2067			 */
2068			if (IN6_IS_ADDR_MC_NODELOCAL(&mreq->ipv6mr_multiaddr)) {
2069				ifp = &loif[0];
2070			} else {
2071				ro.ro_rt = NULL;
2072				dst = (struct sockaddr_in6 *)&ro.ro_dst;
2073				bzero(dst, sizeof(*dst));
2074				dst->sin6_len = sizeof(struct sockaddr_in6);
2075				dst->sin6_family = AF_INET6;
2076				dst->sin6_addr = mreq->ipv6mr_multiaddr;
2077				rtalloc((struct route *)&ro);
2078				if (ro.ro_rt == NULL) {
2079					error = EADDRNOTAVAIL;
2080					break;
2081				}
2082				ifp = ro.ro_rt->rt_ifp;
2083				RTFREE(ro.ro_rt);
2084			}
2085		} else
2086			ifp = ifnet_byindex(mreq->ipv6mr_interface);
2087
2088		/*
2089		 * See if we found an interface, and confirm that it
2090		 * supports multicast
2091		 */
2092		if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
2093			error = EADDRNOTAVAIL;
2094			break;
2095		}
2096		/*
2097		 * Put interface index into the multicast address,
2098		 * if the address has link-local scope.
2099		 */
2100		if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2101			mreq->ipv6mr_multiaddr.s6_addr16[1]
2102				= htons(mreq->ipv6mr_interface);
2103		}
2104		/*
2105		 * See if the membership already exists.
2106		 */
2107		for (imm = im6o->im6o_memberships.lh_first;
2108		     imm != NULL; imm = imm->i6mm_chain.le_next)
2109			if (imm->i6mm_maddr->in6m_ifp == ifp &&
2110			    IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2111					       &mreq->ipv6mr_multiaddr))
2112				break;
2113		if (imm != NULL) {
2114			error = EADDRINUSE;
2115			break;
2116		}
2117		/*
2118		 * Everything looks good; add a new record to the multicast
2119		 * address list for the given interface.
2120		 */
2121		imm = malloc(sizeof(*imm), M_IPMADDR, M_WAITOK);
2122		if (imm == NULL) {
2123			error = ENOBUFS;
2124			break;
2125		}
2126		if ((imm->i6mm_maddr =
2127		     in6_addmulti(&mreq->ipv6mr_multiaddr, ifp, &error)) == NULL) {
2128			free(imm, M_IPMADDR);
2129			break;
2130		}
2131		LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
2132		break;
2133
2134	case IPV6_LEAVE_GROUP:
2135		/*
2136		 * Drop a multicast group membership.
2137		 * Group must be a valid IP6 multicast address.
2138		 */
2139		if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
2140			error = EINVAL;
2141			break;
2142		}
2143		mreq = mtod(m, struct ipv6_mreq *);
2144		if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
2145			if (suser(td)) {
2146				error = EACCES;
2147				break;
2148			}
2149		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
2150			error = EINVAL;
2151			break;
2152		}
2153		/*
2154		 * If an interface address was specified, get a pointer
2155		 * to its ifnet structure.
2156		 */
2157		if (mreq->ipv6mr_interface < 0
2158		 || if_index < mreq->ipv6mr_interface) {
2159			error = ENXIO;	/* XXX EINVAL? */
2160			break;
2161		}
2162		ifp = ifnet_byindex(mreq->ipv6mr_interface);
2163		/*
2164		 * Put interface index into the multicast address,
2165		 * if the address has link-local scope.
2166		 */
2167		if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
2168			mreq->ipv6mr_multiaddr.s6_addr16[1]
2169				= htons(mreq->ipv6mr_interface);
2170		}
2171
2172		/*
2173		 * Find the membership in the membership list.
2174		 */
2175		for (imm = im6o->im6o_memberships.lh_first;
2176		     imm != NULL; imm = imm->i6mm_chain.le_next) {
2177			if ((ifp == NULL || imm->i6mm_maddr->in6m_ifp == ifp) &&
2178			    IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
2179			    &mreq->ipv6mr_multiaddr))
2180				break;
2181		}
2182		if (imm == NULL) {
2183			/* Unable to resolve interface */
2184			error = EADDRNOTAVAIL;
2185			break;
2186		}
2187		/*
2188		 * Give up the multicast address record to which the
2189		 * membership points.
2190		 */
2191		LIST_REMOVE(imm, i6mm_chain);
2192		in6_delmulti(imm->i6mm_maddr);
2193		free(imm, M_IPMADDR);
2194		break;
2195
2196	default:
2197		error = EOPNOTSUPP;
2198		break;
2199	}
2200
2201	/*
2202	 * If all options have default values, no need to keep the mbuf.
2203	 */
2204	if (im6o->im6o_multicast_ifp == NULL &&
2205	    im6o->im6o_multicast_hlim == ip6_defmcasthlim &&
2206	    im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
2207	    im6o->im6o_memberships.lh_first == NULL) {
2208		free(*im6op, M_IPMOPTS);
2209		*im6op = NULL;
2210	}
2211
2212	return (error);
2213}
2214
2215/*
2216 * Return the IP6 multicast options in response to user getsockopt().
2217 */
2218static int
2219ip6_getmoptions(optname, im6o, mp)
2220	int optname;
2221	struct ip6_moptions *im6o;
2222	struct mbuf **mp;
2223{
2224	u_int *hlim, *loop, *ifindex;
2225
2226	*mp = m_get(M_TRYWAIT, MT_HEADER);		/* XXX */
2227
2228	switch (optname) {
2229
2230	case IPV6_MULTICAST_IF:
2231		ifindex = mtod(*mp, u_int *);
2232		(*mp)->m_len = sizeof(u_int);
2233		if (im6o == NULL || im6o->im6o_multicast_ifp == NULL)
2234			*ifindex = 0;
2235		else
2236			*ifindex = im6o->im6o_multicast_ifp->if_index;
2237		return (0);
2238
2239	case IPV6_MULTICAST_HOPS:
2240		hlim = mtod(*mp, u_int *);
2241		(*mp)->m_len = sizeof(u_int);
2242		if (im6o == NULL)
2243			*hlim = ip6_defmcasthlim;
2244		else
2245			*hlim = im6o->im6o_multicast_hlim;
2246		return (0);
2247
2248	case IPV6_MULTICAST_LOOP:
2249		loop = mtod(*mp, u_int *);
2250		(*mp)->m_len = sizeof(u_int);
2251		if (im6o == NULL)
2252			*loop = ip6_defmcasthlim;
2253		else
2254			*loop = im6o->im6o_multicast_loop;
2255		return (0);
2256
2257	default:
2258		return (EOPNOTSUPP);
2259	}
2260}
2261
2262/*
2263 * Discard the IP6 multicast options.
2264 */
2265void
2266ip6_freemoptions(im6o)
2267	struct ip6_moptions *im6o;
2268{
2269	struct in6_multi_mship *imm;
2270
2271	if (im6o == NULL)
2272		return;
2273
2274	while ((imm = im6o->im6o_memberships.lh_first) != NULL) {
2275		LIST_REMOVE(imm, i6mm_chain);
2276		if (imm->i6mm_maddr)
2277			in6_delmulti(imm->i6mm_maddr);
2278		free(imm, M_IPMADDR);
2279	}
2280	free(im6o, M_IPMOPTS);
2281}
2282
2283/*
2284 * Set IPv6 outgoing packet options based on advanced API.
2285 */
2286int
2287ip6_setpktoptions(control, opt, priv, needcopy)
2288	struct mbuf *control;
2289	struct ip6_pktopts *opt;
2290	int priv, needcopy;
2291{
2292	struct cmsghdr *cm = 0;
2293
2294	if (control == 0 || opt == 0)
2295		return (EINVAL);
2296
2297	init_ip6pktopts(opt);
2298
2299	/*
2300	 * XXX: Currently, we assume all the optional information is stored
2301	 * in a single mbuf.
2302	 */
2303	if (control->m_next)
2304		return (EINVAL);
2305
2306	for (; control->m_len; control->m_data += CMSG_ALIGN(cm->cmsg_len),
2307	    control->m_len -= CMSG_ALIGN(cm->cmsg_len)) {
2308		cm = mtod(control, struct cmsghdr *);
2309		if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len)
2310			return (EINVAL);
2311		if (cm->cmsg_level != IPPROTO_IPV6)
2312			continue;
2313
2314		/*
2315		 * XXX should check if RFC2292 API is mixed with 2292bis API
2316		 */
2317		switch (cm->cmsg_type) {
2318		case IPV6_PKTINFO:
2319			if (cm->cmsg_len != CMSG_LEN(sizeof(struct in6_pktinfo)))
2320				return (EINVAL);
2321			if (needcopy) {
2322				/* XXX: Is it really WAITOK? */
2323				opt->ip6po_pktinfo =
2324					malloc(sizeof(struct in6_pktinfo),
2325					       M_IP6OPT, M_WAITOK);
2326				bcopy(CMSG_DATA(cm), opt->ip6po_pktinfo,
2327				    sizeof(struct in6_pktinfo));
2328			} else
2329				opt->ip6po_pktinfo =
2330					(struct in6_pktinfo *)CMSG_DATA(cm);
2331			if (opt->ip6po_pktinfo->ipi6_ifindex &&
2332			    IN6_IS_ADDR_LINKLOCAL(&opt->ip6po_pktinfo->ipi6_addr))
2333				opt->ip6po_pktinfo->ipi6_addr.s6_addr16[1] =
2334					htons(opt->ip6po_pktinfo->ipi6_ifindex);
2335
2336			if (opt->ip6po_pktinfo->ipi6_ifindex > if_index
2337			 || opt->ip6po_pktinfo->ipi6_ifindex < 0) {
2338				return (ENXIO);
2339			}
2340
2341			/*
2342			 * Check if the requested source address is indeed a
2343			 * unicast address assigned to the node, and can be
2344			 * used as the packet's source address.
2345			 */
2346			if (!IN6_IS_ADDR_UNSPECIFIED(&opt->ip6po_pktinfo->ipi6_addr)) {
2347				struct in6_ifaddr *ia6;
2348				struct sockaddr_in6 sin6;
2349
2350				bzero(&sin6, sizeof(sin6));
2351				sin6.sin6_len = sizeof(sin6);
2352				sin6.sin6_family = AF_INET6;
2353				sin6.sin6_addr =
2354					opt->ip6po_pktinfo->ipi6_addr;
2355				ia6 = (struct in6_ifaddr *)ifa_ifwithaddr(sin6tosa(&sin6));
2356				if (ia6 == NULL ||
2357				    (ia6->ia6_flags & (IN6_IFF_ANYCAST |
2358						       IN6_IFF_NOTREADY)) != 0)
2359					return (EADDRNOTAVAIL);
2360			}
2361			break;
2362
2363		case IPV6_HOPLIMIT:
2364			if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
2365				return (EINVAL);
2366
2367			opt->ip6po_hlim = *(int *)CMSG_DATA(cm);
2368			if (opt->ip6po_hlim < -1 || opt->ip6po_hlim > 255)
2369				return (EINVAL);
2370			break;
2371
2372		case IPV6_NEXTHOP:
2373			if (!priv)
2374				return (EPERM);
2375
2376			if (cm->cmsg_len < sizeof(u_char) ||
2377			    /* check if cmsg_len is large enough for sa_len */
2378			    cm->cmsg_len < CMSG_LEN(*CMSG_DATA(cm)))
2379				return (EINVAL);
2380
2381			if (needcopy) {
2382				opt->ip6po_nexthop =
2383					malloc(*CMSG_DATA(cm),
2384					       M_IP6OPT, M_WAITOK);
2385				bcopy(CMSG_DATA(cm),
2386				      opt->ip6po_nexthop,
2387				      *CMSG_DATA(cm));
2388			} else
2389				opt->ip6po_nexthop =
2390					(struct sockaddr *)CMSG_DATA(cm);
2391			break;
2392
2393		case IPV6_HOPOPTS:
2394		{
2395			struct ip6_hbh *hbh;
2396			int hbhlen;
2397
2398			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_hbh)))
2399				return (EINVAL);
2400			hbh = (struct ip6_hbh *)CMSG_DATA(cm);
2401			hbhlen = (hbh->ip6h_len + 1) << 3;
2402			if (cm->cmsg_len != CMSG_LEN(hbhlen))
2403				return (EINVAL);
2404
2405			if (needcopy) {
2406				opt->ip6po_hbh =
2407					malloc(hbhlen, M_IP6OPT, M_WAITOK);
2408				bcopy(hbh, opt->ip6po_hbh, hbhlen);
2409			} else
2410				opt->ip6po_hbh = hbh;
2411			break;
2412		}
2413
2414		case IPV6_DSTOPTS:
2415		{
2416			struct ip6_dest *dest, **newdest;
2417			int destlen;
2418
2419			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_dest)))
2420				return (EINVAL);
2421			dest = (struct ip6_dest *)CMSG_DATA(cm);
2422			destlen = (dest->ip6d_len + 1) << 3;
2423			if (cm->cmsg_len != CMSG_LEN(destlen))
2424				return (EINVAL);
2425
2426			/*
2427			 * The old advacned API is ambiguous on this
2428			 * point. Our approach is to determine the
2429			 * position based according to the existence
2430			 * of a routing header. Note, however, that
2431			 * this depends on the order of the extension
2432			 * headers in the ancillary data; the 1st part
2433			 * of the destination options header must
2434			 * appear before the routing header in the
2435			 * ancillary data, too.
2436			 * RFC2292bis solved the ambiguity by
2437			 * introducing separate cmsg types.
2438			 */
2439			if (opt->ip6po_rthdr == NULL)
2440				newdest = &opt->ip6po_dest1;
2441			else
2442				newdest = &opt->ip6po_dest2;
2443
2444			if (needcopy) {
2445				*newdest = malloc(destlen, M_IP6OPT, M_WAITOK);
2446				bcopy(dest, *newdest, destlen);
2447			} else
2448				*newdest = dest;
2449
2450			break;
2451		}
2452
2453		case IPV6_RTHDR:
2454		{
2455			struct ip6_rthdr *rth;
2456			int rthlen;
2457
2458			if (cm->cmsg_len < CMSG_LEN(sizeof(struct ip6_rthdr)))
2459				return (EINVAL);
2460			rth = (struct ip6_rthdr *)CMSG_DATA(cm);
2461			rthlen = (rth->ip6r_len + 1) << 3;
2462			if (cm->cmsg_len != CMSG_LEN(rthlen))
2463				return (EINVAL);
2464
2465			switch (rth->ip6r_type) {
2466			case IPV6_RTHDR_TYPE_0:
2467				/* must contain one addr */
2468				if (rth->ip6r_len == 0)
2469					return (EINVAL);
2470				/* length must be even */
2471				if (rth->ip6r_len % 2)
2472					return (EINVAL);
2473				if (rth->ip6r_len / 2 != rth->ip6r_segleft)
2474					return (EINVAL);
2475				break;
2476			default:
2477				return (EINVAL);	/* not supported */
2478			}
2479
2480			if (needcopy) {
2481				opt->ip6po_rthdr = malloc(rthlen, M_IP6OPT,
2482							  M_WAITOK);
2483				bcopy(rth, opt->ip6po_rthdr, rthlen);
2484			} else
2485				opt->ip6po_rthdr = rth;
2486
2487			break;
2488		}
2489
2490		default:
2491			return (ENOPROTOOPT);
2492		}
2493	}
2494
2495	return (0);
2496}
2497
2498/*
2499 * Routine called from ip6_output() to loop back a copy of an IP6 multicast
2500 * packet to the input queue of a specified interface.  Note that this
2501 * calls the output routine of the loopback "driver", but with an interface
2502 * pointer that might NOT be &loif -- easier than replicating that code here.
2503 */
2504void
2505ip6_mloopback(ifp, m, dst)
2506	struct ifnet *ifp;
2507	struct mbuf *m;
2508	struct sockaddr_in6 *dst;
2509{
2510	struct mbuf *copym;
2511	struct ip6_hdr *ip6;
2512
2513	copym = m_copy(m, 0, M_COPYALL);
2514	if (copym == NULL)
2515		return;
2516
2517	/*
2518	 * Make sure to deep-copy IPv6 header portion in case the data
2519	 * is in an mbuf cluster, so that we can safely override the IPv6
2520	 * header portion later.
2521	 */
2522	if ((copym->m_flags & M_EXT) != 0 ||
2523	    copym->m_len < sizeof(struct ip6_hdr)) {
2524		copym = m_pullup(copym, sizeof(struct ip6_hdr));
2525		if (copym == NULL)
2526			return;
2527	}
2528
2529#ifdef DIAGNOSTIC
2530	if (copym->m_len < sizeof(*ip6)) {
2531		m_freem(copym);
2532		return;
2533	}
2534#endif
2535
2536	ip6 = mtod(copym, struct ip6_hdr *);
2537#ifndef SCOPEDROUTING
2538	/*
2539	 * clear embedded scope identifiers if necessary.
2540	 * in6_clearscope will touch the addresses only when necessary.
2541	 */
2542	in6_clearscope(&ip6->ip6_src);
2543	in6_clearscope(&ip6->ip6_dst);
2544#endif
2545
2546	(void)if_simloop(ifp, copym, dst->sin6_family, NULL);
2547}
2548
2549/*
2550 * Chop IPv6 header off from the payload.
2551 */
2552static int
2553ip6_splithdr(m, exthdrs)
2554	struct mbuf *m;
2555	struct ip6_exthdrs *exthdrs;
2556{
2557	struct mbuf *mh;
2558	struct ip6_hdr *ip6;
2559
2560	ip6 = mtod(m, struct ip6_hdr *);
2561	if (m->m_len > sizeof(*ip6)) {
2562		MGETHDR(mh, M_DONTWAIT, MT_HEADER);
2563		if (mh == 0) {
2564			m_freem(m);
2565			return ENOBUFS;
2566		}
2567		M_MOVE_PKTHDR(mh, m);
2568		MH_ALIGN(mh, sizeof(*ip6));
2569		m->m_len -= sizeof(*ip6);
2570		m->m_data += sizeof(*ip6);
2571		mh->m_next = m;
2572		m = mh;
2573		m->m_len = sizeof(*ip6);
2574		bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
2575	}
2576	exthdrs->ip6e_ip6 = m;
2577	return 0;
2578}
2579
2580/*
2581 * Compute IPv6 extension header length.
2582 */
2583int
2584ip6_optlen(in6p)
2585	struct in6pcb *in6p;
2586{
2587	int len;
2588
2589	if (!in6p->in6p_outputopts)
2590		return 0;
2591
2592	len = 0;
2593#define elen(x) \
2594    (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0)
2595
2596	len += elen(in6p->in6p_outputopts->ip6po_hbh);
2597	if (in6p->in6p_outputopts->ip6po_rthdr)
2598		/* dest1 is valid with rthdr only */
2599		len += elen(in6p->in6p_outputopts->ip6po_dest1);
2600	len += elen(in6p->in6p_outputopts->ip6po_rthdr);
2601	len += elen(in6p->in6p_outputopts->ip6po_dest2);
2602	return len;
2603#undef elen
2604}
2605