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