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