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