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 /*      $OpenBSD: ip6_output.c,v 1.272 2022/11/12 02:50:59 kn 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 "pf.h"
   65 
   66 #include <sys/param.h>
   67 #include <sys/malloc.h>
   68 #include <sys/mbuf.h>
   69 #include <sys/errno.h>
   70 #include <sys/protosw.h>
   71 #include <sys/socket.h>
   72 #include <sys/socketvar.h>
   73 #include <sys/proc.h>
   74 #include <sys/systm.h>
   75 
   76 #include <net/if.h>
   77 #include <net/if_var.h>
   78 #include <net/if_enc.h>
   79 #include <net/route.h>
   80 
   81 #include <netinet/in.h>
   82 #include <netinet/ip.h>
   83 #include <netinet/in_pcb.h>
   84 #include <netinet/udp.h>
   85 #include <netinet/tcp.h>
   86 
   87 #include <netinet/ip_var.h>
   88 #include <netinet/tcp_timer.h>
   89 #include <netinet/tcp_var.h>
   90 #include <netinet/udp_var.h>
   91 
   92 #include <netinet6/in6_var.h>
   93 #include <netinet/ip6.h>
   94 #include <netinet/icmp6.h>
   95 #include <netinet6/ip6_var.h>
   96 #include <netinet6/nd6.h>
   97 
   98 #include <crypto/idgen.h>
   99 
  100 #if NPF > 0
  101 #include <net/pfvar.h>
  102 #endif
  103 
  104 #ifdef IPSEC
  105 #include <netinet/ip_ipsp.h>
  106 #include <netinet/ip_ah.h>
  107 #include <netinet/ip_esp.h>
  108 
  109 #ifdef ENCDEBUG
  110 #define DPRINTF(fmt, args...)                                           \
  111         do {                                                            \
  112                 if (encdebug)                                           \
  113                         printf("%s: " fmt "\n", __func__, ## args);     \
  114         } while (0)
  115 #else
  116 #define DPRINTF(fmt, args...)                                           \
  117         do { } while (0)
  118 #endif
  119 #endif /* IPSEC */
  120 
  121 struct ip6_exthdrs {
  122         struct mbuf *ip6e_ip6;
  123         struct mbuf *ip6e_hbh;
  124         struct mbuf *ip6e_dest1;
  125         struct mbuf *ip6e_rthdr;
  126         struct mbuf *ip6e_dest2;
  127 };
  128 
  129 int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **, int, int);
  130 int ip6_getpcbopt(struct ip6_pktopts *, int, struct mbuf *);
  131 int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, int, int, int);
  132 int ip6_setmoptions(int, struct ip6_moptions **, struct mbuf *, unsigned int);
  133 int ip6_getmoptions(int, struct ip6_moptions *, struct mbuf *);
  134 int ip6_copyexthdr(struct mbuf **, caddr_t, int);
  135 int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
  136         struct ip6_frag **);
  137 int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
  138 int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
  139 int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *);
  140 int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *);
  141 static __inline u_int16_t __attribute__((__unused__))
  142     in6_cksum_phdr(const struct in6_addr *, const struct in6_addr *,
  143     u_int32_t, u_int32_t);
  144 void in6_delayed_cksum(struct mbuf *, u_int8_t);
  145 
  146 int ip6_output_ipsec_pmtu_update(struct tdb *, struct route_in6 *,
  147     struct in6_addr *, int, int, int);
  148 
  149 /* Context for non-repeating IDs */
  150 struct idgen32_ctx ip6_id_ctx;
  151 
  152 /*
  153  * IP6 output. The packet in mbuf chain m contains a skeletal IP6
  154  * header (with pri, len, nxt, hlim, src, dst).
  155  * This function may modify ver and hlim only.
  156  * The mbuf chain containing the packet will be freed.
  157  * The mbuf opt, if present, will not be freed.
  158  *
  159  * type of "mtu": rt_mtu is u_long, ifnet.ifr_mtu is int.
  160  * We use u_long to hold largest one, * which is rt_mtu.
  161  */
  162 int
  163 ip6_output(struct mbuf *m, struct ip6_pktopts *opt, struct route_in6 *ro,
  164     int flags, struct ip6_moptions *im6o, struct inpcb *inp)
  165 {
  166         struct ip6_hdr *ip6;
  167         struct ifnet *ifp = NULL;
  168         struct mbuf_list fml;
  169         int hlen, tlen;
  170         struct route_in6 ip6route;
  171         struct rtentry *rt = NULL;
  172         struct sockaddr_in6 *dst, dstsock;
  173         int error = 0;
  174         u_long mtu;
  175         int dontfrag;
  176         u_int16_t src_scope, dst_scope;
  177         u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
  178         struct ip6_exthdrs exthdrs;
  179         struct in6_addr finaldst;
  180         struct route_in6 *ro_pmtu = NULL;
  181         int hdrsplit = 0;
  182         u_int8_t sproto = 0;
  183         u_char nextproto;
  184 #ifdef IPSEC
  185         struct tdb *tdb = NULL;
  186 #endif /* IPSEC */
  187 
  188 #ifdef IPSEC
  189         if (inp && (inp->inp_flags & INP_IPV6) == 0)
  190                 panic("%s: IPv4 pcb is passed", __func__);
  191 #endif /* IPSEC */
  192 
  193         ip6 = mtod(m, struct ip6_hdr *);
  194         finaldst = ip6->ip6_dst;
  195 
  196 #define MAKE_EXTHDR(hp, mp)                                             \
  197     do {                                                                \
  198         if (hp) {                                                       \
  199                 struct ip6_ext *eh = (struct ip6_ext *)(hp);            \
  200                 error = ip6_copyexthdr((mp), (caddr_t)(hp),             \
  201                     ((eh)->ip6e_len + 1) << 3);                         \
  202                 if (error)                                              \
  203                         goto freehdrs;                                  \
  204         }                                                               \
  205     } while (0)
  206 
  207         bzero(&exthdrs, sizeof(exthdrs));
  208 
  209         if (opt) {
  210                 /* Hop-by-Hop options header */
  211                 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
  212                 /* Destination options header(1st part) */
  213                 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
  214                 /* Routing header */
  215                 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
  216                 /* Destination options header(2nd part) */
  217                 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
  218         }
  219 
  220 #ifdef IPSEC
  221         if (ipsec_in_use || inp != NULL) {
  222                 error = ip6_output_ipsec_lookup(m, inp, &tdb);
  223                 if (error) {
  224                         /*
  225                          * -EINVAL is used to indicate that the packet should
  226                          * be silently dropped, typically because we've asked
  227                          * key management for an SA.
  228                          */
  229                         if (error == -EINVAL) /* Should silently drop packet */
  230                                 error = 0;
  231 
  232                         goto freehdrs;
  233                 }
  234         }
  235 #endif /* IPSEC */
  236 
  237         /*
  238          * Calculate the total length of the extension header chain.
  239          * Keep the length of the unfragmentable part for fragmentation.
  240          */
  241         optlen = 0;
  242         if (exthdrs.ip6e_hbh) optlen += exthdrs.ip6e_hbh->m_len;
  243         if (exthdrs.ip6e_dest1) optlen += exthdrs.ip6e_dest1->m_len;
  244         if (exthdrs.ip6e_rthdr) optlen += exthdrs.ip6e_rthdr->m_len;
  245         unfragpartlen = optlen + sizeof(struct ip6_hdr);
  246         /* NOTE: we don't add AH/ESP length here. do that later. */
  247         if (exthdrs.ip6e_dest2) optlen += exthdrs.ip6e_dest2->m_len;
  248 
  249         /*
  250          * If we need IPsec, or there is at least one extension header,
  251          * separate IP6 header from the payload.
  252          */
  253         if ((sproto || optlen) && !hdrsplit) {
  254                 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
  255                         m = NULL;
  256                         goto freehdrs;
  257                 }
  258                 m = exthdrs.ip6e_ip6;
  259                 hdrsplit++;
  260         }
  261 
  262         /* adjust pointer */
  263         ip6 = mtod(m, struct ip6_hdr *);
  264 
  265         /* adjust mbuf packet header length */
  266         m->m_pkthdr.len += optlen;
  267         plen = m->m_pkthdr.len - sizeof(*ip6);
  268 
  269         /* If this is a jumbo payload, insert a jumbo payload option. */
  270         if (plen > IPV6_MAXPACKET) {
  271                 if (!hdrsplit) {
  272                         if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
  273                                 m = NULL;
  274                                 goto freehdrs;
  275                         }
  276                         m = exthdrs.ip6e_ip6;
  277                         hdrsplit++;
  278                 }
  279                 /* adjust pointer */
  280                 ip6 = mtod(m, struct ip6_hdr *);
  281                 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
  282                         goto freehdrs;
  283                 ip6->ip6_plen = 0;
  284         } else
  285                 ip6->ip6_plen = htons(plen);
  286 
  287         /*
  288          * Concatenate headers and fill in next header fields.
  289          * Here we have, on "m"
  290          *      IPv6 payload
  291          * and we insert headers accordingly.  Finally, we should be getting:
  292          *      IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
  293          *
  294          * during the header composing process, "m" points to IPv6 header.
  295          * "mprev" points to an extension header prior to esp.
  296          */
  297         {
  298                 u_char *nexthdrp = &ip6->ip6_nxt;
  299                 struct mbuf *mprev = m;
  300 
  301                 /*
  302                  * we treat dest2 specially.  this makes IPsec processing
  303                  * much easier.  the goal here is to make mprev point the
  304                  * mbuf prior to dest2.
  305                  *
  306                  * result: IPv6 dest2 payload
  307                  * m and mprev will point to IPv6 header.
  308                  */
  309                 if (exthdrs.ip6e_dest2) {
  310                         if (!hdrsplit)
  311                                 panic("%s: assumption failed: hdr not split",
  312                                     __func__);
  313                         exthdrs.ip6e_dest2->m_next = m->m_next;
  314                         m->m_next = exthdrs.ip6e_dest2;
  315                         *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
  316                         ip6->ip6_nxt = IPPROTO_DSTOPTS;
  317                 }
  318 
  319 #define MAKE_CHAIN(m, mp, p, i)\
  320     do {\
  321         if (m) {\
  322                 if (!hdrsplit) \
  323                         panic("assumption failed: hdr not split"); \
  324                 *mtod((m), u_char *) = *(p);\
  325                 *(p) = (i);\
  326                 p = mtod((m), u_char *);\
  327                 (m)->m_next = (mp)->m_next;\
  328                 (mp)->m_next = (m);\
  329                 (mp) = (m);\
  330         }\
  331     } while (0)
  332                 /*
  333                  * result: IPv6 hbh dest1 rthdr dest2 payload
  334                  * m will point to IPv6 header.  mprev will point to the
  335                  * extension header prior to dest2 (rthdr in the above case).
  336                  */
  337                 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
  338                 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
  339                     IPPROTO_DSTOPTS);
  340                 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
  341                     IPPROTO_ROUTING);
  342         }
  343 
  344         /*
  345          * If there is a routing header, replace the destination address field
  346          * with the first hop of the routing header.
  347          */
  348         if (exthdrs.ip6e_rthdr) {
  349                 struct ip6_rthdr *rh;
  350                 struct ip6_rthdr0 *rh0;
  351                 struct in6_addr *addr;
  352 
  353                 rh = (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr,
  354                     struct ip6_rthdr *));
  355                 switch (rh->ip6r_type) {
  356                 case IPV6_RTHDR_TYPE_0:
  357                         rh0 = (struct ip6_rthdr0 *)rh;
  358                         addr = (struct in6_addr *)(rh0 + 1);
  359                         ip6->ip6_dst = addr[0];
  360                         bcopy(&addr[1], &addr[0],
  361                             sizeof(struct in6_addr) * (rh0->ip6r0_segleft - 1));
  362                         addr[rh0->ip6r0_segleft - 1] = finaldst;
  363                         break;
  364                 default:        /* is it possible? */
  365                         error = EINVAL;
  366                         goto bad;
  367                 }
  368         }
  369 
  370         /* Source address validation */
  371         if (!(flags & IPV6_UNSPECSRC) &&
  372             IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
  373                 /*
  374                  * XXX: we can probably assume validation in the caller, but
  375                  * we explicitly check the address here for safety.
  376                  */
  377                 error = EOPNOTSUPP;
  378                 ip6stat_inc(ip6s_badscope);
  379                 goto bad;
  380         }
  381         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
  382                 error = EOPNOTSUPP;
  383                 ip6stat_inc(ip6s_badscope);
  384                 goto bad;
  385         }
  386 
  387         ip6stat_inc(ip6s_localout);
  388 
  389         /*
  390          * Route packet.
  391          */
  392 #if NPF > 0
  393 reroute:
  394 #endif
  395 
  396         /* initialize cached route */
  397         if (ro == NULL) {
  398                 ro = &ip6route;
  399                 bzero((caddr_t)ro, sizeof(*ro));
  400         }
  401         ro_pmtu = ro;
  402         if (opt && opt->ip6po_rthdr)
  403                 ro = &opt->ip6po_route;
  404         dst = &ro->ro_dst;
  405 
  406         /*
  407          * if specified, try to fill in the traffic class field.
  408          * do not override if a non-zero value is already set.
  409          * we check the diffserv field and the ecn field separately.
  410          */
  411         if (opt && opt->ip6po_tclass >= 0) {
  412                 int mask = 0;
  413 
  414                 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)
  415                         mask |= 0xfc;
  416                 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0)
  417                         mask |= 0x03;
  418                 if (mask != 0)
  419                         ip6->ip6_flow |=
  420                             htonl((opt->ip6po_tclass & mask) << 20);
  421         }
  422 
  423         /* fill in or override the hop limit field, if necessary. */
  424         if (opt && opt->ip6po_hlim != -1)
  425                 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
  426         else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
  427                 if (im6o != NULL)
  428                         ip6->ip6_hlim = im6o->im6o_hlim;
  429                 else
  430                         ip6->ip6_hlim = ip6_defmcasthlim;
  431         }
  432 
  433 #ifdef IPSEC
  434         if (tdb != NULL) {
  435                 /*
  436                  * XXX what should we do if ip6_hlim == 0 and the
  437                  * packet gets tunneled?
  438                  */
  439                 /*
  440                  * if we are source-routing, do not attempt to tunnel the
  441                  * packet just because ip6_dst is different from what tdb has.
  442                  * XXX
  443                  */
  444                 error = ip6_output_ipsec_send(tdb, m, ro,
  445                     exthdrs.ip6e_rthdr ? 1 : 0, 0);
  446                 goto done;
  447         }
  448 #endif /* IPSEC */
  449 
  450         bzero(&dstsock, sizeof(dstsock));
  451         dstsock.sin6_family = AF_INET6;
  452         dstsock.sin6_addr = ip6->ip6_dst;
  453         dstsock.sin6_len = sizeof(dstsock);
  454         ro->ro_tableid = m->m_pkthdr.ph_rtableid;
  455 
  456         if (IN6_IS_ADDR_MULTICAST(&dstsock.sin6_addr)) {
  457                 struct in6_pktinfo *pi = NULL;
  458 
  459                 /*
  460                  * If the caller specify the outgoing interface
  461                  * explicitly, use it.
  462                  */
  463                 if (opt != NULL && (pi = opt->ip6po_pktinfo) != NULL)
  464                         ifp = if_get(pi->ipi6_ifindex);
  465 
  466                 if (ifp == NULL && im6o != NULL)
  467                         ifp = if_get(im6o->im6o_ifidx);
  468         }
  469 
  470         if (ifp == NULL) {
  471                 rt = in6_selectroute(&dstsock, opt, ro, ro->ro_tableid);
  472                 if (rt == NULL) {
  473                         ip6stat_inc(ip6s_noroute);
  474                         error = EHOSTUNREACH;
  475                         goto bad;
  476                 }
  477                 if (ISSET(rt->rt_flags, RTF_LOCAL))
  478                         ifp = if_get(rtable_loindex(m->m_pkthdr.ph_rtableid));
  479                 else
  480                         ifp = if_get(rt->rt_ifidx);
  481                 /*
  482                  * We aren't using rtisvalid() here because the UP/DOWN state
  483                  * machine is broken with some Ethernet drivers like em(4).
  484                  * As a result we might try to use an invalid cached route
  485                  * entry while an interface is being detached.
  486                  */
  487                 if (ifp == NULL) {
  488                         ip6stat_inc(ip6s_noroute);
  489                         error = EHOSTUNREACH;
  490                         goto bad;
  491                 }
  492         } else {
  493                 *dst = dstsock;
  494         }
  495 
  496         if (rt && (rt->rt_flags & RTF_GATEWAY) &&
  497             !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
  498                 dst = satosin6(rt->rt_gateway);
  499 
  500         if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
  501                 /* Unicast */
  502 
  503                 m->m_flags &= ~(M_BCAST | M_MCAST);     /* just in case */
  504         } else {
  505                 /* Multicast */
  506 
  507                 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
  508 
  509                 /*
  510                  * Confirm that the outgoing interface supports multicast.
  511                  */
  512                 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
  513                         ip6stat_inc(ip6s_noroute);
  514                         error = ENETUNREACH;
  515                         goto bad;
  516                 }
  517 
  518                 if ((im6o == NULL || im6o->im6o_loop) &&
  519                     in6_hasmulti(&ip6->ip6_dst, ifp)) {
  520                         /*
  521                          * If we belong to the destination multicast group
  522                          * on the outgoing interface, and the caller did not
  523                          * forbid loopback, loop back a copy.
  524                          * Can't defer TCP/UDP checksumming, do the
  525                          * computation now.
  526                          */
  527                         in6_proto_cksum_out(m, NULL);
  528                         ip6_mloopback(ifp, m, dst);
  529                 }
  530 #ifdef MROUTING
  531                 else {
  532                         /*
  533                          * If we are acting as a multicast router, perform
  534                          * multicast forwarding as if the packet had just
  535                          * arrived on the interface to which we are about
  536                          * to send.  The multicast forwarding function
  537                          * recursively calls this function, using the
  538                          * IPV6_FORWARDING flag to prevent infinite recursion.
  539                          *
  540                          * Multicasts that are looped back by ip6_mloopback(),
  541                          * above, will be forwarded by the ip6_input() routine,
  542                          * if necessary.
  543                          */
  544                         if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomain] &&
  545                             (flags & IPV6_FORWARDING) == 0) {
  546                                 if (ip6_mforward(ip6, ifp, m) != 0) {
  547                                         m_freem(m);
  548                                         goto done;
  549                                 }
  550                         }
  551                 }
  552 #endif
  553                 /*
  554                  * Multicasts with a hoplimit of zero may be looped back,
  555                  * above, but must not be transmitted on a network.
  556                  * Also, multicasts addressed to the loopback interface
  557                  * are not sent -- the above call to ip6_mloopback() will
  558                  * loop back a copy if this host actually belongs to the
  559                  * destination group on the loopback interface.
  560                  */
  561                 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
  562                     IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
  563                         m_freem(m);
  564                         goto done;
  565                 }
  566         }
  567 
  568         /*
  569          * If this packet is going through a loopback interface we won't
  570          * be able to restore its scope ID using the interface index.
  571          */
  572         if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) {
  573                 if (ifp->if_flags & IFF_LOOPBACK)
  574                         src_scope = ip6->ip6_src.s6_addr16[1];
  575                 ip6->ip6_src.s6_addr16[1] = 0;
  576         }
  577         if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) {
  578                 if (ifp->if_flags & IFF_LOOPBACK)
  579                         dst_scope = ip6->ip6_dst.s6_addr16[1];
  580                 ip6->ip6_dst.s6_addr16[1] = 0;
  581         }
  582 
  583         /* Determine path MTU. */
  584         if ((error = ip6_getpmtu(ro_pmtu->ro_rt, ifp, &mtu)) != 0)
  585                 goto bad;
  586 
  587         /*
  588          * The caller of this function may specify to use the minimum MTU
  589          * in some cases.
  590          * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU
  591          * setting.  The logic is a bit complicated; by default, unicast
  592          * packets will follow path MTU while multicast packets will be sent at
  593          * the minimum MTU.  If IP6PO_MINMTU_ALL is specified, all packets
  594          * including unicast ones will be sent at the minimum MTU.  Multicast
  595          * packets will always be sent at the minimum MTU unless
  596          * IP6PO_MINMTU_DISABLE is explicitly specified.
  597          * See RFC 3542 for more details.
  598          */
  599         if (mtu > IPV6_MMTU) {
  600                 if ((flags & IPV6_MINMTU))
  601                         mtu = IPV6_MMTU;
  602                 else if (opt && opt->ip6po_minmtu == IP6PO_MINMTU_ALL)
  603                         mtu = IPV6_MMTU;
  604                 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && (opt == NULL ||
  605                     opt->ip6po_minmtu != IP6PO_MINMTU_DISABLE)) {
  606                         mtu = IPV6_MMTU;
  607                 }
  608         }
  609 
  610         /*
  611          * If the outgoing packet contains a hop-by-hop options header,
  612          * it must be examined and processed even by the source node.
  613          * (RFC 2460, section 4.)
  614          */
  615         if (exthdrs.ip6e_hbh) {
  616                 struct ip6_hbh *hbh = mtod(exthdrs.ip6e_hbh, struct ip6_hbh *);
  617                 u_int32_t rtalert; /* returned value is ignored */
  618                 u_int32_t plen = 0; /* no more than 1 jumbo payload option! */
  619 
  620                 m->m_pkthdr.ph_ifidx = ifp->if_index;
  621                 if (ip6_process_hopopts(&m, (u_int8_t *)(hbh + 1),
  622                     ((hbh->ip6h_len + 1) << 3) - sizeof(struct ip6_hbh),
  623                     &rtalert, &plen) < 0) {
  624                         /* m was already freed at this point */
  625                         error = EINVAL;/* better error? */
  626                         goto done;
  627                 }
  628                 m->m_pkthdr.ph_ifidx = 0;
  629         }
  630 
  631 #if NPF > 0
  632         if (pf_test(AF_INET6, PF_OUT, ifp, &m) != PF_PASS) {
  633                 error = EACCES;
  634                 m_freem(m);
  635                 goto done;
  636         }
  637         if (m == NULL)
  638                 goto done;
  639         ip6 = mtod(m, struct ip6_hdr *);
  640         if ((m->m_pkthdr.pf.flags & (PF_TAG_REROUTE | PF_TAG_GENERATED)) ==
  641             (PF_TAG_REROUTE | PF_TAG_GENERATED)) {
  642                 /* already rerun the route lookup, go on */
  643                 m->m_pkthdr.pf.flags &= ~(PF_TAG_GENERATED | PF_TAG_REROUTE);
  644         } else if (m->m_pkthdr.pf.flags & PF_TAG_REROUTE) {
  645                 /* tag as generated to skip over pf_test on rerun */
  646                 m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
  647                 finaldst = ip6->ip6_dst;
  648                 ro = NULL;
  649                 if_put(ifp); /* drop reference since destination changed */
  650                 ifp = NULL;
  651                 goto reroute;
  652         }
  653 #endif
  654 
  655         /*
  656          * If the packet is not going on the wire it can be destined
  657          * to any local address.  In this case do not clear its scopes
  658          * to let ip6_input() find a matching local route.
  659          */
  660         if (ifp->if_flags & IFF_LOOPBACK) {
  661                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
  662                         ip6->ip6_src.s6_addr16[1] = src_scope;
  663                 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
  664                         ip6->ip6_dst.s6_addr16[1] = dst_scope;
  665         }
  666 
  667         in6_proto_cksum_out(m, ifp);
  668 
  669         /*
  670          * Send the packet to the outgoing interface.
  671          * If necessary, do IPv6 fragmentation before sending.
  672          *
  673          * the logic here is rather complex:
  674          * 1: normal case (dontfrag == 0)
  675          * 1-a: send as is if tlen <= path mtu
  676          * 1-b: fragment if tlen > path mtu
  677          *
  678          * 2: if user asks us not to fragment (dontfrag == 1)
  679          * 2-a: send as is if tlen <= interface mtu
  680          * 2-b: error if tlen > interface mtu
  681          */
  682         tlen = m->m_pkthdr.len;
  683 
  684         if (ISSET(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT)) {
  685                 CLR(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT);
  686                 dontfrag = 1;
  687         } else if (opt && ISSET(opt->ip6po_flags, IP6PO_DONTFRAG))
  688                 dontfrag = 1;
  689         else
  690                 dontfrag = 0;
  691         if (dontfrag && tlen > ifp->if_mtu) {   /* case 2-b */
  692 #ifdef IPSEC
  693                 if (ip_mtudisc)
  694                         ipsec_adjust_mtu(m, mtu);
  695 #endif
  696                 error = EMSGSIZE;
  697                 goto bad;
  698         }
  699 
  700         /*
  701          * transmit packet without fragmentation
  702          */
  703         if (dontfrag || (tlen <= mtu)) {        /* case 1-a and 2-a */
  704                 error = ifp->if_output(ifp, m, sin6tosa(dst), ro->ro_rt);
  705                 goto done;
  706         }
  707 
  708         /*
  709          * try to fragment the packet.  case 1-b
  710          */
  711         if (mtu < IPV6_MMTU) {
  712                 /* path MTU cannot be less than IPV6_MMTU */
  713                 error = EMSGSIZE;
  714                 goto bad;
  715         } else if (ip6->ip6_plen == 0) {
  716                 /* jumbo payload cannot be fragmented */
  717                 error = EMSGSIZE;
  718                 goto bad;
  719         }
  720 
  721         /*
  722          * Too large for the destination or interface;
  723          * fragment if possible.
  724          * Must be able to put at least 8 bytes per fragment.
  725          */
  726         hlen = unfragpartlen;
  727         if (mtu > IPV6_MAXPACKET)
  728                 mtu = IPV6_MAXPACKET;
  729 
  730         /*
  731          * If we are doing fragmentation, we can't defer TCP/UDP
  732          * checksumming; compute the checksum and clear the flag.
  733          */
  734         in6_proto_cksum_out(m, NULL);
  735 
  736         /*
  737          * Change the next header field of the last header in the
  738          * unfragmentable part.
  739          */
  740         if (exthdrs.ip6e_rthdr) {
  741                 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
  742                 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
  743         } else if (exthdrs.ip6e_dest1) {
  744                 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
  745                 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
  746         } else if (exthdrs.ip6e_hbh) {
  747                 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
  748                 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
  749         } else {
  750                 nextproto = ip6->ip6_nxt;
  751                 ip6->ip6_nxt = IPPROTO_FRAGMENT;
  752         }
  753 
  754         error = ip6_fragment(m, &fml, hlen, nextproto, mtu);
  755         if (error)
  756                 goto done;
  757 
  758         while ((m = ml_dequeue(&fml)) != NULL) {
  759                 error = ifp->if_output(ifp, m, sin6tosa(dst), ro->ro_rt);
  760                 if (error)
  761                         break;
  762         }
  763         if (error)
  764                 ml_purge(&fml);
  765         else
  766                 ip6stat_inc(ip6s_fragmented);
  767 
  768 done:
  769         if (ro == &ip6route && ro->ro_rt) {
  770                 rtfree(ro->ro_rt);
  771         } else if (ro_pmtu == &ip6route && ro_pmtu->ro_rt) {
  772                 rtfree(ro_pmtu->ro_rt);
  773         }
  774         if_put(ifp);
  775 #ifdef IPSEC
  776         tdb_unref(tdb);
  777 #endif /* IPSEC */
  778         return (error);
  779 
  780 freehdrs:
  781         m_freem(exthdrs.ip6e_hbh);      /* m_freem will check if mbuf is 0 */
  782         m_freem(exthdrs.ip6e_dest1);
  783         m_freem(exthdrs.ip6e_rthdr);
  784         m_freem(exthdrs.ip6e_dest2);
  785         /* FALLTHROUGH */
  786 bad:
  787         m_freem(m);
  788         goto done;
  789 }
  790 
  791 int
  792 ip6_fragment(struct mbuf *m0, struct mbuf_list *fml, int hlen,
  793     u_char nextproto, u_long mtu)
  794 {
  795         struct mbuf *m;
  796         struct ip6_hdr *ip6;
  797         u_int32_t id;
  798         int tlen, len, off;
  799         int error;
  800 
  801         ml_init(fml);
  802 
  803         ip6 = mtod(m0, struct ip6_hdr *);
  804         tlen = m0->m_pkthdr.len;
  805         len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
  806         if (len < 8) {
  807                 error = EMSGSIZE;
  808                 goto bad;
  809         }
  810         id = htonl(ip6_randomid());
  811 
  812         /*
  813          * Loop through length of segment,
  814          * make new header and copy data of each part and link onto chain.
  815          */
  816         for (off = hlen; off < tlen; off += len) {
  817                 struct mbuf *mlast;
  818                 struct ip6_hdr *mhip6;
  819                 struct ip6_frag *ip6f;
  820 
  821                 MGETHDR(m, M_DONTWAIT, MT_HEADER);
  822                 if (m == NULL) {
  823                         error = ENOBUFS;
  824                         goto bad;
  825                 }
  826                 ml_enqueue(fml, m);
  827 
  828                 if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT)) != 0)
  829                         goto bad;
  830                 m->m_data += max_linkhdr;
  831                 mhip6 = mtod(m, struct ip6_hdr *);
  832                 *mhip6 = *ip6;
  833                 m->m_len = sizeof(struct ip6_hdr);
  834 
  835                 if ((error = ip6_insertfraghdr(m0, m, hlen, &ip6f)) != 0)
  836                         goto bad;
  837                 ip6f->ip6f_offlg = htons((off - hlen) & ~7);
  838                 if (off + len >= tlen)
  839                         len = tlen - off;
  840                 else
  841                         ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
  842 
  843                 m->m_pkthdr.len = hlen + sizeof(struct ip6_frag) + len;
  844                 mhip6->ip6_plen = htons(m->m_pkthdr.len -
  845                     sizeof(struct ip6_hdr));
  846                 for (mlast = m; mlast->m_next; mlast = mlast->m_next)
  847                         ;
  848                 mlast->m_next = m_copym(m0, off, len, M_DONTWAIT);
  849                 if (mlast->m_next == NULL) {
  850                         error = ENOBUFS;
  851                         goto bad;
  852                 }
  853 
  854                 ip6f->ip6f_reserved = 0;
  855                 ip6f->ip6f_ident = id;
  856                 ip6f->ip6f_nxt = nextproto;
  857         }
  858 
  859         ip6stat_add(ip6s_ofragments, ml_len(fml));
  860         m_freem(m0);
  861         return (0);
  862 
  863 bad:
  864         ip6stat_inc(ip6s_odropped);
  865         ml_purge(fml);
  866         m_freem(m0);
  867         return (error);
  868 }
  869 
  870 int
  871 ip6_copyexthdr(struct mbuf **mp, caddr_t hdr, int hlen)
  872 {
  873         struct mbuf *m;
  874 
  875         if (hlen > MCLBYTES)
  876                 return (ENOBUFS); /* XXX */
  877 
  878         MGET(m, M_DONTWAIT, MT_DATA);
  879         if (!m)
  880                 return (ENOBUFS);
  881 
  882         if (hlen > MLEN) {
  883                 MCLGET(m, M_DONTWAIT);
  884                 if ((m->m_flags & M_EXT) == 0) {
  885                         m_free(m);
  886                         return (ENOBUFS);
  887                 }
  888         }
  889         m->m_len = hlen;
  890         if (hdr)
  891                 memcpy(mtod(m, caddr_t), hdr, hlen);
  892 
  893         *mp = m;
  894         return (0);
  895 }
  896 
  897 /*
  898  * Insert jumbo payload option.
  899  */
  900 int
  901 ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
  902 {
  903         struct mbuf *mopt;
  904         u_int8_t *optbuf;
  905         u_int32_t v;
  906 
  907 #define JUMBOOPTLEN     8       /* length of jumbo payload option and padding */
  908 
  909         /*
  910          * If there is no hop-by-hop options header, allocate new one.
  911          * If there is one but it doesn't have enough space to store the
  912          * jumbo payload option, allocate a cluster to store the whole options.
  913          * Otherwise, use it to store the options.
  914          */
  915         if (exthdrs->ip6e_hbh == 0) {
  916                 MGET(mopt, M_DONTWAIT, MT_DATA);
  917                 if (mopt == NULL)
  918                         return (ENOBUFS);
  919                 mopt->m_len = JUMBOOPTLEN;
  920                 optbuf = mtod(mopt, u_int8_t *);
  921                 optbuf[1] = 0;  /* = ((JUMBOOPTLEN) >> 3) - 1 */
  922                 exthdrs->ip6e_hbh = mopt;
  923         } else {
  924                 struct ip6_hbh *hbh;
  925 
  926                 mopt = exthdrs->ip6e_hbh;
  927                 if (m_trailingspace(mopt) < JUMBOOPTLEN) {
  928                         /*
  929                          * XXX assumption:
  930                          * - exthdrs->ip6e_hbh is not referenced from places
  931                          *   other than exthdrs.
  932                          * - exthdrs->ip6e_hbh is not an mbuf chain.
  933                          */
  934                         int oldoptlen = mopt->m_len;
  935                         struct mbuf *n;
  936 
  937                         /*
  938                          * XXX: give up if the whole (new) hbh header does
  939                          * not fit even in an mbuf cluster.
  940                          */
  941                         if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
  942                                 return (ENOBUFS);
  943 
  944                         /*
  945                          * As a consequence, we must always prepare a cluster
  946                          * at this point.
  947                          */
  948                         MGET(n, M_DONTWAIT, MT_DATA);
  949                         if (n) {
  950                                 MCLGET(n, M_DONTWAIT);
  951                                 if ((n->m_flags & M_EXT) == 0) {
  952                                         m_freem(n);
  953                                         n = NULL;
  954                                 }
  955                         }
  956                         if (!n)
  957                                 return (ENOBUFS);
  958                         n->m_len = oldoptlen + JUMBOOPTLEN;
  959                         memcpy(mtod(n, caddr_t), mtod(mopt, caddr_t),
  960                               oldoptlen);
  961                         optbuf = mtod(n, u_int8_t *) + oldoptlen;
  962                         m_freem(mopt);
  963                         mopt = exthdrs->ip6e_hbh = n;
  964                 } else {
  965                         optbuf = mtod(mopt, u_int8_t *) + mopt->m_len;
  966                         mopt->m_len += JUMBOOPTLEN;
  967                 }
  968                 optbuf[0] = IP6OPT_PADN;
  969                 optbuf[1] = 0;
  970 
  971                 /*
  972                  * Adjust the header length according to the pad and
  973                  * the jumbo payload option.
  974                  */
  975                 hbh = mtod(mopt, struct ip6_hbh *);
  976                 hbh->ip6h_len += (JUMBOOPTLEN >> 3);
  977         }
  978 
  979         /* fill in the option. */
  980         optbuf[2] = IP6OPT_JUMBO;
  981         optbuf[3] = 4;
  982         v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
  983         memcpy(&optbuf[4], &v, sizeof(u_int32_t));
  984 
  985         /* finally, adjust the packet header length */
  986         exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
  987 
  988         return (0);
  989 #undef JUMBOOPTLEN
  990 }
  991 
  992 /*
  993  * Insert fragment header and copy unfragmentable header portions.
  994  */
  995 int
  996 ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen,
  997     struct ip6_frag **frghdrp)
  998 {
  999         struct mbuf *n, *mlast;
 1000 
 1001         if (hlen > sizeof(struct ip6_hdr)) {
 1002                 n = m_copym(m0, sizeof(struct ip6_hdr),
 1003                     hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
 1004                 if (n == NULL)
 1005                         return (ENOBUFS);
 1006                 m->m_next = n;
 1007         } else
 1008                 n = m;
 1009 
 1010         /* Search for the last mbuf of unfragmentable part. */
 1011         for (mlast = n; mlast->m_next; mlast = mlast->m_next)
 1012                 ;
 1013 
 1014         if ((mlast->m_flags & M_EXT) == 0 &&
 1015             m_trailingspace(mlast) >= sizeof(struct ip6_frag)) {
 1016                 /* use the trailing space of the last mbuf for fragment hdr */
 1017                 *frghdrp = (struct ip6_frag *)(mtod(mlast, caddr_t) +
 1018                     mlast->m_len);
 1019                 mlast->m_len += sizeof(struct ip6_frag);
 1020                 m->m_pkthdr.len += sizeof(struct ip6_frag);
 1021         } else {
 1022                 /* allocate a new mbuf for the fragment header */
 1023                 struct mbuf *mfrg;
 1024 
 1025                 MGET(mfrg, M_DONTWAIT, MT_DATA);
 1026                 if (mfrg == NULL)
 1027                         return (ENOBUFS);
 1028                 mfrg->m_len = sizeof(struct ip6_frag);
 1029                 *frghdrp = mtod(mfrg, struct ip6_frag *);
 1030                 mlast->m_next = mfrg;
 1031         }
 1032 
 1033         return (0);
 1034 }
 1035 
 1036 int
 1037 ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup)
 1038 {
 1039         u_int32_t mtu = 0;
 1040         int error = 0;
 1041 
 1042         if (rt != NULL) {
 1043                 mtu = rt->rt_mtu;
 1044                 if (mtu == 0)
 1045                         mtu = ifp->if_mtu;
 1046                 else if (mtu < IPV6_MMTU) {
 1047                         /* RFC8021 IPv6 Atomic Fragments Considered Harmful */
 1048                         mtu = IPV6_MMTU;
 1049                 } else if (mtu > ifp->if_mtu) {
 1050                         /*
 1051                          * The MTU on the route is larger than the MTU on
 1052                          * the interface!  This shouldn't happen, unless the
 1053                          * MTU of the interface has been changed after the
 1054                          * interface was brought up.  Change the MTU in the
 1055                          * route to match the interface MTU (as long as the
 1056                          * field isn't locked).
 1057                          */
 1058                         mtu = ifp->if_mtu;
 1059                         if (!(rt->rt_locks & RTV_MTU))
 1060                                 rt->rt_mtu = mtu;
 1061                 }
 1062         } else {
 1063                 mtu = ifp->if_mtu;
 1064         }
 1065 
 1066         *mtup = mtu;
 1067         return (error);
 1068 }
 1069 
 1070 /*
 1071  * IP6 socket option processing.
 1072  */
 1073 int
 1074 ip6_ctloutput(int op, struct socket *so, int level, int optname,
 1075     struct mbuf *m)
 1076 {
 1077         int privileged, optdatalen, uproto;
 1078         void *optdata;
 1079         struct inpcb *inp = sotoinpcb(so);
 1080         int error, optval;
 1081         struct proc *p = curproc; /* For IPsec and rdomain */
 1082         u_int rtableid, rtid = 0;
 1083 
 1084         error = optval = 0;
 1085 
 1086         privileged = (inp->inp_socket->so_state & SS_PRIV);
 1087         uproto = (int)so->so_proto->pr_protocol;
 1088 
 1089         if (level != IPPROTO_IPV6)
 1090                 return (EINVAL);
 1091 
 1092         rtableid = p->p_p->ps_rtableid;
 1093 
 1094         switch (op) {
 1095         case PRCO_SETOPT:
 1096                 switch (optname) {
 1097                 /*
 1098                  * Use of some Hop-by-Hop options or some
 1099                  * Destination options, might require special
 1100                  * privilege.  That is, normal applications
 1101                  * (without special privilege) might be forbidden
 1102                  * from setting certain options in outgoing packets,
 1103                  * and might never see certain options in received
 1104                  * packets. [RFC 2292 Section 6]
 1105                  * KAME specific note:
 1106                  *  KAME prevents non-privileged users from sending or
 1107                  *  receiving ANY hbh/dst options in order to avoid
 1108                  *  overhead of parsing options in the kernel.
 1109                  */
 1110                 case IPV6_RECVHOPOPTS:
 1111                 case IPV6_RECVDSTOPTS:
 1112                         if (!privileged) {
 1113                                 error = EPERM;
 1114                                 break;
 1115                         }
 1116                         /* FALLTHROUGH */
 1117                 case IPV6_UNICAST_HOPS:
 1118                 case IPV6_MINHOPCOUNT:
 1119                 case IPV6_HOPLIMIT:
 1120 
 1121                 case IPV6_RECVPKTINFO:
 1122                 case IPV6_RECVHOPLIMIT:
 1123                 case IPV6_RECVRTHDR:
 1124                 case IPV6_RECVPATHMTU:
 1125                 case IPV6_RECVTCLASS:
 1126                 case IPV6_V6ONLY:
 1127                 case IPV6_AUTOFLOWLABEL:
 1128                 case IPV6_RECVDSTPORT:
 1129                         if (m == NULL || m->m_len != sizeof(int)) {
 1130                                 error = EINVAL;
 1131                                 break;
 1132                         }
 1133                         optval = *mtod(m, int *);
 1134                         switch (optname) {
 1135 
 1136                         case IPV6_UNICAST_HOPS:
 1137                                 if (optval < -1 || optval >= 256)
 1138                                         error = EINVAL;
 1139                                 else {
 1140                                         /* -1 = kernel default */
 1141                                         inp->inp_hops = optval;
 1142                                 }
 1143                                 break;
 1144 
 1145                         case IPV6_MINHOPCOUNT:
 1146                                 if (optval < 0 || optval > 255)
 1147                                         error = EINVAL;
 1148                                 else
 1149                                         inp->inp_ip6_minhlim = optval;
 1150                                 break;
 1151 
 1152 #define OPTSET(bit) \
 1153 do { \
 1154         if (optval) \
 1155                 inp->inp_flags |= (bit); \
 1156         else \
 1157                 inp->inp_flags &= ~(bit); \
 1158 } while (/*CONSTCOND*/ 0)
 1159 #define OPTBIT(bit) (inp->inp_flags & (bit) ? 1 : 0)
 1160 
 1161                         case IPV6_RECVPKTINFO:
 1162                                 OPTSET(IN6P_PKTINFO);
 1163                                 break;
 1164 
 1165                         case IPV6_HOPLIMIT:
 1166                         {
 1167                                 struct ip6_pktopts **optp;
 1168 
 1169                                 optp = &inp->inp_outputopts6;
 1170                                 error = ip6_pcbopt(IPV6_HOPLIMIT,
 1171                                     (u_char *)&optval, sizeof(optval), optp,
 1172                                     privileged, uproto);
 1173                                 break;
 1174                         }
 1175 
 1176                         case IPV6_RECVHOPLIMIT:
 1177                                 OPTSET(IN6P_HOPLIMIT);
 1178                                 break;
 1179 
 1180                         case IPV6_RECVHOPOPTS:
 1181                                 OPTSET(IN6P_HOPOPTS);
 1182                                 break;
 1183 
 1184                         case IPV6_RECVDSTOPTS:
 1185                                 OPTSET(IN6P_DSTOPTS);
 1186                                 break;
 1187 
 1188                         case IPV6_RECVRTHDR:
 1189                                 OPTSET(IN6P_RTHDR);
 1190                                 break;
 1191 
 1192                         case IPV6_RECVPATHMTU:
 1193                                 /*
 1194                                  * We ignore this option for TCP
 1195                                  * sockets.
 1196                                  * (RFC3542 leaves this case
 1197                                  * unspecified.)
 1198                                  */
 1199                                 if (uproto != IPPROTO_TCP)
 1200                                         OPTSET(IN6P_MTU);
 1201                                 break;
 1202 
 1203                         case IPV6_V6ONLY:
 1204                                 /*
 1205                                  * make setsockopt(IPV6_V6ONLY)
 1206                                  * available only prior to bind(2).
 1207                                  * see ipng mailing list, Jun 22 2001.
 1208                                  */
 1209                                 if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(
 1210                                     &inp->inp_laddr6)) {
 1211                                         error = EINVAL;
 1212                                         break;
 1213                                 }
 1214                                 /* No support for IPv4-mapped addresses. */
 1215                                 if (!optval)
 1216                                         error = EINVAL;
 1217                                 else
 1218                                         error = 0;
 1219                                 break;
 1220                         case IPV6_RECVTCLASS:
 1221                                 OPTSET(IN6P_TCLASS);
 1222                                 break;
 1223                         case IPV6_AUTOFLOWLABEL:
 1224                                 OPTSET(IN6P_AUTOFLOWLABEL);
 1225                                 break;
 1226 
 1227                         case IPV6_RECVDSTPORT:
 1228                                 OPTSET(IN6P_RECVDSTPORT);
 1229                                 break;
 1230                         }
 1231                         break;
 1232 
 1233                 case IPV6_TCLASS:
 1234                 case IPV6_DONTFRAG:
 1235                 case IPV6_USE_MIN_MTU:
 1236                         if (m == NULL || m->m_len != sizeof(optval)) {
 1237                                 error = EINVAL;
 1238                                 break;
 1239                         }
 1240                         optval = *mtod(m, int *);
 1241                         {
 1242                                 struct ip6_pktopts **optp;
 1243                                 optp = &inp->inp_outputopts6;
 1244                                 error = ip6_pcbopt(optname, (u_char *)&optval,
 1245                                     sizeof(optval), optp, privileged, uproto);
 1246                                 break;
 1247                         }
 1248 
 1249                 case IPV6_PKTINFO:
 1250                 case IPV6_HOPOPTS:
 1251                 case IPV6_RTHDR:
 1252                 case IPV6_DSTOPTS:
 1253                 case IPV6_RTHDRDSTOPTS:
 1254                 {
 1255                         /* new advanced API (RFC3542) */
 1256                         u_char *optbuf;
 1257                         int optbuflen;
 1258                         struct ip6_pktopts **optp;
 1259 
 1260                         if (m && m->m_next) {
 1261                                 error = EINVAL; /* XXX */
 1262                                 break;
 1263                         }
 1264                         if (m) {
 1265                                 optbuf = mtod(m, u_char *);
 1266                                 optbuflen = m->m_len;
 1267                         } else {
 1268                                 optbuf = NULL;
 1269                                 optbuflen = 0;
 1270                         }
 1271                         optp = &inp->inp_outputopts6;
 1272                         error = ip6_pcbopt(optname, optbuf, optbuflen, optp,
 1273                             privileged, uproto);
 1274                         break;
 1275                 }
 1276 #undef OPTSET
 1277 
 1278                 case IPV6_MULTICAST_IF:
 1279                 case IPV6_MULTICAST_HOPS:
 1280                 case IPV6_MULTICAST_LOOP:
 1281                 case IPV6_JOIN_GROUP:
 1282                 case IPV6_LEAVE_GROUP:
 1283                         error = ip6_setmoptions(optname,
 1284                                                 &inp->inp_moptions6,
 1285                                                 m, inp->inp_rtableid);
 1286                         break;
 1287 
 1288                 case IPV6_PORTRANGE:
 1289                         if (m == NULL || m->m_len != sizeof(int)) {
 1290                                 error = EINVAL;
 1291                                 break;
 1292                         }
 1293                         optval = *mtod(m, int *);
 1294 
 1295                         switch (optval) {
 1296                         case IPV6_PORTRANGE_DEFAULT:
 1297                                 inp->inp_flags &= ~(IN6P_LOWPORT);
 1298                                 inp->inp_flags &= ~(IN6P_HIGHPORT);
 1299                                 break;
 1300 
 1301                         case IPV6_PORTRANGE_HIGH:
 1302                                 inp->inp_flags &= ~(IN6P_LOWPORT);
 1303                                 inp->inp_flags |= IN6P_HIGHPORT;
 1304                                 break;
 1305 
 1306                         case IPV6_PORTRANGE_LOW:
 1307                                 inp->inp_flags &= ~(IN6P_HIGHPORT);
 1308                                 inp->inp_flags |= IN6P_LOWPORT;
 1309                                 break;
 1310 
 1311                         default:
 1312                                 error = EINVAL;
 1313                                 break;
 1314                         }
 1315                         break;
 1316 
 1317                 case IPSEC6_OUTSA:
 1318                         error = EINVAL;
 1319                         break;
 1320 
 1321                 case IPV6_AUTH_LEVEL:
 1322                 case IPV6_ESP_TRANS_LEVEL:
 1323                 case IPV6_ESP_NETWORK_LEVEL:
 1324                 case IPV6_IPCOMP_LEVEL:
 1325 #ifndef IPSEC
 1326                         error = EINVAL;
 1327 #else
 1328                         if (m == NULL || m->m_len != sizeof(int)) {
 1329                                 error = EINVAL;
 1330                                 break;
 1331                         }
 1332                         optval = *mtod(m, int *);
 1333 
 1334                         if (optval < IPSEC_LEVEL_BYPASS ||
 1335                             optval > IPSEC_LEVEL_UNIQUE) {
 1336                                 error = EINVAL;
 1337                                 break;
 1338                         }
 1339 
 1340                         switch (optname) {
 1341                         case IPV6_AUTH_LEVEL:
 1342                                 if (optval < IPSEC_AUTH_LEVEL_DEFAULT &&
 1343                                     suser(p)) {
 1344                                         error = EACCES;
 1345                                         break;
 1346                                 }
 1347                                 inp->inp_seclevel[SL_AUTH] = optval;
 1348                                 break;
 1349 
 1350                         case IPV6_ESP_TRANS_LEVEL:
 1351                                 if (optval < IPSEC_ESP_TRANS_LEVEL_DEFAULT &&
 1352                                     suser(p)) {
 1353                                         error = EACCES;
 1354                                         break;
 1355                                 }
 1356                                 inp->inp_seclevel[SL_ESP_TRANS] = optval;
 1357                                 break;
 1358 
 1359                         case IPV6_ESP_NETWORK_LEVEL:
 1360                                 if (optval < IPSEC_ESP_NETWORK_LEVEL_DEFAULT &&
 1361                                     suser(p)) {
 1362                                         error = EACCES;
 1363                                         break;
 1364                                 }
 1365                                 inp->inp_seclevel[SL_ESP_NETWORK] = optval;
 1366                                 break;
 1367 
 1368                         case IPV6_IPCOMP_LEVEL:
 1369                                 if (optval < IPSEC_IPCOMP_LEVEL_DEFAULT &&
 1370                                     suser(p)) {
 1371                                         error = EACCES;
 1372                                         break;
 1373                                 }
 1374                                 inp->inp_seclevel[SL_IPCOMP] = optval;
 1375                                 break;
 1376                         }
 1377 #endif
 1378                         break;
 1379                 case SO_RTABLE:
 1380                         if (m == NULL || m->m_len < sizeof(u_int)) {
 1381                                 error = EINVAL;
 1382                                 break;
 1383                         }
 1384                         rtid = *mtod(m, u_int *);
 1385                         if (inp->inp_rtableid == rtid)
 1386                                 break;
 1387                         /* needs privileges to switch when already set */
 1388                         if (rtableid != rtid && rtableid != 0 &&
 1389                             (error = suser(p)) != 0)
 1390                                 break;
 1391                         /* table must exist */
 1392                         if (!rtable_exists(rtid)) {
 1393                                 error = EINVAL;
 1394                                 break;
 1395                         }
 1396                         if (inp->inp_lport) {
 1397                                 error = EBUSY;
 1398                                 break;
 1399                         }
 1400                         inp->inp_rtableid = rtid;
 1401                         in_pcbrehash(inp);
 1402                         break;
 1403                 case IPV6_PIPEX:
 1404                         if (m != NULL && m->m_len == sizeof(int))
 1405                                 inp->inp_pipex = *mtod(m, int *);
 1406                         else
 1407                                 error = EINVAL;
 1408                         break;
 1409 
 1410                 default:
 1411                         error = ENOPROTOOPT;
 1412                         break;
 1413                 }
 1414                 break;
 1415 
 1416         case PRCO_GETOPT:
 1417                 switch (optname) {
 1418 
 1419                 case IPV6_RECVHOPOPTS:
 1420                 case IPV6_RECVDSTOPTS:
 1421                 case IPV6_UNICAST_HOPS:
 1422                 case IPV6_MINHOPCOUNT:
 1423                 case IPV6_RECVPKTINFO:
 1424                 case IPV6_RECVHOPLIMIT:
 1425                 case IPV6_RECVRTHDR:
 1426                 case IPV6_RECVPATHMTU:
 1427 
 1428                 case IPV6_V6ONLY:
 1429                 case IPV6_PORTRANGE:
 1430                 case IPV6_RECVTCLASS:
 1431                 case IPV6_AUTOFLOWLABEL:
 1432                 case IPV6_RECVDSTPORT:
 1433                         switch (optname) {
 1434 
 1435                         case IPV6_RECVHOPOPTS:
 1436                                 optval = OPTBIT(IN6P_HOPOPTS);
 1437                                 break;
 1438 
 1439                         case IPV6_RECVDSTOPTS:
 1440                                 optval = OPTBIT(IN6P_DSTOPTS);
 1441                                 break;
 1442 
 1443                         case IPV6_UNICAST_HOPS:
 1444                                 optval = inp->inp_hops;
 1445                                 break;
 1446 
 1447                         case IPV6_MINHOPCOUNT:
 1448                                 optval = inp->inp_ip6_minhlim;
 1449                                 break;
 1450 
 1451                         case IPV6_RECVPKTINFO:
 1452                                 optval = OPTBIT(IN6P_PKTINFO);
 1453                                 break;
 1454 
 1455                         case IPV6_RECVHOPLIMIT:
 1456                                 optval = OPTBIT(IN6P_HOPLIMIT);
 1457                                 break;
 1458 
 1459                         case IPV6_RECVRTHDR:
 1460                                 optval = OPTBIT(IN6P_RTHDR);
 1461                                 break;
 1462 
 1463                         case IPV6_RECVPATHMTU:
 1464                                 optval = OPTBIT(IN6P_MTU);
 1465                                 break;
 1466 
 1467                         case IPV6_V6ONLY:
 1468                                 optval = 1;
 1469                                 break;
 1470 
 1471                         case IPV6_PORTRANGE:
 1472                             {
 1473                                 int flags;
 1474                                 flags = inp->inp_flags;
 1475                                 if (flags & IN6P_HIGHPORT)
 1476                                         optval = IPV6_PORTRANGE_HIGH;
 1477                                 else if (flags & IN6P_LOWPORT)
 1478                                         optval = IPV6_PORTRANGE_LOW;
 1479                                 else
 1480                                         optval = 0;
 1481                                 break;
 1482                             }
 1483                         case IPV6_RECVTCLASS:
 1484                                 optval = OPTBIT(IN6P_TCLASS);
 1485                                 break;
 1486 
 1487                         case IPV6_AUTOFLOWLABEL:
 1488                                 optval = OPTBIT(IN6P_AUTOFLOWLABEL);
 1489                                 break;
 1490 
 1491                         case IPV6_RECVDSTPORT:
 1492                                 optval = OPTBIT(IN6P_RECVDSTPORT);
 1493                                 break;
 1494                         }
 1495                         if (error)
 1496                                 break;
 1497                         m->m_len = sizeof(int);
 1498                         *mtod(m, int *) = optval;
 1499                         break;
 1500 
 1501                 case IPV6_PATHMTU:
 1502                 {
 1503                         u_long pmtu = 0;
 1504                         struct ip6_mtuinfo mtuinfo;
 1505                         struct ifnet *ifp;
 1506                         struct rtentry *rt;
 1507 
 1508                         if (!(so->so_state & SS_ISCONNECTED))
 1509                                 return (ENOTCONN);
 1510 
 1511                         rt = in_pcbrtentry(inp);
 1512                         if (!rtisvalid(rt))
 1513                                 return (EHOSTUNREACH);
 1514 
 1515                         ifp = if_get(rt->rt_ifidx);
 1516                         if (ifp == NULL)
 1517                                 return (EHOSTUNREACH);
 1518                         /*
 1519                          * XXX: we dot not consider the case of source
 1520                          * routing, or optional information to specify
 1521                          * the outgoing interface.
 1522                          */
 1523                         error = ip6_getpmtu(rt, ifp, &pmtu);
 1524                         if_put(ifp);
 1525                         if (error)
 1526                                 break;
 1527                         if (pmtu > IPV6_MAXPACKET)
 1528                                 pmtu = IPV6_MAXPACKET;
 1529 
 1530                         bzero(&mtuinfo, sizeof(mtuinfo));
 1531                         mtuinfo.ip6m_mtu = (u_int32_t)pmtu;
 1532                         optdata = (void *)&mtuinfo;
 1533                         optdatalen = sizeof(mtuinfo);
 1534                         if (optdatalen > MCLBYTES)
 1535                                 return (EMSGSIZE); /* XXX */
 1536                         if (optdatalen > MLEN)
 1537                                 MCLGET(m, M_WAIT);
 1538                         m->m_len = optdatalen;
 1539                         bcopy(optdata, mtod(m, void *), optdatalen);
 1540                         break;
 1541                 }
 1542 
 1543                 case IPV6_PKTINFO:
 1544                 case IPV6_HOPOPTS:
 1545                 case IPV6_RTHDR:
 1546                 case IPV6_DSTOPTS:
 1547                 case IPV6_RTHDRDSTOPTS:
 1548                 case IPV6_TCLASS:
 1549                 case IPV6_DONTFRAG:
 1550                 case IPV6_USE_MIN_MTU:
 1551                         error = ip6_getpcbopt(inp->inp_outputopts6,
 1552                             optname, m);
 1553                         break;
 1554 
 1555                 case IPV6_MULTICAST_IF:
 1556                 case IPV6_MULTICAST_HOPS:
 1557                 case IPV6_MULTICAST_LOOP:
 1558                 case IPV6_JOIN_GROUP:
 1559                 case IPV6_LEAVE_GROUP:
 1560                         error = ip6_getmoptions(optname,
 1561                             inp->inp_moptions6, m);
 1562                         break;
 1563 
 1564                 case IPSEC6_OUTSA:
 1565                         error = EINVAL;
 1566                         break;
 1567 
 1568                 case IPV6_AUTH_LEVEL:
 1569                 case IPV6_ESP_TRANS_LEVEL:
 1570                 case IPV6_ESP_NETWORK_LEVEL:
 1571                 case IPV6_IPCOMP_LEVEL:
 1572 #ifndef IPSEC
 1573                         m->m_len = sizeof(int);
 1574                         *mtod(m, int *) = IPSEC_LEVEL_NONE;
 1575 #else
 1576                         m->m_len = sizeof(int);
 1577                         switch (optname) {
 1578                         case IPV6_AUTH_LEVEL:
 1579                                 optval = inp->inp_seclevel[SL_AUTH];
 1580                                 break;
 1581 
 1582                         case IPV6_ESP_TRANS_LEVEL:
 1583                                 optval =
 1584                                     inp->inp_seclevel[SL_ESP_TRANS];
 1585                                 break;
 1586 
 1587                         case IPV6_ESP_NETWORK_LEVEL:
 1588                                 optval =
 1589                                     inp->inp_seclevel[SL_ESP_NETWORK];
 1590                                 break;
 1591 
 1592                         case IPV6_IPCOMP_LEVEL:
 1593                                 optval = inp->inp_seclevel[SL_IPCOMP];
 1594                                 break;
 1595                         }
 1596                         *mtod(m, int *) = optval;
 1597 #endif
 1598                         break;
 1599                 case SO_RTABLE:
 1600                         m->m_len = sizeof(u_int);
 1601                         *mtod(m, u_int *) = inp->inp_rtableid;
 1602                         break;
 1603                 case IPV6_PIPEX:
 1604                         m->m_len = sizeof(int);
 1605                         *mtod(m, int *) = inp->inp_pipex;
 1606                         break;
 1607 
 1608                 default:
 1609                         error = ENOPROTOOPT;
 1610                         break;
 1611                 }
 1612                 break;
 1613         }
 1614         return (error);
 1615 }
 1616 
 1617 int
 1618 ip6_raw_ctloutput(int op, struct socket *so, int level, int optname,
 1619     struct mbuf *m)
 1620 {
 1621         int error = 0, optval;
 1622         const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
 1623         struct inpcb *inp = sotoinpcb(so);
 1624 
 1625         if (level != IPPROTO_IPV6)
 1626                 return (EINVAL);
 1627 
 1628         switch (optname) {
 1629         case IPV6_CHECKSUM:
 1630                 /*
 1631                  * For ICMPv6 sockets, no modification allowed for checksum
 1632                  * offset, permit "no change" values to help existing apps.
 1633                  *
 1634                  * RFC3542 says: "An attempt to set IPV6_CHECKSUM
 1635                  * for an ICMPv6 socket will fail."
 1636                  * The current behavior does not meet RFC3542.
 1637                  */
 1638                 switch (op) {
 1639                 case PRCO_SETOPT:
 1640                         if (m == NULL || m->m_len != sizeof(int)) {
 1641                                 error = EINVAL;
 1642                                 break;
 1643                         }
 1644                         optval = *mtod(m, int *);
 1645                         if (optval < -1 ||
 1646                             (optval > 0 && (optval % 2) != 0)) {
 1647                                 /*
 1648                                  * The API assumes non-negative even offset
 1649                                  * values or -1 as a special value.
 1650                                  */
 1651                                 error = EINVAL;
 1652                         } else if (so->so_proto->pr_protocol ==
 1653                             IPPROTO_ICMPV6) {
 1654                                 if (optval != icmp6off)
 1655                                         error = EINVAL;
 1656                         } else
 1657                                 inp->inp_cksum6 = optval;
 1658                         break;
 1659 
 1660                 case PRCO_GETOPT:
 1661                         if (so->so_proto->pr_protocol == IPPROTO_ICMPV6)
 1662                                 optval = icmp6off;
 1663                         else
 1664                                 optval = inp->inp_cksum6;
 1665 
 1666                         m->m_len = sizeof(int);
 1667                         *mtod(m, int *) = optval;
 1668                         break;
 1669 
 1670                 default:
 1671                         error = EINVAL;
 1672                         break;
 1673                 }
 1674                 break;
 1675 
 1676         default:
 1677                 error = ENOPROTOOPT;
 1678                 break;
 1679         }
 1680 
 1681         return (error);
 1682 }
 1683 
 1684 /*
 1685  * initialize ip6_pktopts.  beware that there are non-zero default values in
 1686  * the struct.
 1687  */
 1688 void
 1689 ip6_initpktopts(struct ip6_pktopts *opt)
 1690 {
 1691         bzero(opt, sizeof(*opt));
 1692         opt->ip6po_hlim = -1;   /* -1 means default hop limit */
 1693         opt->ip6po_tclass = -1; /* -1 means default traffic class */
 1694         opt->ip6po_minmtu = IP6PO_MINMTU_MCASTONLY;
 1695 }
 1696 
 1697 int
 1698 ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt,
 1699     int priv, int uproto)
 1700 {
 1701         struct ip6_pktopts *opt;
 1702 
 1703         if (*pktopt == NULL) {
 1704                 *pktopt = malloc(sizeof(struct ip6_pktopts), M_IP6OPT,
 1705                     M_WAITOK);
 1706                 ip6_initpktopts(*pktopt);
 1707         }
 1708         opt = *pktopt;
 1709 
 1710         return (ip6_setpktopt(optname, buf, len, opt, priv, 1, uproto));
 1711 }
 1712 
 1713 int
 1714 ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct mbuf *m)
 1715 {
 1716         void *optdata = NULL;
 1717         int optdatalen = 0;
 1718         struct ip6_ext *ip6e;
 1719         int error = 0;
 1720         struct in6_pktinfo null_pktinfo;
 1721         int deftclass = 0, on;
 1722         int defminmtu = IP6PO_MINMTU_MCASTONLY;
 1723 
 1724         switch (optname) {
 1725         case IPV6_PKTINFO:
 1726                 if (pktopt && pktopt->ip6po_pktinfo)
 1727                         optdata = (void *)pktopt->ip6po_pktinfo;
 1728                 else {
 1729                         /* XXX: we don't have to do this every time... */
 1730                         bzero(&null_pktinfo, sizeof(null_pktinfo));
 1731                         optdata = (void *)&null_pktinfo;
 1732                 }
 1733                 optdatalen = sizeof(struct in6_pktinfo);
 1734                 break;
 1735         case IPV6_TCLASS:
 1736                 if (pktopt && pktopt->ip6po_tclass >= 0)
 1737                         optdata = (void *)&pktopt->ip6po_tclass;
 1738                 else
 1739                         optdata = (void *)&deftclass;
 1740                 optdatalen = sizeof(int);
 1741                 break;
 1742         case IPV6_HOPOPTS:
 1743                 if (pktopt && pktopt->ip6po_hbh) {
 1744                         optdata = (void *)pktopt->ip6po_hbh;
 1745                         ip6e = (struct ip6_ext *)pktopt->ip6po_hbh;
 1746                         optdatalen = (ip6e->ip6e_len + 1) << 3;
 1747                 }
 1748                 break;
 1749         case IPV6_RTHDR:
 1750                 if (pktopt && pktopt->ip6po_rthdr) {
 1751                         optdata = (void *)pktopt->ip6po_rthdr;
 1752                         ip6e = (struct ip6_ext *)pktopt->ip6po_rthdr;
 1753                         optdatalen = (ip6e->ip6e_len + 1) << 3;
 1754                 }
 1755                 break;
 1756         case IPV6_RTHDRDSTOPTS:
 1757                 if (pktopt && pktopt->ip6po_dest1) {
 1758                         optdata = (void *)pktopt->ip6po_dest1;
 1759                         ip6e = (struct ip6_ext *)pktopt->ip6po_dest1;
 1760                         optdatalen = (ip6e->ip6e_len + 1) << 3;
 1761                 }
 1762                 break;
 1763         case IPV6_DSTOPTS:
 1764                 if (pktopt && pktopt->ip6po_dest2) {
 1765                         optdata = (void *)pktopt->ip6po_dest2;
 1766                         ip6e = (struct ip6_ext *)pktopt->ip6po_dest2;
 1767                         optdatalen = (ip6e->ip6e_len + 1) << 3;
 1768                 }
 1769                 break;
 1770         case IPV6_USE_MIN_MTU:
 1771                 if (pktopt)
 1772                         optdata = (void *)&pktopt->ip6po_minmtu;
 1773                 else
 1774                         optdata = (void *)&defminmtu;
 1775                 optdatalen = sizeof(int);
 1776                 break;
 1777         case IPV6_DONTFRAG:
 1778                 if (pktopt && ((pktopt->ip6po_flags) & IP6PO_DONTFRAG))
 1779                         on = 1;
 1780                 else
 1781                         on = 0;
 1782                 optdata = (void *)&on;
 1783                 optdatalen = sizeof(on);
 1784                 break;
 1785         default:                /* should not happen */
 1786 #ifdef DIAGNOSTIC
 1787                 panic("%s: unexpected option", __func__);
 1788 #endif
 1789                 return (ENOPROTOOPT);
 1790         }
 1791 
 1792         if (optdatalen > MCLBYTES)
 1793                 return (EMSGSIZE); /* XXX */
 1794         if (optdatalen > MLEN)
 1795                 MCLGET(m, M_WAIT);
 1796         m->m_len = optdatalen;
 1797         if (optdatalen)
 1798                 bcopy(optdata, mtod(m, void *), optdatalen);
 1799 
 1800         return (error);
 1801 }
 1802 
 1803 void
 1804 ip6_clearpktopts(struct ip6_pktopts *pktopt, int optname)
 1805 {
 1806         if (optname == -1 || optname == IPV6_PKTINFO) {
 1807                 if (pktopt->ip6po_pktinfo)
 1808                         free(pktopt->ip6po_pktinfo, M_IP6OPT, 0);
 1809                 pktopt->ip6po_pktinfo = NULL;
 1810         }
 1811         if (optname == -1 || optname == IPV6_HOPLIMIT)
 1812                 pktopt->ip6po_hlim = -1;
 1813         if (optname == -1 || optname == IPV6_TCLASS)
 1814                 pktopt->ip6po_tclass = -1;
 1815         if (optname == -1 || optname == IPV6_HOPOPTS) {
 1816                 if (pktopt->ip6po_hbh)
 1817                         free(pktopt->ip6po_hbh, M_IP6OPT, 0);
 1818                 pktopt->ip6po_hbh = NULL;
 1819         }
 1820         if (optname == -1 || optname == IPV6_RTHDRDSTOPTS) {
 1821                 if (pktopt->ip6po_dest1)
 1822                         free(pktopt->ip6po_dest1, M_IP6OPT, 0);
 1823                 pktopt->ip6po_dest1 = NULL;
 1824         }
 1825         if (optname == -1 || optname == IPV6_RTHDR) {
 1826                 if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
 1827                         free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT, 0);
 1828                 pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL;
 1829                 if (pktopt->ip6po_route.ro_rt) {
 1830                         rtfree(pktopt->ip6po_route.ro_rt);
 1831                         pktopt->ip6po_route.ro_rt = NULL;
 1832                 }
 1833         }
 1834         if (optname == -1 || optname == IPV6_DSTOPTS) {
 1835                 if (pktopt->ip6po_dest2)
 1836                         free(pktopt->ip6po_dest2, M_IP6OPT, 0);
 1837                 pktopt->ip6po_dest2 = NULL;
 1838         }
 1839 }
 1840 
 1841 #define PKTOPT_EXTHDRCPY(type) \
 1842 do {\
 1843         if (src->type) {\
 1844                 size_t hlen;\
 1845                 hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\
 1846                 dst->type = malloc(hlen, M_IP6OPT, M_NOWAIT);\
 1847                 if (dst->type == NULL)\
 1848                         goto bad;\
 1849                 memcpy(dst->type, src->type, hlen);\
 1850         }\
 1851 } while (/*CONSTCOND*/ 0)
 1852 
 1853 int
 1854 copypktopts(struct ip6_pktopts *dst, struct ip6_pktopts *src)
 1855 {
 1856         dst->ip6po_hlim = src->ip6po_hlim;
 1857         dst->ip6po_tclass = src->ip6po_tclass;
 1858         dst->ip6po_flags = src->ip6po_flags;
 1859         if (src->ip6po_pktinfo) {
 1860                 dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo),
 1861                     M_IP6OPT, M_NOWAIT);
 1862                 if (dst->ip6po_pktinfo == NULL)
 1863                         goto bad;
 1864                 *dst->ip6po_pktinfo = *src->ip6po_pktinfo;
 1865         }
 1866         PKTOPT_EXTHDRCPY(ip6po_hbh);
 1867         PKTOPT_EXTHDRCPY(ip6po_dest1);
 1868         PKTOPT_EXTHDRCPY(ip6po_dest2);
 1869         PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */
 1870         return (0);
 1871 
 1872   bad:
 1873         ip6_clearpktopts(dst, -1);
 1874         return (ENOBUFS);
 1875 }
 1876 #undef PKTOPT_EXTHDRCPY
 1877 
 1878 void
 1879 ip6_freepcbopts(struct ip6_pktopts *pktopt)
 1880 {
 1881         if (pktopt == NULL)
 1882                 return;
 1883 
 1884         ip6_clearpktopts(pktopt, -1);
 1885 
 1886         free(pktopt, M_IP6OPT, 0);
 1887 }
 1888 
 1889 /*
 1890  * Set the IP6 multicast options in response to user setsockopt().
 1891  */
 1892 int
 1893 ip6_setmoptions(int optname, struct ip6_moptions **im6op, struct mbuf *m,
 1894     unsigned int rtableid)
 1895 {
 1896         int error = 0;
 1897         u_int loop, ifindex;
 1898         struct ipv6_mreq *mreq;
 1899         struct ifnet *ifp;
 1900         struct ip6_moptions *im6o = *im6op;
 1901         struct in6_multi_mship *imm;
 1902         struct proc *p = curproc;       /* XXX */
 1903 
 1904         if (im6o == NULL) {
 1905                 /*
 1906                  * No multicast option buffer attached to the pcb;
 1907                  * allocate one and initialize to default values.
 1908                  */
 1909                 im6o = malloc(sizeof(*im6o), M_IPMOPTS, M_WAITOK);
 1910                 if (im6o == NULL)
 1911                         return (ENOBUFS);
 1912                 *im6op = im6o;
 1913                 im6o->im6o_ifidx = 0;
 1914                 im6o->im6o_hlim = ip6_defmcasthlim;
 1915                 im6o->im6o_loop = IPV6_DEFAULT_MULTICAST_LOOP;
 1916                 LIST_INIT(&im6o->im6o_memberships);
 1917         }
 1918 
 1919         switch (optname) {
 1920 
 1921         case IPV6_MULTICAST_IF:
 1922                 /*
 1923                  * Select the interface for outgoing multicast packets.
 1924                  */
 1925                 if (m == NULL || m->m_len != sizeof(u_int)) {
 1926                         error = EINVAL;
 1927                         break;
 1928                 }
 1929                 memcpy(&ifindex, mtod(m, u_int *), sizeof(ifindex));
 1930                 if (ifindex != 0) {
 1931                         ifp = if_get(ifindex);
 1932                         if (ifp == NULL) {
 1933                                 error = ENXIO;  /* XXX EINVAL? */
 1934                                 break;
 1935                         }
 1936                         if (ifp->if_rdomain != rtable_l2(rtableid) ||
 1937                             (ifp->if_flags & IFF_MULTICAST) == 0) {
 1938                                 error = EADDRNOTAVAIL;
 1939                                 if_put(ifp);
 1940                                 break;
 1941                         }
 1942                         if_put(ifp);
 1943                 }
 1944                 im6o->im6o_ifidx = ifindex;
 1945                 break;
 1946 
 1947         case IPV6_MULTICAST_HOPS:
 1948             {
 1949                 /*
 1950                  * Set the IP6 hoplimit for outgoing multicast packets.
 1951                  */
 1952                 int optval;
 1953                 if (m == NULL || m->m_len != sizeof(int)) {
 1954                         error = EINVAL;
 1955                         break;
 1956                 }
 1957                 memcpy(&optval, mtod(m, u_int *), sizeof(optval));
 1958                 if (optval < -1 || optval >= 256)
 1959                         error = EINVAL;
 1960                 else if (optval == -1)
 1961                         im6o->im6o_hlim = ip6_defmcasthlim;
 1962                 else
 1963                         im6o->im6o_hlim = optval;
 1964                 break;
 1965             }
 1966 
 1967         case IPV6_MULTICAST_LOOP:
 1968                 /*
 1969                  * Set the loopback flag for outgoing multicast packets.
 1970                  * Must be zero or one.
 1971                  */
 1972                 if (m == NULL || m->m_len != sizeof(u_int)) {
 1973                         error = EINVAL;
 1974                         break;
 1975                 }
 1976                 memcpy(&loop, mtod(m, u_int *), sizeof(loop));
 1977                 if (loop > 1) {
 1978                         error = EINVAL;
 1979                         break;
 1980                 }
 1981                 im6o->im6o_loop = loop;
 1982                 break;
 1983 
 1984         case IPV6_JOIN_GROUP:
 1985                 /*
 1986                  * Add a multicast group membership.
 1987                  * Group must be a valid IP6 multicast address.
 1988                  */
 1989                 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
 1990                         error = EINVAL;
 1991                         break;
 1992                 }
 1993                 mreq = mtod(m, struct ipv6_mreq *);
 1994                 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
 1995                         /*
 1996                          * We use the unspecified address to specify to accept
 1997                          * all multicast addresses. Only super user is allowed
 1998                          * to do this.
 1999                          */
 2000                         if (suser(p))
 2001                         {
 2002                                 error = EACCES;
 2003                                 break;
 2004                         }
 2005                 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
 2006                         error = EINVAL;
 2007                         break;
 2008                 }
 2009 
 2010                 /*
 2011                  * If no interface was explicitly specified, choose an
 2012                  * appropriate one according to the given multicast address.
 2013                  */
 2014                 if (mreq->ipv6mr_interface == 0) {
 2015                         struct rtentry *rt;
 2016                         struct sockaddr_in6 dst;
 2017 
 2018                         memset(&dst, 0, sizeof(dst));
 2019                         dst.sin6_len = sizeof(dst);
 2020                         dst.sin6_family = AF_INET6;
 2021                         dst.sin6_addr = mreq->ipv6mr_multiaddr;
 2022                         rt = rtalloc(sin6tosa(&dst), RT_RESOLVE, rtableid);
 2023                         if (rt == NULL) {
 2024                                 error = EADDRNOTAVAIL;
 2025                                 break;
 2026                         }
 2027                         ifp = if_get(rt->rt_ifidx);
 2028                         rtfree(rt);
 2029                 } else {
 2030                         /*
 2031                          * If the interface is specified, validate it.
 2032                          */
 2033                         ifp = if_get(mreq->ipv6mr_interface);
 2034                         if (ifp == NULL) {
 2035                                 error = ENXIO;  /* XXX EINVAL? */
 2036                                 break;
 2037                         }
 2038                 }
 2039 
 2040                 /*
 2041                  * See if we found an interface, and confirm that it
 2042                  * supports multicast
 2043                  */
 2044                 if (ifp == NULL || ifp->if_rdomain != rtable_l2(rtableid) ||
 2045                     (ifp->if_flags & IFF_MULTICAST) == 0) {
 2046                         if_put(ifp);
 2047                         error = EADDRNOTAVAIL;
 2048                         break;
 2049                 }
 2050                 /*
 2051                  * Put interface index into the multicast address,
 2052                  * if the address has link/interface-local scope.
 2053                  */
 2054                 if (IN6_IS_SCOPE_EMBED(&mreq->ipv6mr_multiaddr)) {
 2055                         mreq->ipv6mr_multiaddr.s6_addr16[1] =
 2056                             htons(ifp->if_index);
 2057                 }
 2058                 /*
 2059                  * See if the membership already exists.
 2060                  */
 2061                 LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain)
 2062                         if (imm->i6mm_maddr->in6m_ifidx == ifp->if_index &&
 2063                             IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
 2064                             &mreq->ipv6mr_multiaddr))
 2065                                 break;
 2066                 if (imm != NULL) {
 2067                         if_put(ifp);
 2068                         error = EADDRINUSE;
 2069                         break;
 2070                 }
 2071                 /*
 2072                  * Everything looks good; add a new record to the multicast
 2073                  * address list for the given interface.
 2074                  */
 2075                 imm = in6_joingroup(ifp, &mreq->ipv6mr_multiaddr, &error);
 2076                 if_put(ifp);
 2077                 if (!imm)
 2078                         break;
 2079                 LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain);
 2080                 break;
 2081 
 2082         case IPV6_LEAVE_GROUP:
 2083                 /*
 2084                  * Drop a multicast group membership.
 2085                  * Group must be a valid IP6 multicast address.
 2086                  */
 2087                 if (m == NULL || m->m_len != sizeof(struct ipv6_mreq)) {
 2088                         error = EINVAL;
 2089                         break;
 2090                 }
 2091                 mreq = mtod(m, struct ipv6_mreq *);
 2092                 if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
 2093                         if (suser(p)) {
 2094                                 error = EACCES;
 2095                                 break;
 2096                         }
 2097                 } else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
 2098                         error = EINVAL;
 2099                         break;
 2100                 }
 2101 
 2102                 /*
 2103                  * Put interface index into the multicast address,
 2104                  * if the address has link-local scope.
 2105                  */
 2106                 if (IN6_IS_ADDR_MC_LINKLOCAL(&mreq->ipv6mr_multiaddr)) {
 2107                         mreq->ipv6mr_multiaddr.s6_addr16[1] =
 2108                             htons(mreq->ipv6mr_interface);
 2109                 }
 2110 
 2111                 /*
 2112                  * If an interface address was specified, get a pointer
 2113                  * to its ifnet structure.
 2114                  */
 2115                 if (mreq->ipv6mr_interface == 0)
 2116                         ifp = NULL;
 2117                 else {
 2118                         ifp = if_get(mreq->ipv6mr_interface);
 2119                         if (ifp == NULL) {
 2120                                 error = ENXIO;  /* XXX EINVAL? */
 2121                                 break;
 2122                         }
 2123                 }
 2124 
 2125                 /*
 2126                  * Find the membership in the membership list.
 2127                  */
 2128                 LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain) {
 2129                         if ((ifp == NULL ||
 2130                             imm->i6mm_maddr->in6m_ifidx == ifp->if_index) &&
 2131                             IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr,
 2132                             &mreq->ipv6mr_multiaddr))
 2133                                 break;
 2134                 }
 2135 
 2136                 if_put(ifp);
 2137 
 2138                 if (imm == NULL) {
 2139                         /* Unable to resolve interface */
 2140                         error = EADDRNOTAVAIL;
 2141                         break;
 2142                 }
 2143                 /*
 2144                  * Give up the multicast address record to which the
 2145                  * membership points.
 2146                  */
 2147                 LIST_REMOVE(imm, i6mm_chain);
 2148                 in6_leavegroup(imm);
 2149                 break;
 2150 
 2151         default:
 2152                 error = EOPNOTSUPP;
 2153                 break;
 2154         }
 2155 
 2156         /*
 2157          * If all options have default values, no need to keep the option
 2158          * structure.
 2159          */
 2160         if (im6o->im6o_ifidx == 0 &&
 2161             im6o->im6o_hlim == ip6_defmcasthlim &&
 2162             im6o->im6o_loop == IPV6_DEFAULT_MULTICAST_LOOP &&
 2163             LIST_EMPTY(&im6o->im6o_memberships)) {
 2164                 free(*im6op, M_IPMOPTS, sizeof(**im6op));
 2165                 *im6op = NULL;
 2166         }
 2167 
 2168         return (error);
 2169 }
 2170 
 2171 /*
 2172  * Return the IP6 multicast options in response to user getsockopt().
 2173  */
 2174 int
 2175 ip6_getmoptions(int optname, struct ip6_moptions *im6o, struct mbuf *m)
 2176 {
 2177         u_int *hlim, *loop, *ifindex;
 2178 
 2179         switch (optname) {
 2180         case IPV6_MULTICAST_IF:
 2181                 ifindex = mtod(m, u_int *);
 2182                 m->m_len = sizeof(u_int);
 2183                 if (im6o == NULL || im6o->im6o_ifidx == 0)
 2184                         *ifindex = 0;
 2185                 else
 2186                         *ifindex = im6o->im6o_ifidx;
 2187                 return (0);
 2188 
 2189         case IPV6_MULTICAST_HOPS:
 2190                 hlim = mtod(m, u_int *);
 2191                 m->m_len = sizeof(u_int);
 2192                 if (im6o == NULL)
 2193                         *hlim = ip6_defmcasthlim;
 2194                 else
 2195                         *hlim = im6o->im6o_hlim;
 2196                 return (0);
 2197 
 2198         case IPV6_MULTICAST_LOOP:
 2199                 loop = mtod(m, u_int *);
 2200                 m->m_len = sizeof(u_int);
 2201                 if (im6o == NULL)
 2202                         *loop = ip6_defmcasthlim;
 2203                 else
 2204                         *loop = im6o->im6o_loop;
 2205                 return (0);
 2206 
 2207         default:
 2208                 return (EOPNOTSUPP);
 2209         }
 2210 }
 2211 
 2212 /*
 2213  * Discard the IP6 multicast options.
 2214  */
 2215 void
 2216 ip6_freemoptions(struct ip6_moptions *im6o)
 2217 {
 2218         struct in6_multi_mship *imm;
 2219 
 2220         if (im6o == NULL)
 2221                 return;
 2222 
 2223         while (!LIST_EMPTY(&im6o->im6o_memberships)) {
 2224                 imm = LIST_FIRST(&im6o->im6o_memberships);
 2225                 LIST_REMOVE(imm, i6mm_chain);
 2226                 in6_leavegroup(imm);
 2227         }
 2228         free(im6o, M_IPMOPTS, sizeof(*im6o));
 2229 }
 2230 
 2231 /*
 2232  * Set IPv6 outgoing packet options based on advanced API.
 2233  */
 2234 int
 2235 ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt,
 2236     struct ip6_pktopts *stickyopt, int priv, int uproto)
 2237 {
 2238         u_int clen;
 2239         struct cmsghdr *cm = 0;
 2240         caddr_t cmsgs;
 2241         int error;
 2242 
 2243         if (control == NULL || opt == NULL)
 2244                 return (EINVAL);
 2245 
 2246         ip6_initpktopts(opt);
 2247         if (stickyopt) {
 2248                 int error;
 2249 
 2250                 /*
 2251                  * If stickyopt is provided, make a local copy of the options
 2252                  * for this particular packet, then override them by ancillary
 2253                  * objects.
 2254                  * XXX: copypktopts() does not copy the cached route to a next
 2255                  * hop (if any).  This is not very good in terms of efficiency,
 2256                  * but we can allow this since this option should be rarely
 2257                  * used.
 2258                  */
 2259                 if ((error = copypktopts(opt, stickyopt)) != 0)
 2260                         return (error);
 2261         }
 2262 
 2263         /*
 2264          * XXX: Currently, we assume all the optional information is stored
 2265          * in a single mbuf.
 2266          */
 2267         if (control->m_next)
 2268                 return (EINVAL);
 2269 
 2270         clen = control->m_len;
 2271         cmsgs = mtod(control, caddr_t);
 2272         do {
 2273                 if (clen < CMSG_LEN(0))
 2274                         return (EINVAL);
 2275                 cm = (struct cmsghdr *)cmsgs;
 2276                 if (cm->cmsg_len < CMSG_LEN(0) || cm->cmsg_len > clen ||
 2277                     CMSG_ALIGN(cm->cmsg_len) > clen)
 2278                         return (EINVAL);
 2279                 if (cm->cmsg_level == IPPROTO_IPV6) {
 2280                         error = ip6_setpktopt(cm->cmsg_type, CMSG_DATA(cm),
 2281                             cm->cmsg_len - CMSG_LEN(0), opt, priv, 0, uproto);
 2282                         if (error)
 2283                                 return (error);
 2284                 }
 2285 
 2286                 clen -= CMSG_ALIGN(cm->cmsg_len);
 2287                 cmsgs += CMSG_ALIGN(cm->cmsg_len);
 2288         } while (clen);
 2289 
 2290         return (0);
 2291 }
 2292 
 2293 /*
 2294  * Set a particular packet option, as a sticky option or an ancillary data
 2295  * item.  "len" can be 0 only when it's a sticky option.
 2296  */
 2297 int
 2298 ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt,
 2299     int priv, int sticky, int uproto)
 2300 {
 2301         int minmtupolicy;
 2302 
 2303         switch (optname) {
 2304         case IPV6_PKTINFO:
 2305         {
 2306                 struct ifnet *ifp = NULL;
 2307                 struct in6_pktinfo *pktinfo;
 2308 
 2309                 if (len != sizeof(struct in6_pktinfo))
 2310                         return (EINVAL);
 2311 
 2312                 pktinfo = (struct in6_pktinfo *)buf;
 2313 
 2314                 /*
 2315                  * An application can clear any sticky IPV6_PKTINFO option by
 2316                  * doing a "regular" setsockopt with ipi6_addr being
 2317                  * in6addr_any and ipi6_ifindex being zero.
 2318                  * [RFC 3542, Section 6]
 2319                  */
 2320                 if (opt->ip6po_pktinfo &&
 2321                     pktinfo->ipi6_ifindex == 0 &&
 2322                     IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
 2323                         ip6_clearpktopts(opt, optname);
 2324                         break;
 2325                 }
 2326 
 2327                 if (uproto == IPPROTO_TCP &&
 2328                     sticky && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) {
 2329                         return (EINVAL);
 2330                 }
 2331 
 2332                 if (pktinfo->ipi6_ifindex) {
 2333                         ifp = if_get(pktinfo->ipi6_ifindex);
 2334                         if (ifp == NULL)
 2335                                 return (ENXIO);
 2336                         if_put(ifp);
 2337                 }
 2338 
 2339                 /*
 2340                  * We store the address anyway, and let in6_selectsrc()
 2341                  * validate the specified address.  This is because ipi6_addr
 2342                  * may not have enough information about its scope zone, and
 2343                  * we may need additional information (such as outgoing
 2344                  * interface or the scope zone of a destination address) to
 2345                  * disambiguate the scope.
 2346                  * XXX: the delay of the validation may confuse the
 2347                  * application when it is used as a sticky option.
 2348                  */
 2349                 if (opt->ip6po_pktinfo == NULL) {
 2350                         opt->ip6po_pktinfo = malloc(sizeof(*pktinfo),
 2351                             M_IP6OPT, M_NOWAIT);
 2352                         if (opt->ip6po_pktinfo == NULL)
 2353                                 return (ENOBUFS);
 2354                 }
 2355                 bcopy(pktinfo, opt->ip6po_pktinfo, sizeof(*pktinfo));
 2356                 break;
 2357         }
 2358 
 2359         case IPV6_HOPLIMIT:
 2360         {
 2361                 int *hlimp;
 2362 
 2363                 /*
 2364                  * RFC 3542 deprecated the usage of sticky IPV6_HOPLIMIT
 2365                  * to simplify the ordering among hoplimit options.
 2366                  */
 2367                 if (sticky)
 2368                         return (ENOPROTOOPT);
 2369 
 2370                 if (len != sizeof(int))
 2371                         return (EINVAL);
 2372                 hlimp = (int *)buf;
 2373                 if (*hlimp < -1 || *hlimp > 255)
 2374                         return (EINVAL);
 2375 
 2376                 opt->ip6po_hlim = *hlimp;
 2377                 break;
 2378         }
 2379 
 2380         case IPV6_TCLASS:
 2381         {
 2382                 int tclass;
 2383 
 2384                 if (len != sizeof(int))
 2385                         return (EINVAL);
 2386                 tclass = *(int *)buf;
 2387                 if (tclass < -1 || tclass > 255)
 2388                         return (EINVAL);
 2389 
 2390                 opt->ip6po_tclass = tclass;
 2391                 break;
 2392         }
 2393         case IPV6_HOPOPTS:
 2394         {
 2395                 struct ip6_hbh *hbh;
 2396                 int hbhlen;
 2397 
 2398                 /*
 2399                  * XXX: We don't allow a non-privileged user to set ANY HbH
 2400                  * options, since per-option restriction has too much
 2401                  * overhead.
 2402                  */
 2403                 if (!priv)
 2404                         return (EPERM);
 2405 
 2406                 if (len == 0) {
 2407                         ip6_clearpktopts(opt, IPV6_HOPOPTS);
 2408                         break;  /* just remove the option */
 2409                 }
 2410 
 2411                 /* message length validation */
 2412                 if (len < sizeof(struct ip6_hbh))
 2413                         return (EINVAL);
 2414                 hbh = (struct ip6_hbh *)buf;
 2415                 hbhlen = (hbh->ip6h_len + 1) << 3;
 2416                 if (len != hbhlen)
 2417                         return (EINVAL);
 2418 
 2419                 /* turn off the previous option, then set the new option. */
 2420                 ip6_clearpktopts(opt, IPV6_HOPOPTS);
 2421                 opt->ip6po_hbh = malloc(hbhlen, M_IP6OPT, M_NOWAIT);
 2422                 if (opt->ip6po_hbh == NULL)
 2423                         return (ENOBUFS);
 2424                 memcpy(opt->ip6po_hbh, hbh, hbhlen);
 2425 
 2426                 break;
 2427         }
 2428 
 2429         case IPV6_DSTOPTS:
 2430         case IPV6_RTHDRDSTOPTS:
 2431         {
 2432                 struct ip6_dest *dest, **newdest = NULL;
 2433                 int destlen;
 2434 
 2435                 if (!priv)      /* XXX: see the comment for IPV6_HOPOPTS */
 2436                         return (EPERM);
 2437 
 2438                 if (len == 0) {
 2439                         ip6_clearpktopts(opt, optname);
 2440                         break;  /* just remove the option */
 2441                 }
 2442 
 2443                 /* message length validation */
 2444                 if (len < sizeof(struct ip6_dest))
 2445                         return (EINVAL);
 2446                 dest = (struct ip6_dest *)buf;
 2447                 destlen = (dest->ip6d_len + 1) << 3;
 2448                 if (len != destlen)
 2449                         return (EINVAL);
 2450                 /*
 2451                  * Determine the position that the destination options header
 2452                  * should be inserted; before or after the routing header.
 2453                  */
 2454                 switch (optname) {
 2455                 case IPV6_RTHDRDSTOPTS:
 2456                         newdest = &opt->ip6po_dest1;
 2457                         break;
 2458                 case IPV6_DSTOPTS:
 2459                         newdest = &opt->ip6po_dest2;
 2460                         break;
 2461                 }
 2462 
 2463                 /* turn off the previous option, then set the new option. */
 2464                 ip6_clearpktopts(opt, optname);
 2465                 *newdest = malloc(destlen, M_IP6OPT, M_NOWAIT);
 2466                 if (*newdest == NULL)
 2467                         return (ENOBUFS);
 2468                 memcpy(*newdest, dest, destlen);
 2469 
 2470                 break;
 2471         }
 2472 
 2473         case IPV6_RTHDR:
 2474         {
 2475                 struct ip6_rthdr *rth;
 2476                 int rthlen;
 2477 
 2478                 if (len == 0) {
 2479                         ip6_clearpktopts(opt, IPV6_RTHDR);
 2480                         break;  /* just remove the option */
 2481                 }
 2482 
 2483                 /* message length validation */
 2484                 if (len < sizeof(struct ip6_rthdr))
 2485                         return (EINVAL);
 2486                 rth = (struct ip6_rthdr *)buf;
 2487                 rthlen = (rth->ip6r_len + 1) << 3;
 2488                 if (len != rthlen)
 2489                         return (EINVAL);
 2490 
 2491                 switch (rth->ip6r_type) {
 2492                 case IPV6_RTHDR_TYPE_0:
 2493                         if (rth->ip6r_len == 0) /* must contain one addr */
 2494                                 return (EINVAL);
 2495                         if (rth->ip6r_len % 2) /* length must be even */
 2496                                 return (EINVAL);
 2497                         if (rth->ip6r_len / 2 != rth->ip6r_segleft)
 2498                                 return (EINVAL);
 2499                         break;
 2500                 default:
 2501                         return (EINVAL);        /* not supported */
 2502                 }
 2503                 /* turn off the previous option */
 2504                 ip6_clearpktopts(opt, IPV6_RTHDR);
 2505                 opt->ip6po_rthdr = malloc(rthlen, M_IP6OPT, M_NOWAIT);
 2506                 if (opt->ip6po_rthdr == NULL)
 2507                         return (ENOBUFS);
 2508                 memcpy(opt->ip6po_rthdr, rth, rthlen);
 2509                 break;
 2510         }
 2511 
 2512         case IPV6_USE_MIN_MTU:
 2513                 if (len != sizeof(int))
 2514                         return (EINVAL);
 2515                 minmtupolicy = *(int *)buf;
 2516                 if (minmtupolicy != IP6PO_MINMTU_MCASTONLY &&
 2517                     minmtupolicy != IP6PO_MINMTU_DISABLE &&
 2518                     minmtupolicy != IP6PO_MINMTU_ALL) {
 2519                         return (EINVAL);
 2520                 }
 2521                 opt->ip6po_minmtu = minmtupolicy;
 2522                 break;
 2523 
 2524         case IPV6_DONTFRAG:
 2525                 if (len != sizeof(int))
 2526                         return (EINVAL);
 2527 
 2528                 if (uproto == IPPROTO_TCP || *(int *)buf == 0) {
 2529                         /*
 2530                          * we ignore this option for TCP sockets.
 2531                          * (RFC3542 leaves this case unspecified.)
 2532                          */
 2533                         opt->ip6po_flags &= ~IP6PO_DONTFRAG;
 2534                 } else
 2535                         opt->ip6po_flags |= IP6PO_DONTFRAG;
 2536                 break;
 2537 
 2538         default:
 2539                 return (ENOPROTOOPT);
 2540         } /* end of switch */
 2541 
 2542         return (0);
 2543 }
 2544 
 2545 /*
 2546  * Routine called from ip6_output() to loop back a copy of an IP6 multicast
 2547  * packet to the input queue of a specified interface.
 2548  */
 2549 void
 2550 ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst)
 2551 {
 2552         struct mbuf *copym;
 2553         struct ip6_hdr *ip6;
 2554 
 2555         /*
 2556          * Duplicate the packet.
 2557          */
 2558         copym = m_copym(m, 0, M_COPYALL, M_NOWAIT);
 2559         if (copym == NULL)
 2560                 return;
 2561 
 2562         /*
 2563          * Make sure to deep-copy IPv6 header portion in case the data
 2564          * is in an mbuf cluster, so that we can safely override the IPv6
 2565          * header portion later.
 2566          */
 2567         if ((copym->m_flags & M_EXT) != 0 ||
 2568             copym->m_len < sizeof(struct ip6_hdr)) {
 2569                 copym = m_pullup(copym, sizeof(struct ip6_hdr));
 2570                 if (copym == NULL)
 2571                         return;
 2572         }
 2573 
 2574 #ifdef DIAGNOSTIC
 2575         if (copym->m_len < sizeof(*ip6)) {
 2576                 m_freem(copym);
 2577                 return;
 2578         }
 2579 #endif
 2580 
 2581         ip6 = mtod(copym, struct ip6_hdr *);
 2582         if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
 2583                 ip6->ip6_src.s6_addr16[1] = 0;
 2584         if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
 2585                 ip6->ip6_dst.s6_addr16[1] = 0;
 2586 
 2587         if_input_local(ifp, copym, dst->sin6_family);
 2588 }
 2589 
 2590 /*
 2591  * Chop IPv6 header off from the payload.
 2592  */
 2593 int
 2594 ip6_splithdr(struct mbuf *m, struct ip6_exthdrs *exthdrs)
 2595 {
 2596         struct mbuf *mh;
 2597         struct ip6_hdr *ip6;
 2598 
 2599         ip6 = mtod(m, struct ip6_hdr *);
 2600         if (m->m_len > sizeof(*ip6)) {
 2601                 MGET(mh, M_DONTWAIT, MT_HEADER);
 2602                 if (mh == NULL) {
 2603                         m_freem(m);
 2604                         return ENOBUFS;
 2605                 }
 2606                 M_MOVE_PKTHDR(mh, m);
 2607                 m_align(mh, sizeof(*ip6));
 2608                 m->m_len -= sizeof(*ip6);
 2609                 m->m_data += sizeof(*ip6);
 2610                 mh->m_next = m;
 2611                 m = mh;
 2612                 m->m_len = sizeof(*ip6);
 2613                 bcopy((caddr_t)ip6, mtod(m, caddr_t), sizeof(*ip6));
 2614         }
 2615         exthdrs->ip6e_ip6 = m;
 2616         return 0;
 2617 }
 2618 
 2619 u_int32_t
 2620 ip6_randomid(void)
 2621 {
 2622         return idgen32(&ip6_id_ctx);
 2623 }
 2624 
 2625 void
 2626 ip6_randomid_init(void)
 2627 {
 2628         idgen32_init(&ip6_id_ctx);
 2629 }
 2630 
 2631 /*
 2632  *      Compute significant parts of the IPv6 checksum pseudo-header
 2633  *      for use in a delayed TCP/UDP checksum calculation.
 2634  */
 2635 static __inline u_int16_t __attribute__((__unused__))
 2636 in6_cksum_phdr(const struct in6_addr *src, const struct in6_addr *dst,
 2637     u_int32_t len, u_int32_t nxt)
 2638 {
 2639         u_int32_t sum = 0;
 2640         const u_int16_t *w;
 2641 
 2642         w = (const u_int16_t *) src;
 2643         sum += w[0];
 2644         if (!IN6_IS_SCOPE_EMBED(src))
 2645                 sum += w[1];
 2646         sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
 2647         sum += w[6]; sum += w[7];
 2648 
 2649         w = (const u_int16_t *) dst;
 2650         sum += w[0];
 2651         if (!IN6_IS_SCOPE_EMBED(dst))
 2652                 sum += w[1];
 2653         sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
 2654         sum += w[6]; sum += w[7];
 2655 
 2656         sum += (u_int16_t)(len >> 16) + (u_int16_t)(len /*& 0xffff*/);
 2657 
 2658         sum += (u_int16_t)(nxt >> 16) + (u_int16_t)(nxt /*& 0xffff*/);
 2659 
 2660         sum = (u_int16_t)(sum >> 16) + (u_int16_t)(sum /*& 0xffff*/);
 2661 
 2662         if (sum > 0xffff)
 2663                 sum -= 0xffff;
 2664 
 2665         return (sum);
 2666 }
 2667 
 2668 /*
 2669  * Process a delayed payload checksum calculation.
 2670  */
 2671 void
 2672 in6_delayed_cksum(struct mbuf *m, u_int8_t nxt)
 2673 {
 2674         int nxtp, offset;
 2675         u_int16_t csum;
 2676 
 2677         offset = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxtp);
 2678         if (offset <= 0 || nxtp != nxt)
 2679                 /* If the desired next protocol isn't found, punt. */
 2680                 return;
 2681         csum = (u_int16_t)(in6_cksum(m, 0, offset, m->m_pkthdr.len - offset));
 2682 
 2683         switch (nxt) {
 2684         case IPPROTO_TCP:
 2685                 offset += offsetof(struct tcphdr, th_sum);
 2686                 break;
 2687 
 2688         case IPPROTO_UDP:
 2689                 offset += offsetof(struct udphdr, uh_sum);
 2690                 if (csum == 0)
 2691                         csum = 0xffff;
 2692                 break;
 2693 
 2694         case IPPROTO_ICMPV6:
 2695                 offset += offsetof(struct icmp6_hdr, icmp6_cksum);
 2696                 break;
 2697         }
 2698 
 2699         if ((offset + sizeof(u_int16_t)) > m->m_len)
 2700                 m_copyback(m, offset, sizeof(csum), &csum, M_NOWAIT);
 2701         else
 2702                 *(u_int16_t *)(mtod(m, caddr_t) + offset) = csum;
 2703 }
 2704 
 2705 void
 2706 in6_proto_cksum_out(struct mbuf *m, struct ifnet *ifp)
 2707 {
 2708         struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
 2709 
 2710         /* some hw and in6_delayed_cksum need the pseudo header cksum */
 2711         if (m->m_pkthdr.csum_flags &
 2712             (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT|M_ICMP_CSUM_OUT)) {
 2713                 int nxt, offset;
 2714                 u_int16_t csum;
 2715 
 2716                 offset = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
 2717                 csum = in6_cksum_phdr(&ip6->ip6_src, &ip6->ip6_dst,
 2718                     htonl(m->m_pkthdr.len - offset), htonl(nxt));
 2719                 if (nxt == IPPROTO_TCP)
 2720                         offset += offsetof(struct tcphdr, th_sum);
 2721                 else if (nxt == IPPROTO_UDP)
 2722                         offset += offsetof(struct udphdr, uh_sum);
 2723                 else if (nxt == IPPROTO_ICMPV6)
 2724                         offset += offsetof(struct icmp6_hdr, icmp6_cksum);
 2725                 if ((offset + sizeof(u_int16_t)) > m->m_len)
 2726                         m_copyback(m, offset, sizeof(csum), &csum, M_NOWAIT);
 2727                 else
 2728                         *(u_int16_t *)(mtod(m, caddr_t) + offset) = csum;
 2729         }
 2730 
 2731         if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) {
 2732                 if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_TCPv6) ||
 2733                     ip6->ip6_nxt != IPPROTO_TCP ||
 2734                     ifp->if_bridgeidx != 0) {
 2735                         tcpstat_inc(tcps_outswcsum);
 2736                         in6_delayed_cksum(m, IPPROTO_TCP);
 2737                         m->m_pkthdr.csum_flags &= ~M_TCP_CSUM_OUT; /* Clear */
 2738                 }
 2739         } else if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) {
 2740                 if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv6) ||
 2741                     ip6->ip6_nxt != IPPROTO_UDP ||
 2742                     ifp->if_bridgeidx != 0) {
 2743                         udpstat_inc(udps_outswcsum);
 2744                         in6_delayed_cksum(m, IPPROTO_UDP);
 2745                         m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */
 2746                 }
 2747         } else if (m->m_pkthdr.csum_flags & M_ICMP_CSUM_OUT) {
 2748                 in6_delayed_cksum(m, IPPROTO_ICMPV6);
 2749                 m->m_pkthdr.csum_flags &= ~M_ICMP_CSUM_OUT; /* Clear */
 2750         }
 2751 }
 2752 
 2753 #ifdef IPSEC
 2754 int
 2755 ip6_output_ipsec_lookup(struct mbuf *m, struct inpcb *inp, struct tdb **tdbout)
 2756 {
 2757         struct tdb *tdb;
 2758         struct m_tag *mtag;
 2759         struct tdb_ident *tdbi;
 2760         int error;
 2761 
 2762         /*
 2763          * Check if there was an outgoing SA bound to the flow
 2764          * from a transport protocol.
 2765          */
 2766 
 2767         /* Do we have any pending SAs to apply ? */
 2768         error = ipsp_spd_lookup(m, AF_INET6, sizeof(struct ip6_hdr),
 2769             IPSP_DIRECTION_OUT, NULL, inp, &tdb, NULL);
 2770         if (error || tdb == NULL) {
 2771                 *tdbout = NULL;
 2772                 return error;
 2773         }
 2774         /* Loop detection */
 2775         for (mtag = m_tag_first(m); mtag != NULL; mtag = m_tag_next(m, mtag)) {
 2776                 if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE)
 2777                         continue;
 2778                 tdbi = (struct tdb_ident *)(mtag + 1);
 2779                 if (tdbi->spi == tdb->tdb_spi &&
 2780                     tdbi->proto == tdb->tdb_sproto &&
 2781                     tdbi->rdomain == tdb->tdb_rdomain &&
 2782                     !memcmp(&tdbi->dst, &tdb->tdb_dst,
 2783                     sizeof(union sockaddr_union))) {
 2784                         /* no IPsec needed */
 2785                         tdb_unref(tdb);
 2786                         *tdbout = NULL;
 2787                         return 0;
 2788                 }
 2789         }
 2790         *tdbout = tdb;
 2791         return 0;
 2792 }
 2793 
 2794 int
 2795 ip6_output_ipsec_pmtu_update(struct tdb *tdb, struct route_in6 *ro,
 2796     struct in6_addr *dst, int ifidx, int rtableid, int transportmode)
 2797 {
 2798         struct rtentry *rt = NULL;
 2799         int rt_mtucloned = 0;
 2800 
 2801         /* Find a host route to store the mtu in */
 2802         if (ro != NULL)
 2803                 rt = ro->ro_rt;
 2804         /* but don't add a PMTU route for transport mode SAs */
 2805         if (transportmode)
 2806                 rt = NULL;
 2807         else if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0) {
 2808                 struct sockaddr_in6 sin6;
 2809                 int error;
 2810 
 2811                 memset(&sin6, 0, sizeof(sin6));
 2812                 sin6.sin6_family = AF_INET6;
 2813                 sin6.sin6_len = sizeof(sin6);
 2814                 sin6.sin6_addr = *dst;
 2815                 sin6.sin6_scope_id = in6_addr2scopeid(ifidx, dst);
 2816                 error = in6_embedscope(dst, &sin6, NULL);
 2817                 if (error) {
 2818                         /* should be impossible */
 2819                         return error;
 2820                 }
 2821                 rt = icmp6_mtudisc_clone(&sin6, rtableid, 1);
 2822                 rt_mtucloned = 1;
 2823         }
 2824         DPRINTF("spi %08x mtu %d rt %p cloned %d",
 2825             ntohl(tdb->tdb_spi), tdb->tdb_mtu, rt, rt_mtucloned);
 2826         if (rt != NULL) {
 2827                 rt->rt_mtu = tdb->tdb_mtu;
 2828                 if (ro != NULL && ro->ro_rt != NULL) {
 2829                         rtfree(ro->ro_rt);
 2830                         ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst), RT_RESOLVE,
 2831                             rtableid);
 2832                 }
 2833                 if (rt_mtucloned)
 2834                         rtfree(rt);
 2835         }
 2836         return 0;
 2837 }
 2838 
 2839 int
 2840 ip6_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route_in6 *ro,
 2841     int tunalready, int fwd)
 2842 {
 2843 #if NPF > 0
 2844         struct ifnet *encif;
 2845 #endif
 2846         struct ip6_hdr *ip6;
 2847         struct in6_addr dst;
 2848         int error, ifidx, rtableid;
 2849 
 2850 #if NPF > 0
 2851         /*
 2852          * Packet filter
 2853          */
 2854         if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) == NULL ||
 2855             pf_test(AF_INET6, fwd ? PF_FWD : PF_OUT, encif, &m) != PF_PASS) {
 2856                 m_freem(m);
 2857                 return EACCES;
 2858         }
 2859         if (m == NULL)
 2860                 return 0;
 2861         /*
 2862          * PF_TAG_REROUTE handling or not...
 2863          * Packet is entering IPsec so the routing is
 2864          * already overruled by the IPsec policy.
 2865          * Until now the change was not reconsidered.
 2866          * What's the behaviour?
 2867          */
 2868         in6_proto_cksum_out(m, encif);
 2869 #endif
 2870 
 2871         /* Check if we are allowed to fragment */
 2872         ip6 = mtod(m, struct ip6_hdr *);
 2873         dst = ip6->ip6_dst;
 2874         ifidx = m->m_pkthdr.ph_ifidx;
 2875         rtableid = m->m_pkthdr.ph_rtableid;
 2876         if (ip_mtudisc && tdb->tdb_mtu &&
 2877             sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen) > tdb->tdb_mtu &&
 2878             tdb->tdb_mtutimeout > gettime()) {
 2879                 int transportmode;
 2880 
 2881                 transportmode = (tdb->tdb_dst.sa.sa_family == AF_INET6) &&
 2882                     (IN6_ARE_ADDR_EQUAL(&tdb->tdb_dst.sin6.sin6_addr, &dst));
 2883                 error = ip6_output_ipsec_pmtu_update(tdb, ro, &dst, ifidx,
 2884                     rtableid, transportmode);
 2885                 if (error) {
 2886                         ipsecstat_inc(ipsec_odrops);
 2887                         tdbstat_inc(tdb, tdb_odrops);
 2888                         m_freem(m);
 2889                         return error;
 2890                 }
 2891                 ipsec_adjust_mtu(m, tdb->tdb_mtu);
 2892                 m_freem(m);
 2893                 return EMSGSIZE;
 2894         }
 2895         /* propagate don't fragment for v6-over-v6 */
 2896         if (ip_mtudisc)
 2897                 SET(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT);
 2898 
 2899         /*
 2900          * Clear these -- they'll be set in the recursive invocation
 2901          * as needed.
 2902          */
 2903         m->m_flags &= ~(M_BCAST | M_MCAST);
 2904 
 2905         /* Callee frees mbuf */
 2906         KERNEL_LOCK();
 2907         error = ipsp_process_packet(m, tdb, AF_INET6, tunalready);
 2908         KERNEL_UNLOCK();
 2909         if (error) {
 2910                 ipsecstat_inc(ipsec_odrops);
 2911                 tdbstat_inc(tdb, tdb_odrops);
 2912         }
 2913         if (ip_mtudisc && error == EMSGSIZE)
 2914                 ip6_output_ipsec_pmtu_update(tdb, ro, &dst, ifidx, rtableid, 0);
 2915         return error;
 2916 }
 2917 #endif /* IPSEC */

Cache object: 6d9f77b67dacf5a24b37f811c5b5ae10


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