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

Cache object: 47377b0f71fb44261efb5de9971e1144


[ 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.