The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet6/ip6_output.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 43f9a4ad44dbdc50107901bdefd591f5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.