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

Cache object: bcf1056904f449de5bf32f26c17bb7d2


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