2  * Copyright (c) 2000-2015 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  30  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 
  31  * All rights reserved. 
  33  * Redistribution and use in source and binary forms, with or without 
  34  * modification, are permitted provided that the following conditions 
  36  * 1. Redistributions of source code must retain the above copyright 
  37  *    notice, this list of conditions and the following disclaimer. 
  38  * 2. Redistributions in binary form must reproduce the above copyright 
  39  *    notice, this list of conditions and the following disclaimer in the 
  40  *    documentation and/or other materials provided with the distribution. 
  41  * 3. Neither the name of the project nor the names of its contributors 
  42  *    may be used to endorse or promote products derived from this software 
  43  *    without specific prior written permission. 
  45  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
  46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
  49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  59  * Copyright (c) 1982, 1986, 1988, 1990, 1993 
  60  *      The Regents of the University of California.  All rights reserved. 
  62  * Redistribution and use in source and binary forms, with or without 
  63  * modification, are permitted provided that the following conditions 
  65  * 1. Redistributions of source code must retain the above copyright 
  66  *    notice, this list of conditions and the following disclaimer. 
  67  * 2. Redistributions in binary form must reproduce the above copyright 
  68  *    notice, this list of conditions and the following disclaimer in the 
  69  *    documentation and/or other materials provided with the distribution. 
  70  * 3. All advertising materials mentioning features or use of this software 
  71  *    must display the following acknowledgement: 
  72  *      This product includes software developed by the University of 
  73  *      California, Berkeley and its contributors. 
  74  * 4. Neither the name of the University nor the names of its contributors 
  75  *    may be used to endorse or promote products derived from this software 
  76  *    without specific prior written permission. 
  78  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  79  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  80  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  81  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  82  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  83  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  84  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  85  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  86  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  87  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  90  *      @(#)ip_output.c 8.3 (Berkeley) 1/21/94 
  93  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 
  94  * support for mandatory and extensible security protections.  This notice 
  95  * is included in support of clause 2.2 (b) of the Apple Public License, 
  99 #include <sys/param.h> 
 100 #include <sys/malloc.h> 
 101 #include <sys/mbuf.h> 
 102 #include <sys/errno.h> 
 103 #include <sys/protosw.h> 
 104 #include <sys/socket.h> 
 105 #include <sys/socketvar.h> 
 106 #include <sys/systm.h> 
 107 #include <sys/kernel.h> 
 108 #include <sys/proc.h> 
 109 #include <sys/kauth.h> 
 110 #include <sys/mcache.h> 
 111 #include <sys/sysctl.h> 
 112 #include <kern/zalloc.h> 
 113 #include <libkern/OSByteOrder.h> 
 115 #include <pexpert/pexpert.h> 
 116 #include <mach/sdt.h> 
 119 #include <net/route.h> 
 120 #include <net/dlil.h> 
 121 #include <net/net_osdep.h> 
 122 #include <net/net_perf.h> 
 124 #include <netinet/in.h> 
 125 #include <netinet/in_var.h> 
 126 #include <netinet/ip_var.h> 
 127 #include <netinet6/in6_var.h> 
 128 #include <netinet/ip6.h> 
 129 #include <netinet/kpi_ipfilter_var.h> 
 131 #include <netinet6/ip6protosw.h> 
 132 #include <netinet/icmp6.h> 
 133 #include <netinet6/ip6_var.h> 
 134 #include <netinet/in_pcb.h> 
 135 #include <netinet6/nd6.h> 
 136 #include <netinet6/scope6_var.h> 
 138 #include <netinet6/ipsec.h> 
 139 #include <netinet6/ipsec6.h> 
 140 #include <netkey/key.h> 
 141 extern int ipsec_bypass
; 
 145 #include <net/necp.h> 
 149 #include <security/mac.h> 
 150 #endif /* CONFIG_MACF_NET */ 
 153 #include <netinet6/ip6_fw.h> 
 154 #include <netinet/ip_fw.h> 
 155 #include <netinet/ip_dummynet.h> 
 156 #endif /* DUMMYNET */ 
 159 #include <net/pfvar.h> 
 162 static int sysctl_reset_ip6_output_stats SYSCTL_HANDLER_ARGS
; 
 163 static int sysctl_ip6_output_measure_bins SYSCTL_HANDLER_ARGS
; 
 164 static int sysctl_ip6_output_getperf SYSCTL_HANDLER_ARGS
; 
 165 static int ip6_copyexthdr(struct mbuf 
**, caddr_t
, int); 
 166 static void ip6_out_cksum_stats(int, u_int32_t
); 
 167 static int ip6_insert_jumboopt(struct ip6_exthdrs 
*, u_int32_t
); 
 168 static int ip6_insertfraghdr(struct mbuf 
*, struct mbuf 
*, int, 
 170 static int ip6_getpmtu(struct route_in6 
*, struct route_in6 
*, 
 171     struct ifnet 
*, struct in6_addr 
*, u_int32_t 
*, boolean_t 
*); 
 172 static int ip6_pcbopts(struct ip6_pktopts 
**, struct mbuf 
*, struct socket 
*, 
 173     struct sockopt 
*sopt
); 
 174 static int ip6_pcbopt(int, u_char 
*, int, struct ip6_pktopts 
**, int); 
 175 static int ip6_getpcbopt(struct ip6_pktopts 
*, int, struct sockopt 
*); 
 176 static int copypktopts(struct ip6_pktopts 
*, struct ip6_pktopts 
*, int); 
 177 static void im6o_trace(struct ip6_moptions 
*, int); 
 178 static int ip6_setpktopt(int, u_char 
*, int, struct ip6_pktopts 
*, int, 
 180 static int ip6_splithdr(struct mbuf 
*, struct ip6_exthdrs 
*); 
 181 static void ip6_output_checksum(struct ifnet 
*, uint32_t, struct mbuf 
*, 
 182     int, uint32_t, uint32_t); 
 183 extern int udp_ctloutput(struct socket 
*, struct sockopt 
*); 
 184 static int ip6_do_fragmentation(struct mbuf 
**morig
, 
 185     uint32_t optlen
, struct ifnet 
*ifp
, uint32_t unfragpartlen
, 
 186     struct ip6_hdr 
*ip6
, struct ip6_exthdrs 
*exthdrsp
, uint32_t mtu
, 
 188 static int ip6_fragment_packet(struct mbuf 
**m
, 
 189     struct ip6_pktopts 
*opt
, struct ip6_exthdrs 
*exthdrsp
, struct ifnet 
*ifp
, 
 190     uint32_t mtu
, boolean_t alwaysfrag
, uint32_t unfragpartlen
, 
 191     struct route_in6 
*ro_pmtu
, int nxt0
, uint32_t optlen
); 
 193 SYSCTL_DECL(_net_inet6_ip6
); 
 195 static int ip6_output_measure 
= 0; 
 196 SYSCTL_PROC(_net_inet6_ip6
, OID_AUTO
, output_perf
, 
 197         CTLTYPE_INT 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, 
 198         &ip6_output_measure
, 0, sysctl_reset_ip6_output_stats
, "I", "Do time measurement"); 
 200 static uint64_t ip6_output_measure_bins 
= 0; 
 201 SYSCTL_PROC(_net_inet6_ip6
, OID_AUTO
, output_perf_bins
, 
 202         CTLTYPE_QUAD 
| CTLFLAG_RW 
| CTLFLAG_LOCKED
, &ip6_output_measure_bins
, 0, 
 203         sysctl_ip6_output_measure_bins
, "I", 
 204         "bins for chaining performance data histogram"); 
 206 static net_perf_t net_perf
; 
 207 SYSCTL_PROC(_net_inet6_ip6
, OID_AUTO
, output_perf_data
, 
 208         CTLTYPE_STRUCT 
| CTLFLAG_RD 
| CTLFLAG_LOCKED
, 
 209         0, 0, sysctl_ip6_output_getperf
, "S,net_perf", 
 210         "IP6 output performance data (struct net_perf, net/net_perf.h)"); 
 212 #define IM6O_TRACE_HIST_SIZE    32      /* size of trace history */ 
 215 __private_extern__ 
unsigned int im6o_trace_hist_size 
= IM6O_TRACE_HIST_SIZE
; 
 217 struct ip6_moptions_dbg 
{ 
 218         struct ip6_moptions     im6o
;                   /* ip6_moptions */ 
 219         u_int16_t               im6o_refhold_cnt
;       /* # of IM6O_ADDREF */ 
 220         u_int16_t               im6o_refrele_cnt
;       /* # of IM6O_REMREF */ 
 222          * Alloc and free callers. 
 227          * Circular lists of IM6O_ADDREF and IM6O_REMREF callers. 
 229         ctrace_t                im6o_refhold
[IM6O_TRACE_HIST_SIZE
]; 
 230         ctrace_t                im6o_refrele
[IM6O_TRACE_HIST_SIZE
]; 
 234 static unsigned int im6o_debug 
= 1;     /* debugging (enabled) */ 
 236 static unsigned int im6o_debug
;         /* debugging (disabled) */ 
 239 static unsigned int im6o_size
;          /* size of zone element */ 
 240 static struct zone 
*im6o_zone
;          /* zone for ip6_moptions */ 
 242 #define IM6O_ZONE_MAX           64              /* maximum elements in zone */ 
 243 #define IM6O_ZONE_NAME          "ip6_moptions"  /* zone name */ 
 246  * ip6_output() calls ip6_output_list() to do the work 
 249 ip6_output(struct mbuf 
*m0
, struct ip6_pktopts 
*opt
, 
 250     struct route_in6 
*ro
, int flags
, struct ip6_moptions 
*im6o
, 
 251     struct ifnet 
**ifpp
, struct ip6_out_args 
*ip6oa
) 
 253         return ip6_output_list(m0
, 0, opt
, ro
, flags
, im6o
, ifpp
, ip6oa
); 
 257  * IP6 output. Each packet in mbuf chain m contains a skeletal IP6 
 258  * header (with pri, len, nxt, hlim, src, dst). 
 259  * This function may modify ver and hlim only. 
 260  * The mbuf chain containing the packet will be freed. 
 261  * The mbuf opt, if present, will not be freed. 
 263  * If ro is non-NULL and has valid ro->ro_rt, route lookup would be 
 264  * skipped and ro->ro_rt would be used.  Otherwise the result of route 
 265  * lookup is stored in ro->ro_rt. 
 267  * type of "mtu": rt_rmx.rmx_mtu is u_int32_t, ifnet.ifr_mtu is int, and 
 268  * nd_ifinfo.linkmtu is u_int32_t.  so we use u_int32_t to hold largest one, 
 269  * which is rt_rmx.rmx_mtu. 
 272 ip6_output_list(struct mbuf 
*m0
, int packetchain
, struct ip6_pktopts 
*opt
, 
 273     struct route_in6 
*ro
, int flags
, struct ip6_moptions 
*im6o
, 
 274     struct ifnet 
**ifpp
, struct ip6_out_args 
*ip6oa
) 
 278         struct ifnet 
*ifp 
= NULL
, *origifp 
= NULL
;      /* refcnt'd */ 
 279         struct ifnet 
**ifpp_save 
= ifpp
; 
 280         struct mbuf 
*m
, *mprev
; 
 281         struct mbuf 
*sendchain 
= NULL
, *sendchain_last 
= NULL
; 
 282         struct mbuf 
*inputchain 
= NULL
; 
 284         struct route_in6 
*ro_pmtu 
= NULL
; 
 285         struct rtentry 
*rt 
= NULL
; 
 286         struct sockaddr_in6 
*dst
, src_sa
, dst_sa
; 
 288         struct in6_ifaddr 
*ia 
= NULL
, *src_ia 
= NULL
; 
 290         boolean_t alwaysfrag 
= FALSE
; 
 291         u_int32_t optlen 
= 0, plen 
= 0, unfragpartlen 
= 0; 
 292         struct ip6_rthdr 
*rh
; 
 293         struct in6_addr finaldst
; 
 294         ipfilter_t inject_filter_ref
; 
 295         struct ipf_pktopts 
*ippo 
= NULL
; 
 296         struct flowadv 
*adv 
= NULL
; 
 298         uint32_t packets_processed 
= 0; 
 299         struct timeval start_tv
; 
 302         struct ip6_out_args saved_ip6oa
; 
 303         struct sockaddr_in6 dst_buf
; 
 304 #endif /* DUMMYNET */ 
 306         struct socket 
*so 
= NULL
; 
 307         struct secpolicy 
*sp 
= NULL
; 
 308         struct route_in6 
*ipsec_saved_route 
= NULL
; 
 309         boolean_t needipsectun 
= FALSE
; 
 312         necp_kernel_policy_result necp_result 
= 0; 
 313         necp_kernel_policy_result_parameter necp_result_parameter
; 
 314         necp_kernel_policy_id necp_matched_policy_id 
= 0; 
 317                 struct ipf_pktopts ipf_pktopts
; 
 318                 struct ip6_exthdrs exthdrs
; 
 319                 struct route_in6 ip6route
; 
 321                 struct ipsec_output_state ipsec_state
; 
 324                 struct route_in6 necp_route
; 
 327                 struct route_in6 saved_route
; 
 328                 struct route_in6 saved_ro_pmtu
; 
 329                 struct ip_fw_args args
; 
 330 #endif /* DUMMYNET */ 
 332 #define ipf_pktopts     ip6obz.ipf_pktopts 
 333 #define exthdrs         ip6obz.exthdrs 
 334 #define ip6route        ip6obz.ip6route 
 335 #define ipsec_state     ip6obz.ipsec_state 
 336 #define necp_route      ip6obz.necp_route 
 337 #define saved_route     ip6obz.saved_route 
 338 #define saved_ro_pmtu   ip6obz.saved_ro_pmtu 
 339 #define args            ip6obz.args 
 342                         boolean_t select_srcif 
: 1; 
 343                         boolean_t hdrsplit 
: 1; 
 344                         boolean_t route_selected 
: 1; 
 345                         boolean_t dontfrag 
: 1; 
 347                         boolean_t needipsec 
: 1; 
 348                         boolean_t noipsec 
: 1; 
 352         } ip6obf 
= { .raw 
= 0 }; 
 354         if (ip6_output_measure
) 
 355                 net_perf_start_time(&net_perf
, &start_tv
); 
 357         VERIFY(m0
->m_flags 
& M_PKTHDR
); 
 359         /* zero out {saved_route, saved_ro_pmtu, ip6route, exthdrs, args} */ 
 360         bzero(&ip6obz
, sizeof (ip6obz
)); 
 363         if (SLIST_EMPTY(&m0
->m_pkthdr
.tags
)) 
 366         /* Grab info from mtags prepended to the chain */ 
 367         if ((tag 
= m_tag_locate(m0
, KERNEL_MODULE_TAG_ID
, 
 368             KERNEL_TAG_TYPE_DUMMYNET
, NULL
)) != NULL
) { 
 369                 struct dn_pkt_tag       
*dn_tag
; 
 372                  * ip6_output_list() cannot handle chains of packets reinjected 
 373                  * by dummynet. The same restriction applies to 
 376                 VERIFY(0 == packetchain
); 
 378                 dn_tag 
= (struct dn_pkt_tag 
*)(tag
+1); 
 379                 args
.fwa_pf_rule 
= dn_tag
->dn_pf_rule
; 
 381                 bcopy(&dn_tag
->dn_dst6
, &dst_buf
, sizeof (dst_buf
)); 
 383                 ifp 
= dn_tag
->dn_ifp
; 
 385                         ifnet_reference(ifp
); 
 386                 flags 
= dn_tag
->dn_flags
; 
 387                 if (dn_tag
->dn_flags 
& IPV6_OUTARGS
) { 
 388                         saved_ip6oa 
= dn_tag
->dn_ip6oa
; 
 389                         ip6oa 
= &saved_ip6oa
; 
 392                 saved_route 
= dn_tag
->dn_ro6
; 
 394                 saved_ro_pmtu 
= dn_tag
->dn_ro6_pmtu
; 
 395                 ro_pmtu 
= &saved_ro_pmtu
; 
 396                 origifp 
= dn_tag
->dn_origifp
; 
 398                         ifnet_reference(origifp
); 
 399                 mtu 
= dn_tag
->dn_mtu
; 
 400                 alwaysfrag 
= (dn_tag
->dn_alwaysfrag 
!= 0); 
 401                 unfragpartlen 
= dn_tag
->dn_unfragpartlen
; 
 403                 bcopy(&dn_tag
->dn_exthdrs
, &exthdrs
, sizeof (exthdrs
)); 
 405                 m_tag_delete(m0
, tag
); 
 409 #endif /* DUMMYNET */ 
 414         if (ipsec_bypass 
== 0) { 
 415                 so 
= ipsec_getsocket(m
); 
 417                         (void) ipsec_setsocket(m
, NULL
); 
 419                 /* If packet is bound to an interface, check bound policies */ 
 420                 if ((flags 
& IPV6_OUTARGS
) && 
 421                         (ip6oa
->ip6oa_flags 
& IPOAF_BOUND_IF
) && 
 422                         ip6oa
->ip6oa_boundif 
!= IFSCOPE_NONE
) { 
 423                         /* ip6obf.noipsec is a bitfield, use temp integer */ 
 426                         if (ipsec6_getpolicybyinterface(m
, IPSEC_DIR_OUTBOUND
, 
 427                                 flags
, ip6oa
, &noipsec
, &sp
) != 0) 
 430                         ip6obf
.noipsec 
= (noipsec 
!= 0); 
 437         if (ip6_doscopedroute 
&& (flags 
& IPV6_OUTARGS
)) { 
 439                  * In the forwarding case, only the ifscope value is used, 
 440                  * as source interface selection doesn't take place. 
 442                 if ((ip6obf
.select_srcif 
= (!(flags 
& (IPV6_FORWARDING 
| 
 443                     IPV6_UNSPECSRC 
| IPV6_FLAG_NOSRCIFSEL
)) && 
 444                     (ip6oa
->ip6oa_flags 
& IP6OAF_SELECT_SRCIF
)))) 
 445                         ipf_pktopts
.ippo_flags 
|= IPPOF_SELECT_SRCIF
; 
 447                 if ((ip6oa
->ip6oa_flags 
& IP6OAF_BOUND_IF
) && 
 448                     ip6oa
->ip6oa_boundif 
!= IFSCOPE_NONE
) { 
 449                         ipf_pktopts
.ippo_flags 
|= (IPPOF_BOUND_IF 
| 
 450                             (ip6oa
->ip6oa_boundif 
<< IPPOF_SHIFT_IFSCOPE
)); 
 453                 if (ip6oa
->ip6oa_flags 
& IP6OAF_BOUND_SRCADDR
) 
 454                         ipf_pktopts
.ippo_flags 
|= IPPOF_BOUND_SRCADDR
; 
 456                 ip6obf
.select_srcif 
= FALSE
; 
 457                 if (flags 
& IPV6_OUTARGS
) { 
 458                         ip6oa
->ip6oa_boundif 
= IFSCOPE_NONE
; 
 459                         ip6oa
->ip6oa_flags 
&= ~(IP6OAF_SELECT_SRCIF 
| 
 460                             IP6OAF_BOUND_IF 
| IP6OAF_BOUND_SRCADDR
); 
 464         if (flags 
& IPV6_OUTARGS
) { 
 465                 if (ip6oa
->ip6oa_flags 
& IP6OAF_NO_CELLULAR
) 
 466                         ipf_pktopts
.ippo_flags 
|= IPPOF_NO_IFT_CELLULAR
; 
 467                 if (ip6oa
->ip6oa_flags 
& IP6OAF_NO_EXPENSIVE
) 
 468                         ipf_pktopts
.ippo_flags 
|= IPPOF_NO_IFF_EXPENSIVE
; 
 469                 adv 
= &ip6oa
->ip6oa_flowadv
; 
 470                 adv
->code 
= FADV_SUCCESS
; 
 471                 ip6oa
->ip6oa_retflags 
= 0; 
 475          * Clear out ifpp to be filled in after determining route. ifpp_save is 
 476          * used to keep old value to release reference properly and dtrace 
 477          * ipsec tunnel traffic properly. 
 479         if (ifpp 
!= NULL 
&& *ifpp 
!= NULL
) 
 483         if (args
.fwa_pf_rule
) { 
 484                 ip6 
= mtod(m
, struct ip6_hdr 
*); 
 485                 VERIFY(ro 
!= NULL
);     /* ro == saved_route */ 
 488 #endif /* DUMMYNET */ 
 492          * Since all packets are assumed to come from same socket, necp lookup 
 493          * only needs to happen once per function entry. 
 495         necp_matched_policy_id 
= necp_ip6_output_find_policy_match(m
, flags
, 
 496             (flags 
& IPV6_OUTARGS
) ? ip6oa 
: NULL
, &necp_result
, 
 497             &necp_result_parameter
); 
 501          * If a chain was passed in, prepare for ther first iteration. For all 
 502          * other iterations, this work will be done at evaluateloop: label. 
 506                  * Remove m from the chain during processing to avoid 
 507                  * accidental frees on entire list. 
 509                 inputchain 
= m
->m_nextpkt
; 
 515         m
->m_pkthdr
.pkt_flags 
&= ~(PKTF_LOOP
|PKTF_IFAINFO
); 
 516         ip6 
= mtod(m
, struct ip6_hdr 
*); 
 518         finaldst 
= ip6
->ip6_dst
; 
 519         ip6obf
.hdrsplit 
= FALSE
; 
 522         if (!SLIST_EMPTY(&m
->m_pkthdr
.tags
)) 
 523                 inject_filter_ref 
= ipf_get_inject_filter(m
); 
 525                 inject_filter_ref 
= NULL
; 
 527 #define MAKE_EXTHDR(hp, mp) do {                                        \ 
 529                 struct ip6_ext *eh = (struct ip6_ext *)(hp);            \ 
 530                 error = ip6_copyexthdr((mp), (caddr_t)(hp),             \ 
 531                     ((eh)->ip6e_len + 1) << 3);                         \ 
 538                 /* Hop-by-Hop options header */ 
 539                 MAKE_EXTHDR(opt
->ip6po_hbh
, &exthdrs
.ip6e_hbh
); 
 540                 /* Destination options header(1st part) */ 
 541                 if (opt
->ip6po_rthdr
) { 
 543                          * Destination options header(1st part) 
 544                          * This only makes sense with a routing header. 
 545                          * See Section 9.2 of RFC 3542. 
 546                          * Disabling this part just for MIP6 convenience is 
 547                          * a bad idea.  We need to think carefully about a 
 548                          * way to make the advanced API coexist with MIP6 
 549                          * options, which might automatically be inserted in 
 552                         MAKE_EXTHDR(opt
->ip6po_dest1
, &exthdrs
.ip6e_dest1
); 
 555                 MAKE_EXTHDR(opt
->ip6po_rthdr
, &exthdrs
.ip6e_rthdr
); 
 556                 /* Destination options header(2nd part) */ 
 557                 MAKE_EXTHDR(opt
->ip6po_dest2
, &exthdrs
.ip6e_dest2
); 
 563         if (necp_matched_policy_id
) { 
 564                 necp_mark_packet_from_ip(m
, necp_matched_policy_id
); 
 566                 switch (necp_result
) { 
 567                 case NECP_KERNEL_POLICY_RESULT_PASS
: 
 569                 case NECP_KERNEL_POLICY_RESULT_DROP
: 
 570                 case NECP_KERNEL_POLICY_RESULT_SOCKET_DIVERT
: 
 572                          * Flow divert packets should be blocked at the IP 
 575                         error 
= EHOSTUNREACH
; 
 577                 case NECP_KERNEL_POLICY_RESULT_IP_TUNNEL
: { 
 579                          * Verify that the packet is being routed to the tunnel 
 581                         struct ifnet 
*policy_ifp 
= 
 582                             necp_get_ifnet_from_result_parameter( 
 583                                 &necp_result_parameter
); 
 585                         if (policy_ifp 
== ifp
) { 
 588                                 if (necp_packet_can_rebind_to_ifnet(m
, 
 589                                     policy_ifp
, (struct route 
*)&necp_route
, 
 592                                          * Set scoped index to the tunnel 
 593                                          * interface, since it is compatible 
 594                                          * with the packet. This will only work 
 595                                          * for callers who pass IPV6_OUTARGS, 
 596                                          * but that covers all of the clients 
 597                                          * we care about today. 
 599                                         if (flags 
& IPV6_OUTARGS
) { 
 600                                                 ip6oa
->ip6oa_boundif 
= 
 601                                                     policy_ifp
->if_index
; 
 602                                                 ip6oa
->ip6oa_flags 
|= 
 606                                             && opt
->ip6po_pktinfo 
!= NULL
) { 
 609                                                         policy_ifp
->if_index
; 
 627         if (ipsec_bypass 
!= 0 || ip6obf
.noipsec
) 
 631                 /* get a security policy for this packet */ 
 633                         sp 
= ipsec6_getpolicybysock(m
, IPSEC_DIR_OUTBOUND
, 
 636                         sp 
= ipsec6_getpolicybyaddr(m
, IPSEC_DIR_OUTBOUND
, 
 640                         IPSEC_STAT_INCREMENT(ipsec6stat
.out_inval
); 
 648         switch (sp
->policy
) { 
 649         case IPSEC_POLICY_DISCARD
: 
 650         case IPSEC_POLICY_GENERATE
: 
 652                  * This packet is just discarded. 
 654                 IPSEC_STAT_INCREMENT(ipsec6stat
.out_polvio
); 
 657         case IPSEC_POLICY_BYPASS
: 
 658         case IPSEC_POLICY_NONE
: 
 659                 /* no need to do IPsec. */ 
 660                 ip6obf
.needipsec 
= FALSE
; 
 663         case IPSEC_POLICY_IPSEC
: 
 664                 if (sp
->req 
== NULL
) { 
 665                         /* acquire a policy */ 
 666                         error 
= key_spdacquire(sp
); 
 672                         ip6obf
.needipsec 
= TRUE
; 
 676         case IPSEC_POLICY_ENTRUST
: 
 678                 printf("%s: Invalid policy found: %d\n", __func__
, sp
->policy
); 
 685          * Calculate the total length of the extension header chain. 
 686          * Keep the length of the unfragmentable part for fragmentation. 
 689         if (exthdrs
.ip6e_hbh 
!= NULL
) 
 690                 optlen 
+= exthdrs
.ip6e_hbh
->m_len
; 
 691         if (exthdrs
.ip6e_dest1 
!= NULL
) 
 692                 optlen 
+= exthdrs
.ip6e_dest1
->m_len
; 
 693         if (exthdrs
.ip6e_rthdr 
!= NULL
) 
 694                 optlen 
+= exthdrs
.ip6e_rthdr
->m_len
; 
 695         unfragpartlen 
= optlen 
+ sizeof (struct ip6_hdr
); 
 697         /* NOTE: we don't add AH/ESP length here. do that later. */ 
 698         if (exthdrs
.ip6e_dest2 
!= NULL
) 
 699                 optlen 
+= exthdrs
.ip6e_dest2
->m_len
; 
 702          * If we need IPsec, or there is at least one extension header, 
 703          * separate IP6 header from the payload. 
 709             optlen
) && !ip6obf
.hdrsplit
) { 
 710                 if ((error 
= ip6_splithdr(m
, &exthdrs
)) != 0) { 
 714                 m 
= exthdrs
.ip6e_ip6
; 
 715                 ip6obf
.hdrsplit 
= TRUE
; 
 719         ip6 
= mtod(m
, struct ip6_hdr 
*); 
 721         /* adjust mbuf packet header length */ 
 722         m
->m_pkthdr
.len 
+= optlen
; 
 723         plen 
= m
->m_pkthdr
.len 
- sizeof (*ip6
); 
 725         /* If this is a jumbo payload, insert a jumbo payload option. */ 
 726         if (plen 
> IPV6_MAXPACKET
) { 
 727                 if (!ip6obf
.hdrsplit
) { 
 728                         if ((error 
= ip6_splithdr(m
, &exthdrs
)) != 0) { 
 732                         m 
= exthdrs
.ip6e_ip6
; 
 733                         ip6obf
.hdrsplit 
= TRUE
; 
 736                 ip6 
= mtod(m
, struct ip6_hdr 
*); 
 737                 if ((error 
= ip6_insert_jumboopt(&exthdrs
, plen
)) != 0) 
 741                 ip6
->ip6_plen 
= htons(plen
); 
 744          * Concatenate headers and fill in next header fields. 
 745          * Here we have, on "m" 
 747          * and we insert headers accordingly.  Finally, we should be getting: 
 748          *      IPv6 hbh dest1 rthdr ah* [esp* dest2 payload] 
 750          * during the header composing process, "m" points to IPv6 header. 
 751          * "mprev" points to an extension header prior to esp. 
 753         nexthdrp 
= &ip6
->ip6_nxt
; 
 757          * we treat dest2 specially.  this makes IPsec processing 
 758          * much easier.  the goal here is to make mprev point the 
 759          * mbuf prior to dest2. 
 761          * result: IPv6 dest2 payload 
 762          * m and mprev will point to IPv6 header. 
 764         if (exthdrs
.ip6e_dest2 
!= NULL
) { 
 765                 if (!ip6obf
.hdrsplit
) { 
 766                         panic("assumption failed: hdr not split"); 
 769                 exthdrs
.ip6e_dest2
->m_next 
= m
->m_next
; 
 770                 m
->m_next 
= exthdrs
.ip6e_dest2
; 
 771                 *mtod(exthdrs
.ip6e_dest2
, u_char 
*) = ip6
->ip6_nxt
; 
 772                 ip6
->ip6_nxt 
= IPPROTO_DSTOPTS
; 
 775 #define MAKE_CHAIN(m, mp, p, i) do {                                    \ 
 777                 if (!ip6obf.hdrsplit) {                                 \ 
 778                         panic("assumption failed: hdr not split");      \ 
 781                 *mtod((m), u_char *) = *(p);                            \ 
 783                 p = mtod((m), u_char *);                                \ 
 784                 (m)->m_next = (mp)->m_next;                             \ 
 785                 (mp)->m_next = (m);                                     \ 
 790          * result: IPv6 hbh dest1 rthdr dest2 payload 
 791          * m will point to IPv6 header.  mprev will point to the 
 792          * extension header prior to dest2 (rthdr in the above case). 
 794         MAKE_CHAIN(exthdrs
.ip6e_hbh
, mprev
, nexthdrp
, IPPROTO_HOPOPTS
); 
 795         MAKE_CHAIN(exthdrs
.ip6e_dest1
, mprev
, nexthdrp
, IPPROTO_DSTOPTS
); 
 796         MAKE_CHAIN(exthdrs
.ip6e_rthdr
, mprev
, nexthdrp
, IPPROTO_ROUTING
); 
 798         /* It is no longer safe to free the pointers in exthdrs. */ 
 799         exthdrs
.merged 
= TRUE
; 
 804         if (ip6obf
.needipsec 
&& (m
->m_pkthdr
.csum_flags 
& CSUM_DELAY_IPV6_DATA
)) 
 805                 in6_delayed_cksum_offset(m
, 0, optlen
, nxt0
); 
 808         if (!TAILQ_EMPTY(&ipv6_filters
)) { 
 809                 struct ipfilter 
*filter
; 
 810                 int seen 
= (inject_filter_ref 
== NULL
); 
 813                 if (im6o 
!= NULL 
&& IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
)) { 
 814                         ippo
->ippo_flags 
|= IPPOF_MCAST_OPTS
; 
 816                         ippo
->ippo_mcast_ifnet 
= im6o
->im6o_multicast_ifp
; 
 817                         ippo
->ippo_mcast_ttl 
= im6o
->im6o_multicast_hlim
; 
 818                         ippo
->ippo_mcast_loop 
= im6o
->im6o_multicast_loop
; 
 822                 /* Hack: embed the scope_id in the destination */ 
 823                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6
->ip6_dst
) && 
 824                     (ip6
->ip6_dst
.s6_addr16
[1] == 0) && (ro 
!= NULL
)) { 
 826                         ip6
->ip6_dst
.s6_addr16
[1] = 
 827                             htons(ro
->ro_dst
.sin6_scope_id
); 
 831                 TAILQ_FOREACH(filter
, &ipv6_filters
, ipf_link
) { 
 833                          * Don't process packet twice if we've already seen it. 
 836                                 if ((struct ipfilter 
*)inject_filter_ref 
== 
 839                         } else if (filter
->ipf_filter
.ipf_output 
!= NULL
) { 
 842                                 result 
= filter
->ipf_filter
.ipf_output( 
 843                                     filter
->ipf_filter
.cookie
, 
 845                                 if (result 
== EJUSTRETURN
) { 
 858                 ip6 
= mtod(m
, struct ip6_hdr 
*); 
 859                 /* Hack: cleanup embedded scope_id if we put it there */ 
 861                         ip6
->ip6_dst
.s6_addr16
[1] = 0; 
 865         if (ip6obf
.needipsec
) { 
 869                  * pointers after IPsec headers are not valid any more. 
 870                  * other pointers need a great care too. 
 871                  * (IPsec routines should not mangle mbufs prior to AH/ESP) 
 873                 exthdrs
.ip6e_dest2 
= NULL
; 
 875                 if (exthdrs
.ip6e_rthdr 
!= NULL
) { 
 876                         rh 
= mtod(exthdrs
.ip6e_rthdr
, struct ip6_rthdr 
*); 
 877                         segleft_org 
= rh
->ip6r_segleft
; 
 878                         rh
->ip6r_segleft 
= 0; 
 885                 error 
= ipsec6_output_trans(&ipsec_state
, nexthdrp
, mprev
, 
 886                     sp
, flags
, &needipsectun
); 
 889                         /* mbuf is already reclaimed in ipsec6_output_trans. */ 
 899                                 printf("ip6_output (ipsec): error code %d\n", 
 903                                 /* don't show these error codes to the user */ 
 909                 if (exthdrs
.ip6e_rthdr 
!= NULL
) { 
 910                         /* ah6_output doesn't modify mbuf chain */ 
 911                         rh
->ip6r_segleft 
= segleft_org
; 
 917          * If there is a routing header, replace the destination address field 
 918          * with the first hop of the routing header. 
 920         if (exthdrs
.ip6e_rthdr 
!= NULL
) { 
 921                 struct ip6_rthdr0 
*rh0
; 
 922                 struct in6_addr 
*addr
; 
 923                 struct sockaddr_in6 sa
; 
 925                 rh 
= (struct ip6_rthdr 
*) 
 926                     (mtod(exthdrs
.ip6e_rthdr
, struct ip6_rthdr 
*)); 
 927                 switch (rh
->ip6r_type
) { 
 928                 case IPV6_RTHDR_TYPE_0
: 
 929                         rh0 
= (struct ip6_rthdr0 
*)rh
; 
 930                         addr 
= (struct in6_addr 
*)(void *)(rh0 
+ 1); 
 933                          * construct a sockaddr_in6 form of 
 936                          * XXX: we may not have enough 
 937                          * information about its scope zone; 
 938                          * there is no standard API to pass 
 939                          * the information from the 
 942                         bzero(&sa
, sizeof (sa
)); 
 943                         sa
.sin6_family 
= AF_INET6
; 
 944                         sa
.sin6_len 
= sizeof (sa
); 
 945                         sa
.sin6_addr 
= addr
[0]; 
 946                         if ((error 
= sa6_embedscope(&sa
, 
 947                             ip6_use_defzone
)) != 0) { 
 950                         ip6
->ip6_dst 
= sa
.sin6_addr
; 
 951                         bcopy(&addr
[1], &addr
[0], sizeof (struct in6_addr
) * 
 952                             (rh0
->ip6r0_segleft 
- 1)); 
 953                         addr
[rh0
->ip6r0_segleft 
- 1] = finaldst
; 
 955                         in6_clearscope(addr 
+ rh0
->ip6r0_segleft 
- 1); 
 957                 default:        /* is it possible? */ 
 963         /* Source address validation */ 
 964         if (IN6_IS_ADDR_UNSPECIFIED(&ip6
->ip6_src
) && 
 965             !(flags 
& IPV6_UNSPECSRC
)) { 
 967                 ip6stat
.ip6s_badscope
++; 
 970         if (IN6_IS_ADDR_MULTICAST(&ip6
->ip6_src
)) { 
 972                 ip6stat
.ip6s_badscope
++; 
 976         ip6stat
.ip6s_localout
++; 
 983                 bzero((caddr_t
)ro
, sizeof (*ro
)); 
 986         if (opt 
!= NULL 
&& opt
->ip6po_rthdr
) 
 987                 ro 
= &opt
->ip6po_route
; 
 988         dst 
= SIN6(&ro
->ro_dst
); 
 990         if (ro
->ro_rt 
!= NULL
) 
 991                 RT_LOCK_ASSERT_NOTHELD(ro
->ro_rt
); 
 993          * if specified, try to fill in the traffic class field. 
 994          * do not override if a non-zero value is already set. 
 995          * we check the diffserv field and the ecn field separately. 
 997         if (opt 
!= NULL 
&& opt
->ip6po_tclass 
>= 0) { 
1000                 if ((ip6
->ip6_flow 
& htonl(0xfc << 20)) == 0) 
1002                 if ((ip6
->ip6_flow 
& htonl(0x03 << 20)) == 0) 
1006                             htonl((opt
->ip6po_tclass 
& mask
) << 20); 
1010         /* fill in or override the hop limit field, if necessary. */ 
1011         if (opt 
&& opt
->ip6po_hlim 
!= -1) { 
1012                 ip6
->ip6_hlim 
= opt
->ip6po_hlim 
& 0xff; 
1013         } else if (IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
)) { 
1016                         ip6
->ip6_hlim 
= im6o
->im6o_multicast_hlim
; 
1019                         ip6
->ip6_hlim 
= ip6_defmcasthlim
; 
1024          * If there is a cached route, check that it is to the same 
1025          * destination and is still up. If not, free it and try again. 
1026          * Test rt_flags without holding rt_lock for performance reasons; 
1027          * if the route is down it will hopefully be caught by the layer 
1028          * below (since it uses this route as a hint) or during the 
1031         if (ROUTE_UNUSABLE(ro
) || dst
->sin6_family 
!= AF_INET6 
|| 
1032             !IN6_ARE_ADDR_EQUAL(&dst
->sin6_addr
, &ip6
->ip6_dst
)) 
1035         if (ro
->ro_rt 
== NULL
) { 
1036                 bzero(dst
, sizeof (*dst
)); 
1037                 dst
->sin6_family 
= AF_INET6
; 
1038                 dst
->sin6_len 
= sizeof (struct sockaddr_in6
); 
1039                 dst
->sin6_addr 
= ip6
->ip6_dst
; 
1042         if (ip6obf
.needipsec 
&& needipsectun
) { 
1044                 struct ifnet 
*trace_ifp 
= (ifpp_save 
!= NULL
) ? (*ifpp_save
) : NULL
; 
1045 #endif /* CONFIG_DTRACE */ 
1047                  * All the extension headers will become inaccessible 
1048                  * (since they can be encrypted). 
1049                  * Don't panic, we need no more updates to extension headers 
1050                  * on inner IPv6 packet (since they are now encapsulated). 
1052                  * IPv6 [ESP|AH] IPv6 [extension headers] payload 
1054                 bzero(&exthdrs
, sizeof (exthdrs
)); 
1055                 exthdrs
.ip6e_ip6 
= m
; 
1058                 route_copyout(&ipsec_state
.ro
, (struct route 
*)ro
, 
1059                     sizeof (ipsec_state
.ro
)); 
1060                 ipsec_state
.dst 
= SA(dst
); 
1062                 /* So that we can see packets inside the tunnel */ 
1063                 DTRACE_IP6(send
, struct mbuf 
*, m
, struct inpcb 
*, NULL
, 
1064                     struct ip6_hdr 
*, ip6
, struct ifnet 
*, trace_ifp
, 
1065                     struct ip 
*, NULL
, struct ip6_hdr 
*, ip6
); 
1067                 error 
= ipsec6_output_tunnel(&ipsec_state
, sp
, flags
); 
1068                 /* tunneled in IPv4? packet is gone */ 
1069                 if (ipsec_state
.tunneled 
== 4) { 
1074                 ipsec_saved_route 
= ro
; 
1075                 ro 
= (struct route_in6 
*)&ipsec_state
.ro
; 
1076                 dst 
= SIN6(ipsec_state
.dst
); 
1078                         /* mbuf is already reclaimed in ipsec6_output_tunnel. */ 
1088                                 printf("ip6_output (ipsec): error code %d\n", 
1092                                 /* don't show these error codes to the user */ 
1099                  * The packet has been encapsulated so the ifscope 
1100                  * is no longer valid since it does not apply to the 
1101                  * outer address: ignore the ifscope. 
1103                 if (flags 
& IPV6_OUTARGS
) { 
1104                         ip6oa
->ip6oa_boundif 
= IFSCOPE_NONE
; 
1105                         ip6oa
->ip6oa_flags 
&= ~IP6OAF_BOUND_IF
; 
1107                 if (opt 
!= NULL 
&& opt
->ip6po_pktinfo 
!= NULL
) { 
1108                         if (opt
->ip6po_pktinfo
->ipi6_ifindex 
!= IFSCOPE_NONE
) 
1109                                 opt
->ip6po_pktinfo
->ipi6_ifindex 
= IFSCOPE_NONE
; 
1111                 exthdrs
.ip6e_ip6 
= m
; 
1116          * ifp should only be filled in for dummy net packets which will jump 
1117          * to check_with_pf label. 
1120                 VERIFY(ip6obf
.route_selected
); 
1123         /* adjust pointer */ 
1124         ip6 
= mtod(m
, struct ip6_hdr 
*); 
1126         if (ip6obf
.select_srcif
) { 
1127                 bzero(&src_sa
, sizeof (src_sa
)); 
1128                 src_sa
.sin6_family 
= AF_INET6
; 
1129                 src_sa
.sin6_len 
= sizeof (src_sa
); 
1130                 src_sa
.sin6_addr 
= ip6
->ip6_src
; 
1132         bzero(&dst_sa
, sizeof (dst_sa
)); 
1133         dst_sa
.sin6_family 
= AF_INET6
; 
1134         dst_sa
.sin6_len 
= sizeof (dst_sa
); 
1135         dst_sa
.sin6_addr 
= ip6
->ip6_dst
; 
1138          * Only call in6_selectroute() on first iteration to avoid taking 
1139          * multiple references on ifp and rt. 
1141          * in6_selectroute() might return an ifp with its reference held 
1142          * even in the error case, so make sure to release its reference. 
1143          * ip6oa may be NULL if IPV6_OUTARGS isn't set. 
1145         if (!ip6obf
.route_selected
) { 
1146                 error 
= in6_selectroute( ip6obf
.select_srcif 
? &src_sa 
: NULL
, 
1147                     &dst_sa
, opt
, im6o
, &src_ia
, ro
, &ifp
, &rt
, 0, ip6oa
); 
1152                                 ip6stat
.ip6s_noroute
++; 
1156                                 break; /* XXX statistics? */ 
1159                                 in6_ifstat_inc(ifp
, ifs6_out_discard
); 
1160                         /* ifp (if non-NULL) will be released at the end */ 
1163                 ip6obf
.route_selected 
= TRUE
; 
1167                  * If in6_selectroute() does not return a route entry, 
1168                  * dst may not have been updated. 
1170                 *dst 
= dst_sa
;  /* XXX */ 
1174         /* Catch-all to check if the interface is allowed */ 
1175         if (!necp_packet_is_allowed_over_interface(m
, ifp
)) { 
1176                 error 
= EHOSTUNREACH
; 
1182          * then rt (for unicast) and ifp must be non-NULL valid values. 
1184         if (!(flags 
& IPV6_FORWARDING
)) { 
1185                 in6_ifstat_inc_na(ifp
, ifs6_out_request
); 
1190                         ia 
= (struct in6_ifaddr 
*)(rt
->rt_ifa
); 
1192                                 IFA_ADDREF(&ia
->ia_ifa
); 
1199          * The outgoing interface must be in the zone of source and 
1200          * destination addresses (except local/loopback).  We should 
1201          * use ia_ifp to support the case of sending packets to an 
1202          * address of our own. 
1204         if (ia 
!= NULL 
&& ia
->ia_ifp
) { 
1205                 ifnet_reference(ia
->ia_ifp
);    /* for origifp */ 
1206                 if (origifp 
!= NULL
) 
1207                         ifnet_release(origifp
); 
1208                 origifp 
= ia
->ia_ifp
; 
1211                         ifnet_reference(ifp
);   /* for origifp */ 
1212                 if (origifp 
!= NULL
) 
1213                         ifnet_release(origifp
); 
1217         /* skip scope enforcements for local/loopback route */ 
1218         if (rt 
== NULL 
|| !(rt
->rt_ifp
->if_flags 
& IFF_LOOPBACK
)) { 
1219                 struct in6_addr src0
, dst0
; 
1222                 src0 
= ip6
->ip6_src
; 
1223                 if (in6_setscope(&src0
, origifp
, &zone
)) 
1225                 bzero(&src_sa
, sizeof (src_sa
)); 
1226                 src_sa
.sin6_family 
= AF_INET6
; 
1227                 src_sa
.sin6_len 
= sizeof (src_sa
); 
1228                 src_sa
.sin6_addr 
= ip6
->ip6_src
; 
1229                 if ((sa6_recoverscope(&src_sa
, TRUE
) || 
1230                     zone 
!= src_sa
.sin6_scope_id
)) 
1233                 dst0 
= ip6
->ip6_dst
; 
1234                 if ((in6_setscope(&dst0
, origifp
, &zone
))) 
1236                 /* re-initialize to be sure */ 
1237                 bzero(&dst_sa
, sizeof (dst_sa
)); 
1238                 dst_sa
.sin6_family 
= AF_INET6
; 
1239                 dst_sa
.sin6_len 
= sizeof (dst_sa
); 
1240                 dst_sa
.sin6_addr 
= ip6
->ip6_dst
; 
1241                 if ((sa6_recoverscope(&dst_sa
, TRUE
) || 
1242                     zone 
!= dst_sa
.sin6_scope_id
)) 
1245                 /* scope check is done. */ 
1249                 ip6stat
.ip6s_badscope
++; 
1250                 in6_ifstat_inc(origifp
, ifs6_out_discard
); 
1252                         error 
= EHOSTUNREACH
; /* XXX */ 
1257         if (rt 
!= NULL 
&& !IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
)) { 
1258                 if (opt 
!= NULL 
&& opt
->ip6po_nextroute
.ro_rt
) { 
1260                          * The nexthop is explicitly specified by the 
1261                          * application.  We assume the next hop is an IPv6 
1264                         dst 
= SIN6(opt
->ip6po_nexthop
); 
1265                 } else if ((rt
->rt_flags 
& RTF_GATEWAY
)) { 
1266                         dst 
= SIN6(rt
->rt_gateway
); 
1269                  * For packets destined to local/loopback, record the 
1270                  * source the source interface (which owns the source 
1271                  * address), as well as the output interface.  This is 
1272                  * needed to reconstruct the embedded zone for the 
1273                  * link-local address case in ip6_input(). 
1275                 if (ia 
!= NULL 
&& (ifp
->if_flags 
& IFF_LOOPBACK
)) { 
1279                                 srcidx 
= src_ia
->ia_ifp
->if_index
; 
1280                         else if (ro
->ro_srcia 
!= NULL
) 
1281                                 srcidx 
= ro
->ro_srcia
->ifa_ifp
->if_index
; 
1285                         ip6_setsrcifaddr_info(m
, srcidx
, NULL
); 
1286                         ip6_setdstifaddr_info(m
, 0, ia
); 
1290         if (!IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
)) { 
1291                 m
->m_flags 
&= ~(M_BCAST 
| M_MCAST
); /* just in case */ 
1293                 struct  in6_multi 
*in6m
; 
1295                 m
->m_flags 
= (m
->m_flags 
& ~M_BCAST
) | M_MCAST
; 
1296                 in6_ifstat_inc_na(ifp
, ifs6_out_mcast
); 
1299                  * Confirm that the outgoing interface supports multicast. 
1301                 if (!(ifp
->if_flags 
& IFF_MULTICAST
)) { 
1302                         ip6stat
.ip6s_noroute
++; 
1303                         in6_ifstat_inc(ifp
, ifs6_out_discard
); 
1304                         error 
= ENETUNREACH
; 
1307                 in6_multihead_lock_shared(); 
1308                 IN6_LOOKUP_MULTI(&ip6
->ip6_dst
, ifp
, in6m
); 
1309                 in6_multihead_lock_done(); 
1313                     (im6o 
== NULL 
|| im6o
->im6o_multicast_loop
)) { 
1317                          * If we belong to the destination multicast group 
1318                          * on the outgoing interface, and the caller did not 
1319                          * forbid loopback, loop back a copy. 
1321                         ip6_mloopback(NULL
, ifp
, m
, dst
, optlen
, nxt0
); 
1322                 } else if (im6o 
!= NULL
)  
1327                  * Multicasts with a hoplimit of zero may be looped back, 
1328                  * above, but must not be transmitted on a network. 
1329                  * Also, multicasts addressed to the loopback interface 
1330                  * are not sent -- the above call to ip6_mloopback() will 
1331                  * loop back a copy if this host actually belongs to the 
1332                  * destination group on the loopback interface. 
1334                 if (ip6
->ip6_hlim 
== 0 || (ifp
->if_flags 
& IFF_LOOPBACK
) || 
1335                     IN6_IS_ADDR_MC_INTFACELOCAL(&ip6
->ip6_dst
)) { 
1336                         /* remove m from the packetchain and continue looping */ 
1345          * Fill the outgoing inteface to tell the upper layer 
1346          * to increment per-interface statistics. 
1348         if (ifpp 
!= NULL 
&& *ifpp 
== NULL
) { 
1349                 ifnet_reference(ifp
);   /* for caller */ 
1353         /* Determine path MTU. */ 
1354         if ((error 
= ip6_getpmtu(ro_pmtu
, ro
, ifp
, &finaldst
, &mtu
, 
1359          * The caller of this function may specify to use the minimum MTU 
1361          * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU 
1362          * setting.  The logic is a bit complicated; by default, unicast 
1363          * packets will follow path MTU while multicast packets will be sent at 
1364          * the minimum MTU.  If IP6PO_MINMTU_ALL is specified, all packets 
1365          * including unicast ones will be sent at the minimum MTU.  Multicast 
1366          * packets will always be sent at the minimum MTU unless 
1367          * IP6PO_MINMTU_DISABLE is explicitly specified. 
1368          * See RFC 3542 for more details. 
1370         if (mtu 
> IPV6_MMTU
) { 
1371                 if ((flags 
& IPV6_MINMTU
)) { 
1373                 } else if (opt 
&& opt
->ip6po_minmtu 
== IP6PO_MINMTU_ALL
) { 
1375                 } else if (IN6_IS_ADDR_MULTICAST(&ip6
->ip6_dst
) && 
1377                     opt
->ip6po_minmtu 
!= IP6PO_MINMTU_DISABLE
)) { 
1383          * clear embedded scope identifiers if necessary. 
1384          * in6_clearscope will touch the addresses only when necessary. 
1386         in6_clearscope(&ip6
->ip6_src
); 
1387         in6_clearscope(&ip6
->ip6_dst
); 
1391          * Check with the firewall... 
1393         if (ip6_fw_enable 
&& ip6_fw_chk_ptr
) { 
1395                 m
->m_pkthdr
.rcvif 
= NULL
;       /* XXX */ 
1396                 /* If ipfw says divert, we have to just drop packet */ 
1397                 if (ip6_fw_chk_ptr(&ip6
, ifp
, &port
, &m
) || m 
== NULL
) { 
1411          * If the outgoing packet contains a hop-by-hop options header, 
1412          * it must be examined and processed even by the source node. 
1413          * (RFC 2460, section 4.) 
1415         if (exthdrs
.ip6e_hbh 
!= NULL
) { 
1416                 struct ip6_hbh 
*hbh 
= mtod(exthdrs
.ip6e_hbh
, struct ip6_hbh 
*); 
1417                 u_int32_t dummy
; /* XXX unused */ 
1418                 uint32_t oplen 
= 0; /* for ip6_process_hopopts() */ 
1420                 if ((hbh
->ip6h_len 
+ 1) << 3 > exthdrs
.ip6e_hbh
->m_len
) 
1421                         panic("ip6e_hbh is not continuous"); 
1424                  * XXX: If we have to send an ICMPv6 error to the sender, 
1425                  * we need the M_LOOP flag since icmp6_error() expects 
1426                  * the IPv6 and the hop-by-hop options header are 
1427                  * continuous unless the flag is set. 
1429                 m
->m_flags 
|= M_LOOP
; 
1430                 m
->m_pkthdr
.rcvif 
= ifp
; 
1431                 if (ip6_process_hopopts(m
, (u_int8_t 
*)(hbh 
+ 1), 
1432                     ((hbh
->ip6h_len 
+ 1) << 3) - sizeof (struct ip6_hbh
), 
1433                     &dummy
, &oplen
) < 0) { 
1435                          * m was already freed at this point. Set to NULL so it 
1436                          * is not re-freed at end of ip6_output_list. 
1439                         error 
= EINVAL
; /* better error? */ 
1442                 m
->m_flags 
&= ~M_LOOP
; /* XXX */ 
1443                 m
->m_pkthdr
.rcvif 
= NULL
; 
1448 #endif /* DUMMYNET */ 
1450         if (PF_IS_ENABLED
) { 
1454                  * TODO: Need to save opt->ip6po_flags for reinjection 
1459                 args
.fwa_oflags 
= flags
; 
1460                 if (flags 
& IPV6_OUTARGS
) 
1461                         args
.fwa_ip6oa 
= ip6oa
; 
1463                 args
.fwa_dst6 
= dst
; 
1464                 args
.fwa_ro6_pmtu 
= ro_pmtu
; 
1465                 args
.fwa_origifp 
= origifp
; 
1467                 args
.fwa_alwaysfrag 
= alwaysfrag
; 
1468                 args
.fwa_unfragpartlen 
= unfragpartlen
; 
1469                 args
.fwa_exthdrs 
= &exthdrs
; 
1470                 /* Invoke outbound packet filter */ 
1471                 error 
= pf_af_hook(ifp
, NULL
, &m
, AF_INET6
, FALSE
, &args
); 
1472 #else /* !DUMMYNET */ 
1473                 error 
= pf_af_hook(ifp
, NULL
, &m
, AF_INET6
, FALSE
, NULL
); 
1474 #endif /* !DUMMYNET */ 
1476                 if (error 
!= 0 || m 
== NULL
) { 
1478                                 panic("%s: unexpected packet %p\n", 
1482                         /* m was already freed by callee and is now NULL.  */ 
1485                 ip6 
= mtod(m
, struct ip6_hdr 
*); 
1490         /* clean ipsec history before fragmentation */ 
1495          * Determine whether fragmentation is necessary. If so, m is passed 
1496          * back as a chain of packets and original mbuf is freed. Otherwise, m 
1499         error 
= ip6_fragment_packet(&m
, opt
, 
1500             &exthdrs
, ifp
, mtu
, alwaysfrag
, unfragpartlen
, ro_pmtu
, nxt0
, 
1507  * The evaluateloop label is where we decide whether to continue looping over 
1508  * packets or call into nd code to send. 
1513          * m may be NULL when we jump to the evaluateloop label from PF or 
1514          * other code that can drop packets. 
1518                  * If we already have a chain to send, tack m onto the end. 
1519                  * Otherwise make m the start and end of the to-be-sent chain. 
1521                 if (sendchain 
!= NULL
) { 
1522                         sendchain_last
->m_nextpkt 
= m
; 
1527                 /* Fragmentation may mean m is a chain. Find the last packet. */ 
1528                 while (m
->m_nextpkt
) 
1534         /* Fill in next m from inputchain as appropriate. */ 
1537                 /* Isolate m from rest of input chain. */ 
1538                 inputchain 
= m
->m_nextpkt
; 
1539                 m
->m_nextpkt 
= NULL
; 
1542                  * Clear exthdrs and ipsec_state so stale contents are not 
1543                  * reused. Note this also clears the exthdrs.merged flag. 
1545                 bzero(&exthdrs
, sizeof(exthdrs
)); 
1546                 bzero(&ipsec_state
, sizeof(ipsec_state
)); 
1548                 /* Continue looping. */ 
1553          * If we get here, there's no more mbufs in inputchain, so send the 
1554          * sendchain if there is one. 
1557                 error 
= nd6_output_list(ifp
, origifp
, sendchain
, dst
, 
1560                  * Fall through to done label even in error case because 
1561                  * nd6_output_list frees packetchain in both success and 
1567         if (ifpp_save 
!= NULL 
&& *ifpp_save 
!= NULL
) { 
1568                 ifnet_release(*ifpp_save
); 
1571         ROUTE_RELEASE(&ip6route
); 
1573         ROUTE_RELEASE(&ipsec_state
.ro
); 
1575                 key_freesp(sp
, KEY_SADB_UNLOCKED
); 
1578         ROUTE_RELEASE(&necp_route
); 
1581         ROUTE_RELEASE(&saved_route
); 
1582         ROUTE_RELEASE(&saved_ro_pmtu
); 
1583 #endif /* DUMMYNET */ 
1586                 IFA_REMREF(&ia
->ia_ifa
); 
1588                 IFA_REMREF(&src_ia
->ia_ifa
); 
1591         if (origifp 
!= NULL
) 
1592                 ifnet_release(origifp
); 
1593         if (ip6_output_measure
) { 
1594                 net_perf_measure_time(&net_perf
, &start_tv
, packets_processed
); 
1595                 net_perf_histogram(&net_perf
, packets_processed
); 
1600         if (exthdrs
.ip6e_hbh 
!= NULL
) { 
1602                         panic("Double free of ip6e_hbh"); 
1603                 m_freem(exthdrs
.ip6e_hbh
); 
1605         if (exthdrs
.ip6e_dest1 
!= NULL
) { 
1607                         panic("Double free of ip6e_dest1"); 
1608                 m_freem(exthdrs
.ip6e_dest1
); 
1610         if (exthdrs
.ip6e_rthdr 
!= NULL
) { 
1612                         panic("Double free of ip6e_rthdr"); 
1613                 m_freem(exthdrs
.ip6e_rthdr
); 
1615         if (exthdrs
.ip6e_dest2 
!= NULL
) { 
1617                         panic("Double free of ip6e_dest2"); 
1618                 m_freem(exthdrs
.ip6e_dest2
); 
1622         if (inputchain 
!= NULL
) 
1623                 m_freem_list(inputchain
); 
1624         if (sendchain 
!= NULL
) 
1625                 m_freem_list(sendchain
); 
1636 #undef saved_ro_pmtu 
1640 /* ip6_fragment_packet 
1642  * The fragmentation logic is rather complex: 
1643  * 1: normal case (dontfrag == 0, alwaysfrag == 0) 
1644  * 1-a: send as is if tlen <= path mtu 
1645  * 1-b: fragment if tlen > path mtu 
1647  * 2: if user asks us not to fragment (dontfrag == 1) 
1648  * 2-a: send as is if tlen <= interface mtu 
1649  * 2-b: error if tlen > interface mtu 
1651  * 3: if we always need to attach fragment header (alwaysfrag == 1) 
1654  * 4: if dontfrag == 1 && alwaysfrag == 1 
1655  *      error, as we cannot handle this conflicting request 
1659 ip6_fragment_packet(struct mbuf 
**mptr
, struct ip6_pktopts 
*opt
, 
1660      struct ip6_exthdrs 
*exthdrsp
, struct ifnet 
*ifp
, uint32_t mtu
, 
1661      boolean_t alwaysfrag
, uint32_t unfragpartlen
, struct route_in6 
*ro_pmtu
, 
1662      int nxt0
, uint32_t optlen
) 
1664         VERIFY(NULL 
!= mptr
); 
1665         struct mbuf 
*m 
= *mptr
; 
1667         size_t tlen 
= m
->m_pkthdr
.len
; 
1668         boolean_t dontfrag 
= (opt 
!= NULL 
&& (opt
->ip6po_flags 
& IP6PO_DONTFRAG
)); 
1670         if (dontfrag 
&& alwaysfrag
) {   /* case 4 */ 
1671                 /* conflicting request - can't transmit */ 
1675         /* Access without acquiring nd_ifinfo lock for performance */ 
1676         if (dontfrag 
&& tlen 
> IN6_LINKMTU(ifp
)) {      /* case 2-b */ 
1678                  * Even if the DONTFRAG option is specified, we cannot send the 
1679                  * packet when the data length is larger than the MTU of the 
1680                  * outgoing interface. 
1681                  * Notify the error by sending IPV6_PATHMTU ancillary data as 
1682                  * well as returning an error code (the latter is not described 
1686                 struct ip6ctlparam ip6cp
; 
1688                 mtu32 
= (u_int32_t
)mtu
; 
1689                 bzero(&ip6cp
, sizeof (ip6cp
)); 
1690                 ip6cp
.ip6c_cmdarg 
= (void *)&mtu32
; 
1691                 pfctlinput2(PRC_MSGSIZE
, SA(&ro_pmtu
->ro_dst
), (void *)&ip6cp
); 
1696          * transmit packet without fragmentation 
1698         if (dontfrag 
|| (!alwaysfrag 
&&         /* case 1-a and 2-a */ 
1699             (tlen 
<= mtu 
|| TSO_IPV6_OK(ifp
, m
) || 
1700             (ifp
->if_hwassist 
& CSUM_FRAGMENT_IPV6
)))) { 
1702                  * mppn not updated in this case because no new chain is formed 
1705                 ip6_output_checksum(ifp
, mtu
, m
, nxt0
, tlen
, optlen
); 
1708                  * time to fragment - cases 1-b and 3 are handled inside 
1709                  * ip6_do_fragmentation(). 
1710                  * mppn is passed down to be updated to point at fragment chain. 
1712                 error 
= ip6_do_fragmentation(mptr
, optlen
, ifp
, 
1713                     unfragpartlen
, mtod(m
, struct ip6_hdr 
*), exthdrsp
, mtu
, nxt0
); 
1720  * ip6_do_fragmentation() is called by ip6_fragment_packet() after determining 
1721  * the packet needs to be fragmented. on success, morig is freed and a chain 
1722  * of fragments is linked into the packet chain where morig existed. Otherwise, 
1723  * an errno is returned. 
1726 ip6_do_fragmentation(struct mbuf 
**mptr
, uint32_t optlen
, struct ifnet 
*ifp
, 
1727     uint32_t unfragpartlen
, struct ip6_hdr 
*ip6
, struct ip6_exthdrs 
*exthdrsp
, 
1728     uint32_t mtu
, int nxt0
) 
1730         VERIFY(NULL 
!= mptr
); 
1733         struct mbuf 
*morig 
= *mptr
; 
1734         struct mbuf 
*first_mbufp 
= NULL
; 
1735         struct mbuf 
*last_mbufp 
= NULL
; 
1737         size_t tlen 
= morig
->m_pkthdr
.len
; 
1740          * try to fragment the packet.  case 1-b and 3 
1742         if ((morig
->m_pkthdr
.csum_flags 
& CSUM_TSO_IPV6
)) { 
1743                 /* TSO and fragment aren't compatible */ 
1744                 in6_ifstat_inc(ifp
, ifs6_out_fragfail
); 
1746         } else if (mtu 
< IPV6_MMTU
) { 
1747                 /* path MTU cannot be less than IPV6_MMTU */ 
1748                 in6_ifstat_inc(ifp
, ifs6_out_fragfail
); 
1750         } else if (ip6
->ip6_plen 
== 0) { 
1751                 /* jumbo payload cannot be fragmented */ 
1752                 in6_ifstat_inc(ifp
, ifs6_out_fragfail
); 
1755                 size_t hlen
, len
, off
; 
1756                 struct mbuf 
**mnext 
= NULL
; 
1757                 struct ip6_frag 
*ip6f
; 
1758                 u_int32_t id 
= htonl(ip6_randomid()); 
1762                  * Too large for the destination or interface; 
1763                  * fragment if possible. 
1764                  * Must be able to put at least 8 bytes per fragment. 
1766                 hlen 
= unfragpartlen
; 
1767                 if (mtu 
> IPV6_MAXPACKET
) 
1768                         mtu 
= IPV6_MAXPACKET
; 
1770                 len 
= (mtu 
- hlen 
- sizeof (struct ip6_frag
)) & ~7; 
1772                         in6_ifstat_inc(ifp
, ifs6_out_fragfail
); 
1777                  * Change the next header field of the last header in the 
1778                  * unfragmentable part. 
1780                 if (exthdrsp
->ip6e_rthdr 
!= NULL
) { 
1781                         nextproto 
= *mtod(exthdrsp
->ip6e_rthdr
, u_char 
*); 
1782                         *mtod(exthdrsp
->ip6e_rthdr
, u_char 
*) = IPPROTO_FRAGMENT
; 
1783                 } else if (exthdrsp
->ip6e_dest1 
!= NULL
) { 
1784                         nextproto 
= *mtod(exthdrsp
->ip6e_dest1
, u_char 
*); 
1785                         *mtod(exthdrsp
->ip6e_dest1
, u_char 
*) = IPPROTO_FRAGMENT
; 
1786                 } else if (exthdrsp
->ip6e_hbh 
!= NULL
) { 
1787                         nextproto 
= *mtod(exthdrsp
->ip6e_hbh
, u_char 
*); 
1788                         *mtod(exthdrsp
->ip6e_hbh
, u_char 
*) = IPPROTO_FRAGMENT
; 
1790                         nextproto 
= ip6
->ip6_nxt
; 
1791                         ip6
->ip6_nxt 
= IPPROTO_FRAGMENT
; 
1794                 if (morig
->m_pkthdr
.csum_flags 
& CSUM_DELAY_IPV6_DATA
) 
1795                         in6_delayed_cksum_offset(morig
, 0, optlen
, nxt0
); 
1798                  * Loop through length of segment after first fragment, 
1799                  * make new header and copy data of each part and link onto 
1802                 for (off 
= hlen
; off 
< tlen
; off 
+= len
) { 
1803                         struct ip6_hdr 
*new_mhip6
; 
1805                         struct mbuf 
*m_frgpart
; 
1807                         MGETHDR(new_m
, M_DONTWAIT
, MT_HEADER
);  /* MAC-OK */ 
1808                         if (new_m 
== NULL
) { 
1810                                 ip6stat
.ip6s_odropped
++; 
1813                         new_m
->m_pkthdr
.rcvif 
= NULL
; 
1814                         new_m
->m_flags 
= morig
->m_flags 
& M_COPYFLAGS
; 
1816                         if (first_mbufp 
!= NULL
) { 
1817                                 /* Every pass through loop but first */ 
1821                                 /* This is the first element of the fragment chain */ 
1822                                 first_mbufp 
= new_m
; 
1825                         mnext 
= &new_m
->m_nextpkt
; 
1827                         new_m
->m_data 
+= max_linkhdr
; 
1828                         new_mhip6 
= mtod(new_m
, struct ip6_hdr 
*); 
1830                         new_m
->m_len 
= sizeof (*new_mhip6
); 
1832                         error 
= ip6_insertfraghdr(morig
, new_m
, hlen
, &ip6f
); 
1834                                 ip6stat
.ip6s_odropped
++; 
1838                         ip6f
->ip6f_offlg 
= htons((u_short
)((off 
- hlen
) & ~7)); 
1839                         if (off 
+ len 
>= tlen
) 
1842                                 ip6f
->ip6f_offlg 
|= IP6F_MORE_FRAG
; 
1843                         new_mhip6
->ip6_plen 
= htons((u_short
)(len 
+ hlen 
+ 
1844                             sizeof (*ip6f
) - sizeof (struct ip6_hdr
))); 
1846                         if ((m_frgpart 
= m_copy(morig
, off
, len
)) == NULL
) { 
1848                                 ip6stat
.ip6s_odropped
++; 
1851                         m_cat(new_m
, m_frgpart
); 
1852                         new_m
->m_pkthdr
.len 
= len 
+ hlen 
+ sizeof (*ip6f
); 
1853                         new_m
->m_pkthdr
.rcvif 
= NULL
; 
1855                         M_COPY_CLASSIFIER(new_m
, morig
); 
1856                         M_COPY_PFTAG(new_m
, morig
); 
1860                         mac_create_fragment(morig
, new_m
); 
1861 #endif /* CONFIG_MACF_NET */ 
1864                         ip6f
->ip6f_reserved 
= 0; 
1865                         ip6f
->ip6f_ident 
= id
; 
1866                         ip6f
->ip6f_nxt 
= nextproto
; 
1867                         ip6stat
.ip6s_ofragments
++; 
1868                         in6_ifstat_inc(ifp
, ifs6_out_fragcreat
); 
1872                         /* free all the fragments created */ 
1873                         if (first_mbufp 
!= NULL
) { 
1874                                 m_freem_list(first_mbufp
); 
1879                         /* successful fragmenting */ 
1881                         *mptr 
= first_mbufp
; 
1882                         last_mbufp
->m_nextpkt 
= NULL
; 
1883                         ip6stat
.ip6s_fragmented
++; 
1884                         in6_ifstat_inc(ifp
, ifs6_out_fragok
); 
1891 ip6_copyexthdr(struct mbuf 
**mp
, caddr_t hdr
, int hlen
) 
1895         if (hlen 
> MCLBYTES
) 
1896                 return (ENOBUFS
); /* XXX */ 
1898         MGET(m
, M_DONTWAIT
, MT_DATA
); 
1903                 MCLGET(m
, M_DONTWAIT
); 
1904                 if (!(m
->m_flags 
& M_EXT
)) { 
1911                 bcopy(hdr
, mtod(m
, caddr_t
), hlen
); 
1918 ip6_out_cksum_stats(int proto
, u_int32_t len
) 
1922                 tcp_out6_cksum_stats(len
); 
1925                 udp_out6_cksum_stats(len
); 
1928                 /* keep only TCP or UDP stats for now */ 
1934  * Process a delayed payload checksum calculation (outbound path.) 
1936  * hoff is the number of bytes beyond the mbuf data pointer which 
1937  * points to the IPv6 header.  optlen is the number of bytes, if any, 
1938  * between the end of IPv6 header and the beginning of the ULP payload 
1939  * header, which represents the extension headers.  If optlen is less 
1940  * than zero, this routine will bail when it detects extension headers. 
1942  * Returns a bitmask representing all the work done in software. 
1945 in6_finalize_cksum(struct mbuf 
*m
, uint32_t hoff
, int32_t optlen
, 
1946     int32_t nxt0
, uint32_t csum_flags
) 
1948         unsigned char buf
[sizeof (struct ip6_hdr
)] __attribute__((aligned(8))); 
1949         struct ip6_hdr 
*ip6
; 
1950         uint32_t offset
, mlen
, hlen
, olen
, sw_csum
; 
1951         uint16_t csum
, ulpoff
, plen
; 
1954         _CASSERT(sizeof (csum
) == sizeof (uint16_t)); 
1955         VERIFY(m
->m_flags 
& M_PKTHDR
); 
1957         sw_csum 
= (csum_flags 
& m
->m_pkthdr
.csum_flags
); 
1959         if ((sw_csum 
&= CSUM_DELAY_IPV6_DATA
) == 0) 
1962         mlen 
= m
->m_pkthdr
.len
;                         /* total mbuf len */ 
1963         hlen 
= sizeof (*ip6
);                           /* IPv6 header len */ 
1965         /* sanity check (need at least IPv6 header) */ 
1966         if (mlen 
< (hoff 
+ hlen
)) { 
1967                 panic("%s: mbuf %p pkt len (%u) < hoff+ip6_hdr " 
1968                     "(%u+%u)\n", __func__
, m
, mlen
, hoff
, hlen
); 
1973          * In case the IPv6 header is not contiguous, or not 32-bit 
1974          * aligned, copy it to a local buffer. 
1976         if ((hoff 
+ hlen
) > m
->m_len 
|| 
1977             !IP6_HDR_ALIGNED_P(mtod(m
, caddr_t
) + hoff
)) { 
1978                 m_copydata(m
, hoff
, hlen
, (caddr_t
)buf
); 
1979                 ip6 
= (struct ip6_hdr 
*)(void *)buf
; 
1981                 ip6 
= (struct ip6_hdr 
*)(void *)(m
->m_data 
+ hoff
); 
1985         plen 
= ntohs(ip6
->ip6_plen
); 
1986         if (plen 
!= (mlen 
- (hoff 
+ hlen
))) { 
1987                 plen 
= OSSwapInt16(plen
); 
1988                 if (plen 
!= (mlen 
- (hoff 
+ hlen
))) { 
1989                         /* Don't complain for jumbograms */ 
1990                         if (plen 
!= 0 || nxt 
!= IPPROTO_HOPOPTS
) { 
1991                                 printf("%s: mbuf 0x%llx proto %d IPv6 " 
1992                                     "plen %d (%x) [swapped %d (%x)] doesn't " 
1993                                     "match actual packet length; %d is used " 
1994                                     "instead\n", __func__
, 
1995                                     (uint64_t)VM_KERNEL_ADDRPERM(m
), nxt
, 
1996                                     ip6
->ip6_plen
, ip6
->ip6_plen
, plen
, plen
, 
1997                                     (mlen 
- (hoff 
+ hlen
))); 
1999                         plen 
= mlen 
- (hoff 
+ hlen
); 
2004                 /* next header isn't TCP/UDP and we don't know optlen, bail */ 
2005                 if (nxt 
!= IPPROTO_TCP 
&& nxt 
!= IPPROTO_UDP
) { 
2011                 /* caller supplied the original transport number; use it */ 
2017         offset 
= hoff 
+ hlen 
+ olen
;                    /* ULP header */ 
2020         if (mlen 
< offset
) { 
2021                 panic("%s: mbuf %p pkt len (%u) < hoff+ip6_hdr+ext_hdr " 
2022                     "(%u+%u+%u)\n", __func__
, m
, mlen
, hoff
, hlen
, olen
); 
2027          * offset is added to the lower 16-bit value of csum_data, 
2028          * which is expected to contain the ULP offset; therefore 
2029          * CSUM_PARTIAL offset adjustment must be undone. 
2031         if ((m
->m_pkthdr
.csum_flags 
& (CSUM_PARTIAL
|CSUM_DATA_VALID
)) == 
2032             (CSUM_PARTIAL
|CSUM_DATA_VALID
)) { 
2034                  * Get back the original ULP offset (this will 
2035                  * undo the CSUM_PARTIAL logic in ip6_output.) 
2037                 m
->m_pkthdr
.csum_data 
= (m
->m_pkthdr
.csum_tx_stuff 
- 
2038                     m
->m_pkthdr
.csum_tx_start
); 
2041         ulpoff 
= (m
->m_pkthdr
.csum_data 
& 0xffff);      /* ULP csum offset */ 
2043         if (mlen 
< (ulpoff 
+ sizeof (csum
))) { 
2044                 panic("%s: mbuf %p pkt len (%u) proto %d invalid ULP " 
2045                     "cksum offset (%u) cksum flags 0x%x\n", __func__
, 
2046                     m
, mlen
, nxt
, ulpoff
, m
->m_pkthdr
.csum_flags
); 
2050         csum 
= inet6_cksum(m
, 0, offset
, plen 
- olen
); 
2053         ip6_out_cksum_stats(nxt
, plen 
- olen
); 
2055         /* RFC1122 4.1.3.4 */ 
2056         if (csum 
== 0 && (m
->m_pkthdr
.csum_flags 
& CSUM_UDPIPV6
)) 
2059         /* Insert the checksum in the ULP csum field */ 
2061         if ((offset 
+ sizeof (csum
)) > m
->m_len
) { 
2062                 m_copyback(m
, offset
, sizeof (csum
), &csum
); 
2063         } else if (IP6_HDR_ALIGNED_P(mtod(m
, char *) + hoff
)) { 
2064                 *(uint16_t *)(void *)(mtod(m
, char *) + offset
) = csum
; 
2066                 bcopy(&csum
, (mtod(m
, char *) + offset
), sizeof (csum
)); 
2068         m
->m_pkthdr
.csum_flags 
&= 
2069             ~(CSUM_DELAY_IPV6_DATA 
| CSUM_DATA_VALID 
| CSUM_PARTIAL
); 
2076  * Insert jumbo payload option. 
2079 ip6_insert_jumboopt(struct ip6_exthdrs 
*exthdrs
, u_int32_t plen
) 
2085 #define JUMBOOPTLEN     8       /* length of jumbo payload option and padding */ 
2088          * If there is no hop-by-hop options header, allocate new one. 
2089          * If there is one but it doesn't have enough space to store the 
2090          * jumbo payload option, allocate a cluster to store the whole options. 
2091          * Otherwise, use it to store the options. 
2093         if (exthdrs
->ip6e_hbh 
== NULL
) { 
2094                 MGET(mopt
, M_DONTWAIT
, MT_DATA
); 
2097                 mopt
->m_len 
= JUMBOOPTLEN
; 
2098                 optbuf 
= mtod(mopt
, u_char 
*); 
2099                 optbuf
[1] = 0;  /* = ((JUMBOOPTLEN) >> 3) - 1 */ 
2100                 exthdrs
->ip6e_hbh 
= mopt
; 
2102                 struct ip6_hbh 
*hbh
; 
2104                 mopt 
= exthdrs
->ip6e_hbh
; 
2105                 if (M_TRAILINGSPACE(mopt
) < JUMBOOPTLEN
) { 
2108                          * - exthdrs->ip6e_hbh is not referenced from places 
2109                          *   other than exthdrs. 
2110                          * - exthdrs->ip6e_hbh is not an mbuf chain. 
2112                         u_int32_t oldoptlen 
= mopt
->m_len
; 
2116                          * XXX: give up if the whole (new) hbh header does 
2117                          * not fit even in an mbuf cluster. 
2119                         if (oldoptlen 
+ JUMBOOPTLEN 
> MCLBYTES
) 
2123                          * As a consequence, we must always prepare a cluster 
2126                         MGET(n
, M_DONTWAIT
, MT_DATA
); 
2128                                 MCLGET(n
, M_DONTWAIT
); 
2129                                 if (!(n
->m_flags 
& M_EXT
)) { 
2136                         n
->m_len 
= oldoptlen 
+ JUMBOOPTLEN
; 
2137                         bcopy(mtod(mopt
, caddr_t
), mtod(n
, caddr_t
), 
2139                         optbuf 
= mtod(n
, u_char 
*) + oldoptlen
; 
2141                         mopt 
= exthdrs
->ip6e_hbh 
= n
; 
2143                         optbuf 
= mtod(mopt
, u_char 
*) + mopt
->m_len
; 
2144                         mopt
->m_len 
+= JUMBOOPTLEN
; 
2146                 optbuf
[0] = IP6OPT_PADN
; 
2150                  * Adjust the header length according to the pad and 
2151                  * the jumbo payload option. 
2153                 hbh 
= mtod(mopt
, struct ip6_hbh 
*); 
2154                 hbh
->ip6h_len 
+= (JUMBOOPTLEN 
>> 3); 
2157         /* fill in the option. */ 
2158         optbuf
[2] = IP6OPT_JUMBO
; 
2160         v 
= (u_int32_t
)htonl(plen 
+ JUMBOOPTLEN
); 
2161         bcopy(&v
, &optbuf
[4], sizeof (u_int32_t
)); 
2163         /* finally, adjust the packet header length */ 
2164         exthdrs
->ip6e_ip6
->m_pkthdr
.len 
+= JUMBOOPTLEN
; 
2171  * Insert fragment header and copy unfragmentable header portions. 
2174 ip6_insertfraghdr(struct mbuf 
*m0
, struct mbuf 
*m
, int hlen
, 
2175     struct ip6_frag 
**frghdrp
) 
2177         struct mbuf 
*n
, *mlast
; 
2179         if (hlen 
> sizeof (struct ip6_hdr
)) { 
2180                 n 
= m_copym(m0
, sizeof (struct ip6_hdr
), 
2181                     hlen 
- sizeof (struct ip6_hdr
), M_DONTWAIT
); 
2188         /* Search for the last mbuf of unfragmentable part. */ 
2189         for (mlast 
= n
; mlast
->m_next
; mlast 
= mlast
->m_next
) 
2192         if (!(mlast
->m_flags 
& M_EXT
) && 
2193             M_TRAILINGSPACE(mlast
) >= sizeof (struct ip6_frag
)) { 
2194                 /* use the trailing space of the last mbuf for the frag hdr */ 
2195                 *frghdrp 
= (struct ip6_frag 
*)(mtod(mlast
, caddr_t
) + 
2197                 mlast
->m_len 
+= sizeof (struct ip6_frag
); 
2198                 m
->m_pkthdr
.len 
+= sizeof (struct ip6_frag
); 
2200                 /* allocate a new mbuf for the fragment header */ 
2203                 MGET(mfrg
, M_DONTWAIT
, MT_DATA
); 
2206                 mfrg
->m_len 
= sizeof (struct ip6_frag
); 
2207                 *frghdrp 
= mtod(mfrg
, struct ip6_frag 
*); 
2208                 mlast
->m_next 
= mfrg
; 
2215 ip6_getpmtu(struct route_in6 
*ro_pmtu
, struct route_in6 
*ro
, 
2216     struct ifnet 
*ifp
, struct in6_addr 
*dst
, u_int32_t 
*mtup
, 
2217     boolean_t 
*alwaysfragp
) 
2220         boolean_t alwaysfrag 
= FALSE
; 
2223         if (ro_pmtu 
!= ro
) { 
2224                 /* The first hop and the final destination may differ. */ 
2225                 struct sockaddr_in6 
*sa6_dst 
= SIN6(&ro_pmtu
->ro_dst
); 
2226                 if (ROUTE_UNUSABLE(ro_pmtu
) || 
2227                     !IN6_ARE_ADDR_EQUAL(&sa6_dst
->sin6_addr
, dst
)) 
2228                         ROUTE_RELEASE(ro_pmtu
); 
2230                 if (ro_pmtu
->ro_rt 
== NULL
) { 
2231                         bzero(sa6_dst
, sizeof (*sa6_dst
)); 
2232                         sa6_dst
->sin6_family 
= AF_INET6
; 
2233                         sa6_dst
->sin6_len 
= sizeof (struct sockaddr_in6
); 
2234                         sa6_dst
->sin6_addr 
= *dst
; 
2236                         rtalloc_scoped((struct route 
*)ro_pmtu
, 
2237                             ifp 
!= NULL 
? ifp
->if_index 
: IFSCOPE_NONE
); 
2241         if (ro_pmtu
->ro_rt 
!= NULL
) { 
2245                         ifp 
= ro_pmtu
->ro_rt
->rt_ifp
; 
2246                 /* Access without acquiring nd_ifinfo lock for performance */ 
2247                 ifmtu 
= IN6_LINKMTU(ifp
); 
2250                  * Access rmx_mtu without holding the route entry lock, 
2251                  * for performance; this isn't something that changes 
2252                  * often, so optimize. 
2254                 mtu 
= ro_pmtu
->ro_rt
->rt_rmx
.rmx_mtu
; 
2255                 if (mtu 
> ifmtu 
|| mtu 
== 0) { 
2257                          * The MTU on the route is larger than the MTU on 
2258                          * the interface!  This shouldn't happen, unless the 
2259                          * MTU of the interface has been changed after the 
2260                          * interface was brought up.  Change the MTU in the 
2261                          * route to match the interface MTU (as long as the 
2262                          * field isn't locked). 
2264                          * if MTU on the route is 0, we need to fix the MTU. 
2265                          * this case happens with path MTU discovery timeouts. 
2268                         if (!(ro_pmtu
->ro_rt
->rt_rmx
.rmx_locks 
& RTV_MTU
)) 
2269                                 ro_pmtu
->ro_rt
->rt_rmx
.rmx_mtu 
= mtu
; /* XXX */ 
2270                 } else if (mtu 
< IPV6_MMTU
) { 
2272                          * RFC2460 section 5, last paragraph: 
2273                          * if we record ICMPv6 too big message with 
2274                          * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU 
2275                          * or smaller, with framgent header attached. 
2276                          * (fragment header is needed regardless from the 
2277                          * packet size, for translators to identify packets) 
2284                         /* Don't hold nd_ifinfo lock for performance */ 
2285                         mtu 
= IN6_LINKMTU(ifp
); 
2287                         error 
= EHOSTUNREACH
; /* XXX */ 
2292         if (alwaysfragp 
!= NULL
) 
2293                 *alwaysfragp 
= alwaysfrag
; 
2298  * IP6 socket option processing. 
2301 ip6_ctloutput(struct socket 
*so
, struct sockopt 
*sopt
) 
2303         int optdatalen
, uproto
; 
2306         struct inpcb 
*in6p 
= sotoinpcb(so
); 
2307         int error 
= 0, optval 
= 0; 
2308         int level
, op 
= -1, optname 
= 0; 
2312         VERIFY(sopt 
!= NULL
); 
2314         level 
= sopt
->sopt_level
; 
2315         op 
= sopt
->sopt_dir
; 
2316         optname 
= sopt
->sopt_name
; 
2317         optlen 
= sopt
->sopt_valsize
; 
2319         uproto 
= (int)SOCK_PROTO(so
); 
2321         privileged 
= (proc_suser(p
) == 0); 
2323         if (level 
== IPPROTO_IPV6
) { 
2327                         case IPV6_2292PKTOPTIONS
: { 
2330                                 error 
= soopt_getm(sopt
, &m
); 
2333                                 error 
= soopt_mcopyin(sopt
, m
); 
2336                                 error 
= ip6_pcbopts(&in6p
->in6p_outputopts
, 
2343                          * Use of some Hop-by-Hop options or some 
2344                          * Destination options, might require special 
2345                          * privilege.  That is, normal applications 
2346                          * (without special privilege) might be forbidden 
2347                          * from setting certain options in outgoing packets, 
2348                          * and might never see certain options in received 
2349                          * packets. [RFC 2292 Section 6] 
2350                          * KAME specific note: 
2351                          *  KAME prevents non-privileged users from sending or 
2352                          *  receiving ANY hbh/dst options in order to avoid 
2353                          *  overhead of parsing options in the kernel. 
2355                         case IPV6_RECVHOPOPTS
: 
2356                         case IPV6_RECVDSTOPTS
: 
2357                         case IPV6_RECVRTHDRDSTOPTS
: 
2361                         case IPV6_UNICAST_HOPS
: 
2363                         case IPV6_RECVPKTINFO
: 
2364                         case IPV6_RECVHOPLIMIT
: 
2365                         case IPV6_RECVRTHDR
: 
2366                         case IPV6_RECVPATHMTU
: 
2367                         case IPV6_RECVTCLASS
: 
2369                         case IPV6_AUTOFLOWLABEL
: 
2370                                 if (optlen 
!= sizeof (int)) { 
2374                                 error 
= sooptcopyin(sopt
, &optval
, 
2375                                     sizeof (optval
), sizeof (optval
)); 
2380                                 case IPV6_UNICAST_HOPS
: 
2381                                         if (optval 
< -1 || optval 
>= 256) { 
2384                                                 /* -1 = kernel default */ 
2385                                                 in6p
->in6p_hops 
= optval
; 
2386                                                 if (in6p
->inp_vflag 
& 
2393 #define OPTSET(bit) do {                                                \ 
2395                 in6p->inp_flags |= (bit);                               \ 
2397                 in6p->inp_flags &= ~(bit);                              \ 
2400 #define OPTSET2292(bit) do {                                            \ 
2401         in6p->inp_flags |= IN6P_RFC2292;                                \ 
2403                 in6p->inp_flags |= (bit);                               \ 
2405                 in6p->inp_flags &= ~(bit);                              \ 
2408 #define OPTBIT(bit) (in6p->inp_flags & (bit) ? 1 : 0) 
2410                                 case IPV6_RECVPKTINFO
: 
2411                                         /* cannot mix with RFC2292 */ 
2412                                         if (OPTBIT(IN6P_RFC2292
)) { 
2416                                         OPTSET(IN6P_PKTINFO
); 
2419                                 case IPV6_HOPLIMIT
: { 
2420                                         struct ip6_pktopts 
**optp
; 
2422                                         /* cannot mix with RFC2292 */ 
2423                                         if (OPTBIT(IN6P_RFC2292
)) { 
2427                                         optp 
= &in6p
->in6p_outputopts
; 
2428                                         error 
= ip6_pcbopt(IPV6_HOPLIMIT
, 
2429                                             (u_char 
*)&optval
, sizeof (optval
), 
2434                                 case IPV6_RECVHOPLIMIT
: 
2435                                         /* cannot mix with RFC2292 */ 
2436                                         if (OPTBIT(IN6P_RFC2292
)) { 
2440                                         OPTSET(IN6P_HOPLIMIT
); 
2443                                 case IPV6_RECVHOPOPTS
: 
2444                                         /* cannot mix with RFC2292 */ 
2445                                         if (OPTBIT(IN6P_RFC2292
)) { 
2449                                         OPTSET(IN6P_HOPOPTS
); 
2452                                 case IPV6_RECVDSTOPTS
: 
2453                                         /* cannot mix with RFC2292 */ 
2454                                         if (OPTBIT(IN6P_RFC2292
)) { 
2458                                         OPTSET(IN6P_DSTOPTS
); 
2461                                 case IPV6_RECVRTHDRDSTOPTS
: 
2462                                         /* cannot mix with RFC2292 */ 
2463                                         if (OPTBIT(IN6P_RFC2292
)) { 
2467                                         OPTSET(IN6P_RTHDRDSTOPTS
); 
2470                                 case IPV6_RECVRTHDR
: 
2471                                         /* cannot mix with RFC2292 */ 
2472                                         if (OPTBIT(IN6P_RFC2292
)) { 
2479                                 case IPV6_RECVPATHMTU
: 
2481                                          * We ignore this option for TCP 
2483                                          * (RFC3542 leaves this case 
2486                                         if (uproto 
!= IPPROTO_TCP
) 
2492                                          * make setsockopt(IPV6_V6ONLY) 
2493                                          * available only prior to bind(2). 
2494                                          * see ipng mailing list, Jun 22 2001. 
2496                                         if (in6p
->inp_lport 
|| 
2497                                             !IN6_IS_ADDR_UNSPECIFIED( 
2498                                             &in6p
->in6p_laddr
)) { 
2502                                         OPTSET(IN6P_IPV6_V6ONLY
); 
2504                                                 in6p
->inp_vflag 
&= ~INP_IPV4
; 
2506                                                 in6p
->inp_vflag 
|= INP_IPV4
; 
2509                                 case IPV6_RECVTCLASS
: 
2510                                         /* we can mix with RFC2292 */ 
2511                                         OPTSET(IN6P_TCLASS
); 
2514                                 case IPV6_AUTOFLOWLABEL
: 
2515                                         OPTSET(IN6P_AUTOFLOWLABEL
); 
2523                         case IPV6_USE_MIN_MTU
: 
2524                         case IPV6_PREFER_TEMPADDR
: { 
2525                                 struct ip6_pktopts 
**optp
; 
2527                                 if (optlen 
!= sizeof (optval
)) { 
2531                                 error 
= sooptcopyin(sopt
, &optval
, 
2532                                     sizeof (optval
), sizeof (optval
)); 
2536                                 optp 
= &in6p
->in6p_outputopts
; 
2537                                 error 
= ip6_pcbopt(optname
, (u_char 
*)&optval
, 
2538                                     sizeof (optval
), optp
, uproto
); 
2542                         case IPV6_2292PKTINFO
: 
2543                         case IPV6_2292HOPLIMIT
: 
2544                         case IPV6_2292HOPOPTS
: 
2545                         case IPV6_2292DSTOPTS
: 
2546                         case IPV6_2292RTHDR
: 
2548                                 if (optlen 
!= sizeof (int)) { 
2552                                 error 
= sooptcopyin(sopt
, &optval
, 
2553                                     sizeof (optval
), sizeof (optval
)); 
2557                                 case IPV6_2292PKTINFO
: 
2558                                         OPTSET2292(IN6P_PKTINFO
); 
2560                                 case IPV6_2292HOPLIMIT
: 
2561                                         OPTSET2292(IN6P_HOPLIMIT
); 
2563                                 case IPV6_2292HOPOPTS
: 
2565                                          * Check super-user privilege. 
2566                                          * See comments for IPV6_RECVHOPOPTS. 
2570                                         OPTSET2292(IN6P_HOPOPTS
); 
2572                                 case IPV6_2292DSTOPTS
: 
2575                                         OPTSET2292(IN6P_DSTOPTS
| 
2576                                             IN6P_RTHDRDSTOPTS
); /* XXX */ 
2578                                 case IPV6_2292RTHDR
: 
2579                                         OPTSET2292(IN6P_RTHDR
); 
2584                         case IPV6_3542PKTINFO
: 
2585                         case IPV6_3542HOPOPTS
: 
2586                         case IPV6_3542RTHDR
: 
2587                         case IPV6_3542DSTOPTS
: 
2588                         case IPV6_RTHDRDSTOPTS
: 
2589                         case IPV6_3542NEXTHOP
: { 
2590                                 struct ip6_pktopts 
**optp
; 
2591                                 /* new advanced API (RFC3542) */ 
2594                                 /* cannot mix with RFC2292 */ 
2595                                 if (OPTBIT(IN6P_RFC2292
)) { 
2599                                 error 
= soopt_getm(sopt
, &m
); 
2602                                 error 
= soopt_mcopyin(sopt
, m
); 
2606                                 optp 
= &in6p
->in6p_outputopts
; 
2607                                 error 
= ip6_pcbopt(optname
, mtod(m
, u_char 
*), 
2608                                     m
->m_len
, optp
, uproto
); 
2613                         case IPV6_MULTICAST_IF
: 
2614                         case IPV6_MULTICAST_HOPS
: 
2615                         case IPV6_MULTICAST_LOOP
: 
2616                         case IPV6_JOIN_GROUP
: 
2617                         case IPV6_LEAVE_GROUP
: 
2619                         case MCAST_BLOCK_SOURCE
: 
2620                         case MCAST_UNBLOCK_SOURCE
: 
2621                         case MCAST_JOIN_GROUP
: 
2622                         case MCAST_LEAVE_GROUP
: 
2623                         case MCAST_JOIN_SOURCE_GROUP
: 
2624                         case MCAST_LEAVE_SOURCE_GROUP
: 
2625                                 error 
= ip6_setmoptions(in6p
, sopt
); 
2628                         case IPV6_PORTRANGE
: 
2629                                 error 
= sooptcopyin(sopt
, &optval
, 
2630                                     sizeof (optval
), sizeof (optval
)); 
2635                                 case IPV6_PORTRANGE_DEFAULT
: 
2636                                         in6p
->inp_flags 
&= ~(INP_LOWPORT
); 
2637                                         in6p
->inp_flags 
&= ~(INP_HIGHPORT
); 
2640                                 case IPV6_PORTRANGE_HIGH
: 
2641                                         in6p
->inp_flags 
&= ~(INP_LOWPORT
); 
2642                                         in6p
->inp_flags 
|= INP_HIGHPORT
; 
2645                                 case IPV6_PORTRANGE_LOW
: 
2646                                         in6p
->inp_flags 
&= ~(INP_HIGHPORT
); 
2647                                         in6p
->inp_flags 
|= INP_LOWPORT
; 
2656                         case IPV6_IPSEC_POLICY
: { 
2661                                 if ((error 
= soopt_getm(sopt
, &m
)) != 0) 
2663                                 if ((error 
= soopt_mcopyin(sopt
, m
)) != 0) 
2666                                 req 
= mtod(m
, caddr_t
); 
2668                                 error 
= ipsec6_set_policy(in6p
, optname
, req
, 
2678                         case IPV6_FW_ZERO
: { 
2679                                 if (ip6_fw_ctl_ptr 
== NULL
) 
2681                                 if (ip6_fw_ctl_ptr 
!= NULL
) 
2682                                         error 
= (*ip6_fw_ctl_ptr
)(sopt
); 
2684                                         error 
= ENOPROTOOPT
; 
2687 #endif /* IPFIREWALL */ 
2689                          * IPv6 variant of IP_BOUND_IF; for details see 
2690                          * comments on IP_BOUND_IF in ip_ctloutput(). 
2693                                 /* This option is settable only on IPv6 */ 
2694                                 if (!(in6p
->inp_vflag 
& INP_IPV6
)) { 
2699                                 error 
= sooptcopyin(sopt
, &optval
, 
2700                                     sizeof (optval
), sizeof (optval
)); 
2705                                 error 
= inp_bindif(in6p
, optval
, NULL
); 
2708                         case IPV6_NO_IFT_CELLULAR
: 
2709                                 /* This option is settable only for IPv6 */ 
2710                                 if (!(in6p
->inp_vflag 
& INP_IPV6
)) { 
2715                                 error 
= sooptcopyin(sopt
, &optval
, 
2716                                     sizeof (optval
), sizeof (optval
)); 
2721                                 /* once set, it cannot be unset */ 
2722                                 if (!optval 
&& INP_NO_CELLULAR(in6p
)) { 
2727                                 error 
= so_set_restrictions(so
, 
2728                                     SO_RESTRICT_DENY_CELLULAR
); 
2732                                 /* This option is not settable */ 
2737                                 error 
= ENOPROTOOPT
; 
2745                         case IPV6_2292PKTOPTIONS
: 
2747                                  * RFC3542 (effectively) deprecated the 
2748                                  * semantics of the 2292-style pktoptions. 
2749                                  * Since it was not reliable in nature (i.e., 
2750                                  * applications had to expect the lack of some 
2751                                  * information after all), it would make sense 
2752                                  * to simplify this part by always returning 
2755                                 sopt
->sopt_valsize 
= 0; 
2758                         case IPV6_RECVHOPOPTS
: 
2759                         case IPV6_RECVDSTOPTS
: 
2760                         case IPV6_RECVRTHDRDSTOPTS
: 
2761                         case IPV6_UNICAST_HOPS
: 
2762                         case IPV6_RECVPKTINFO
: 
2763                         case IPV6_RECVHOPLIMIT
: 
2764                         case IPV6_RECVRTHDR
: 
2765                         case IPV6_RECVPATHMTU
: 
2767                         case IPV6_PORTRANGE
: 
2768                         case IPV6_RECVTCLASS
: 
2769                         case IPV6_AUTOFLOWLABEL
: 
2772                                 case IPV6_RECVHOPOPTS
: 
2773                                         optval 
= OPTBIT(IN6P_HOPOPTS
); 
2776                                 case IPV6_RECVDSTOPTS
: 
2777                                         optval 
= OPTBIT(IN6P_DSTOPTS
); 
2780                                 case IPV6_RECVRTHDRDSTOPTS
: 
2781                                         optval 
= OPTBIT(IN6P_RTHDRDSTOPTS
); 
2784                                 case IPV6_UNICAST_HOPS
: 
2785                                         optval 
= in6p
->in6p_hops
; 
2788                                 case IPV6_RECVPKTINFO
: 
2789                                         optval 
= OPTBIT(IN6P_PKTINFO
); 
2792                                 case IPV6_RECVHOPLIMIT
: 
2793                                         optval 
= OPTBIT(IN6P_HOPLIMIT
); 
2796                                 case IPV6_RECVRTHDR
: 
2797                                         optval 
= OPTBIT(IN6P_RTHDR
); 
2800                                 case IPV6_RECVPATHMTU
: 
2801                                         optval 
= OPTBIT(IN6P_MTU
); 
2805                                         optval 
= OPTBIT(IN6P_IPV6_V6ONLY
); 
2808                                 case IPV6_PORTRANGE
: { 
2810                                         flags 
= in6p
->inp_flags
; 
2811                                         if (flags 
& INP_HIGHPORT
) 
2812                                                 optval 
= IPV6_PORTRANGE_HIGH
; 
2813                                         else if (flags 
& INP_LOWPORT
) 
2814                                                 optval 
= IPV6_PORTRANGE_LOW
; 
2819                                 case IPV6_RECVTCLASS
: 
2820                                         optval 
= OPTBIT(IN6P_TCLASS
); 
2823                                 case IPV6_AUTOFLOWLABEL
: 
2824                                         optval 
= OPTBIT(IN6P_AUTOFLOWLABEL
); 
2829                                 error 
= sooptcopyout(sopt
, &optval
, 
2833                         case IPV6_PATHMTU
: { 
2835                                 struct ip6_mtuinfo mtuinfo
; 
2836                                 struct route_in6 sro
; 
2838                                 bzero(&sro
, sizeof (sro
)); 
2840                                 if (!(so
->so_state 
& SS_ISCONNECTED
)) 
2843                                  * XXX: we dot not consider the case of source 
2844                                  * routing, or optional information to specify 
2845                                  * the outgoing interface. 
2847                                 error 
= ip6_getpmtu(&sro
, NULL
, NULL
, 
2848                                     &in6p
->in6p_faddr
, &pmtu
, NULL
); 
2849                                 ROUTE_RELEASE(&sro
); 
2852                                 if (pmtu 
> IPV6_MAXPACKET
) 
2853                                         pmtu 
= IPV6_MAXPACKET
; 
2855                                 bzero(&mtuinfo
, sizeof (mtuinfo
)); 
2856                                 mtuinfo
.ip6m_mtu 
= (u_int32_t
)pmtu
; 
2857                                 optdata 
= (void *)&mtuinfo
; 
2858                                 optdatalen 
= sizeof (mtuinfo
); 
2859                                 error 
= sooptcopyout(sopt
, optdata
, 
2864                         case IPV6_2292PKTINFO
: 
2865                         case IPV6_2292HOPLIMIT
: 
2866                         case IPV6_2292HOPOPTS
: 
2867                         case IPV6_2292RTHDR
: 
2868                         case IPV6_2292DSTOPTS
: 
2870                                 case IPV6_2292PKTINFO
: 
2871                                         optval 
= OPTBIT(IN6P_PKTINFO
); 
2873                                 case IPV6_2292HOPLIMIT
: 
2874                                         optval 
= OPTBIT(IN6P_HOPLIMIT
); 
2876                                 case IPV6_2292HOPOPTS
: 
2877                                         optval 
= OPTBIT(IN6P_HOPOPTS
); 
2879                                 case IPV6_2292RTHDR
: 
2880                                         optval 
= OPTBIT(IN6P_RTHDR
); 
2882                                 case IPV6_2292DSTOPTS
: 
2883                                         optval 
= OPTBIT(IN6P_DSTOPTS
| 
2887                                 error 
= sooptcopyout(sopt
, &optval
, 
2895                         case IPV6_RTHDRDSTOPTS
: 
2899                         case IPV6_USE_MIN_MTU
: 
2900                         case IPV6_PREFER_TEMPADDR
: 
2901                                 error 
= ip6_getpcbopt(in6p
->in6p_outputopts
, 
2905                         case IPV6_MULTICAST_IF
: 
2906                         case IPV6_MULTICAST_HOPS
: 
2907                         case IPV6_MULTICAST_LOOP
: 
2909                                 error 
= ip6_getmoptions(in6p
, sopt
); 
2912                         case IPV6_IPSEC_POLICY
: { 
2913                                 error 
= 0; /* This option is no longer supported */ 
2919                                 if (ip6_fw_ctl_ptr 
== NULL
) 
2921                                 if (ip6_fw_ctl_ptr 
!= NULL
) 
2922                                         error 
= (*ip6_fw_ctl_ptr
)(sopt
); 
2924                                         error 
= ENOPROTOOPT
; 
2927 #endif /* IPFIREWALL */ 
2929                                 if (in6p
->inp_flags 
& INP_BOUND_IF
) 
2930                                         optval 
= in6p
->inp_boundifp
->if_index
; 
2931                                 error 
= sooptcopyout(sopt
, &optval
, 
2935                         case IPV6_NO_IFT_CELLULAR
: 
2936                                 optval 
= INP_NO_CELLULAR(in6p
) ? 1 : 0; 
2937                                 error 
= sooptcopyout(sopt
, &optval
, 
2942                                 optval 
= (in6p
->in6p_last_outifp 
!= NULL
) ? 
2943                                     in6p
->in6p_last_outifp
->if_index 
: 0; 
2944                                 error 
= sooptcopyout(sopt
, &optval
, 
2949                                 error 
= ENOPROTOOPT
; 
2954         } else if (level 
== IPPROTO_UDP
) { 
2955                 error 
= udp_ctloutput(so
, sopt
); 
2963 ip6_raw_ctloutput(struct socket 
*so
, struct sockopt 
*sopt
) 
2965         int error 
= 0, optval
, optlen
; 
2966         const int icmp6off 
= offsetof(struct icmp6_hdr
, icmp6_cksum
); 
2967         struct inpcb 
*in6p 
= sotoinpcb(so
); 
2968         int level
, op
, optname
; 
2970         level 
= sopt
->sopt_level
; 
2971         op 
= sopt
->sopt_dir
; 
2972         optname 
= sopt
->sopt_name
; 
2973         optlen 
= sopt
->sopt_valsize
; 
2975         if (level 
!= IPPROTO_IPV6
) 
2981                  * For ICMPv6 sockets, no modification allowed for checksum 
2982                  * offset, permit "no change" values to help existing apps. 
2984                  * RFC3542 says: "An attempt to set IPV6_CHECKSUM 
2985                  * for an ICMPv6 socket will fail." 
2986                  * The current behavior does not meet RFC3542. 
2990                         if (optlen 
!= sizeof (int)) { 
2994                         error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
2998                         if ((optval 
% 2) != 0) { 
2999                                 /* the API assumes even offset values */ 
3001                         } else if (SOCK_PROTO(so
) == IPPROTO_ICMPV6
) { 
3002                                 if (optval 
!= icmp6off
) 
3005                                 in6p
->in6p_cksum 
= optval
; 
3010                         if (SOCK_PROTO(so
) == IPPROTO_ICMPV6
) 
3013                                 optval 
= in6p
->in6p_cksum
; 
3015                         error 
= sooptcopyout(sopt
, &optval
, sizeof (optval
)); 
3025                 error 
= ENOPROTOOPT
; 
3033  * Set up IP6 options in pcb for insertion in output packets or 
3034  * specifying behavior of outgoing packets. 
3037 ip6_pcbopts(struct ip6_pktopts 
**pktopt
, struct mbuf 
*m
, struct socket 
*so
, 
3038     struct sockopt 
*sopt
) 
3040 #pragma unused(sopt) 
3041         struct ip6_pktopts 
*opt 
= *pktopt
; 
3044         /* turn off any old options. */ 
3047                 if (opt
->ip6po_pktinfo 
|| opt
->ip6po_nexthop 
|| 
3048                     opt
->ip6po_hbh 
|| opt
->ip6po_dest1 
|| opt
->ip6po_dest2 
|| 
3049                     opt
->ip6po_rhinfo
.ip6po_rhi_rthdr
) 
3050                         printf("%s: all specified options are cleared.\n", 
3053                 ip6_clearpktopts(opt
, -1); 
3055                 opt 
= _MALLOC(sizeof (*opt
), M_IP6OPT
, M_WAITOK
); 
3061         if (m 
== NULL 
|| m
->m_len 
== 0) { 
3063                  * Only turning off any previous options, regardless of 
3064                  * whether the opt is just created or given. 
3067                         FREE(opt
, M_IP6OPT
); 
3071         /*  set options specified by user. */ 
3072         if ((error 
= ip6_setpktopts(m
, opt
, NULL
, SOCK_PROTO(so
))) != 0) { 
3073                 ip6_clearpktopts(opt
, -1); /* XXX: discard all options */ 
3074                 FREE(opt
, M_IP6OPT
); 
3082  * initialize ip6_pktopts.  beware that there are non-zero default values in 
3086 ip6_initpktopts(struct ip6_pktopts 
*opt
) 
3089         bzero(opt
, sizeof (*opt
)); 
3090         opt
->ip6po_hlim 
= -1;   /* -1 means default hop limit */ 
3091         opt
->ip6po_tclass 
= -1; /* -1 means default traffic class */ 
3092         opt
->ip6po_minmtu 
= IP6PO_MINMTU_MCASTONLY
; 
3093         opt
->ip6po_prefer_tempaddr 
= IP6PO_TEMPADDR_SYSTEM
; 
3097 ip6_pcbopt(int optname
, u_char 
*buf
, int len
, struct ip6_pktopts 
**pktopt
, 
3100         struct ip6_pktopts 
*opt
; 
3104                 opt 
= _MALLOC(sizeof (*opt
), M_IP6OPT
, M_WAITOK
); 
3107                 ip6_initpktopts(opt
); 
3111         return (ip6_setpktopt(optname
, buf
, len
, opt
, 1, 0, uproto
)); 
3115 ip6_getpcbopt(struct ip6_pktopts 
*pktopt
, int optname
, struct sockopt 
*sopt
) 
3117         void *optdata 
= NULL
; 
3119         struct ip6_ext 
*ip6e
; 
3120         struct in6_pktinfo null_pktinfo
; 
3121         int deftclass 
= 0, on
; 
3122         int defminmtu 
= IP6PO_MINMTU_MCASTONLY
; 
3123         int defpreftemp 
= IP6PO_TEMPADDR_SYSTEM
; 
3128                 if (pktopt 
&& pktopt
->ip6po_pktinfo
) 
3129                         optdata 
= (void *)pktopt
->ip6po_pktinfo
; 
3131                         /* XXX: we don't have to do this every time... */ 
3132                         bzero(&null_pktinfo
, sizeof (null_pktinfo
)); 
3133                         optdata 
= (void *)&null_pktinfo
; 
3135                 optdatalen 
= sizeof (struct in6_pktinfo
); 
3139                 if (pktopt 
&& pktopt
->ip6po_tclass 
>= 0) 
3140                         optdata 
= (void *)&pktopt
->ip6po_tclass
; 
3142                         optdata 
= (void *)&deftclass
; 
3143                 optdatalen 
= sizeof (int); 
3147                 if (pktopt 
&& pktopt
->ip6po_hbh
) { 
3148                         optdata 
= (void *)pktopt
->ip6po_hbh
; 
3149                         ip6e 
= (struct ip6_ext 
*)pktopt
->ip6po_hbh
; 
3150                         optdatalen 
= (ip6e
->ip6e_len 
+ 1) << 3; 
3155                 if (pktopt 
&& pktopt
->ip6po_rthdr
) { 
3156                         optdata 
= (void *)pktopt
->ip6po_rthdr
; 
3157                         ip6e 
= (struct ip6_ext 
*)pktopt
->ip6po_rthdr
; 
3158                         optdatalen 
= (ip6e
->ip6e_len 
+ 1) << 3; 
3162         case IPV6_RTHDRDSTOPTS
: 
3163                 if (pktopt 
&& pktopt
->ip6po_dest1
) { 
3164                         optdata 
= (void *)pktopt
->ip6po_dest1
; 
3165                         ip6e 
= (struct ip6_ext 
*)pktopt
->ip6po_dest1
; 
3166                         optdatalen 
= (ip6e
->ip6e_len 
+ 1) << 3; 
3171                 if (pktopt 
&& pktopt
->ip6po_dest2
) { 
3172                         optdata 
= (void *)pktopt
->ip6po_dest2
; 
3173                         ip6e 
= (struct ip6_ext 
*)pktopt
->ip6po_dest2
; 
3174                         optdatalen 
= (ip6e
->ip6e_len 
+ 1) << 3; 
3179                 if (pktopt 
&& pktopt
->ip6po_nexthop
) { 
3180                         optdata 
= (void *)pktopt
->ip6po_nexthop
; 
3181                         optdatalen 
= pktopt
->ip6po_nexthop
->sa_len
; 
3185         case IPV6_USE_MIN_MTU
: 
3187                         optdata 
= (void *)&pktopt
->ip6po_minmtu
; 
3189                         optdata 
= (void *)&defminmtu
; 
3190                 optdatalen 
= sizeof (int); 
3194                 if (pktopt 
&& ((pktopt
->ip6po_flags
) & IP6PO_DONTFRAG
)) 
3198                 optdata 
= (void *)&on
; 
3199                 optdatalen 
= sizeof (on
); 
3202         case IPV6_PREFER_TEMPADDR
: 
3204                         optdata 
= (void *)&pktopt
->ip6po_prefer_tempaddr
; 
3206                         optdata 
= (void *)&defpreftemp
; 
3207                 optdatalen 
= sizeof (int); 
3210         default:                /* should not happen */ 
3212                 panic("ip6_getpcbopt: unexpected option\n"); 
3214                 return (ENOPROTOOPT
); 
3217         return (sooptcopyout(sopt
, optdata
, optdatalen
)); 
3221 ip6_clearpktopts(struct ip6_pktopts 
*pktopt
, int optname
) 
3226         if (optname 
== -1 || optname 
== IPV6_PKTINFO
) { 
3227                 if (pktopt
->ip6po_pktinfo
) 
3228                         FREE(pktopt
->ip6po_pktinfo
, M_IP6OPT
); 
3229                 pktopt
->ip6po_pktinfo 
= NULL
; 
3231         if (optname 
== -1 || optname 
== IPV6_HOPLIMIT
) 
3232                 pktopt
->ip6po_hlim 
= -1; 
3233         if (optname 
== -1 || optname 
== IPV6_TCLASS
) 
3234                 pktopt
->ip6po_tclass 
= -1; 
3235         if (optname 
== -1 || optname 
== IPV6_NEXTHOP
) { 
3236                 ROUTE_RELEASE(&pktopt
->ip6po_nextroute
); 
3237                 if (pktopt
->ip6po_nexthop
) 
3238                         FREE(pktopt
->ip6po_nexthop
, M_IP6OPT
); 
3239                 pktopt
->ip6po_nexthop 
= NULL
; 
3241         if (optname 
== -1 || optname 
== IPV6_HOPOPTS
) { 
3242                 if (pktopt
->ip6po_hbh
) 
3243                         FREE(pktopt
->ip6po_hbh
, M_IP6OPT
); 
3244                 pktopt
->ip6po_hbh 
= NULL
; 
3246         if (optname 
== -1 || optname 
== IPV6_RTHDRDSTOPTS
) { 
3247                 if (pktopt
->ip6po_dest1
) 
3248                         FREE(pktopt
->ip6po_dest1
, M_IP6OPT
); 
3249                 pktopt
->ip6po_dest1 
= NULL
; 
3251         if (optname 
== -1 || optname 
== IPV6_RTHDR
) { 
3252                 if (pktopt
->ip6po_rhinfo
.ip6po_rhi_rthdr
) 
3253                         FREE(pktopt
->ip6po_rhinfo
.ip6po_rhi_rthdr
, M_IP6OPT
); 
3254                 pktopt
->ip6po_rhinfo
.ip6po_rhi_rthdr 
= NULL
; 
3255                 ROUTE_RELEASE(&pktopt
->ip6po_route
); 
3257         if (optname 
== -1 || optname 
== IPV6_DSTOPTS
) { 
3258                 if (pktopt
->ip6po_dest2
) 
3259                         FREE(pktopt
->ip6po_dest2
, M_IP6OPT
); 
3260                 pktopt
->ip6po_dest2 
= NULL
; 
3264 #define PKTOPT_EXTHDRCPY(type) do {                                     \ 
3267                     (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3; \ 
3268                 dst->type = _MALLOC(hlen, M_IP6OPT, canwait);           \ 
3269                 if (dst->type == NULL && canwait == M_NOWAIT)           \ 
3271                 bcopy(src->type, dst->type, hlen);                      \ 
3276 copypktopts(struct ip6_pktopts 
*dst
, struct ip6_pktopts 
*src
, int canwait
) 
3278         if (dst 
== NULL 
|| src 
== NULL
)  { 
3279                 printf("copypktopts: invalid argument\n"); 
3283         dst
->ip6po_hlim 
= src
->ip6po_hlim
; 
3284         dst
->ip6po_tclass 
= src
->ip6po_tclass
; 
3285         dst
->ip6po_flags 
= src
->ip6po_flags
; 
3286         if (src
->ip6po_pktinfo
) { 
3287                 dst
->ip6po_pktinfo 
= _MALLOC(sizeof (*dst
->ip6po_pktinfo
), 
3289                 if (dst
->ip6po_pktinfo 
== NULL 
&& canwait 
== M_NOWAIT
) 
3291                 *dst
->ip6po_pktinfo 
= *src
->ip6po_pktinfo
; 
3293         if (src
->ip6po_nexthop
) { 
3294                 dst
->ip6po_nexthop 
= _MALLOC(src
->ip6po_nexthop
->sa_len
, 
3296                 if (dst
->ip6po_nexthop 
== NULL 
&& canwait 
== M_NOWAIT
) 
3298                 bcopy(src
->ip6po_nexthop
, dst
->ip6po_nexthop
, 
3299                     src
->ip6po_nexthop
->sa_len
); 
3301         PKTOPT_EXTHDRCPY(ip6po_hbh
); 
3302         PKTOPT_EXTHDRCPY(ip6po_dest1
); 
3303         PKTOPT_EXTHDRCPY(ip6po_dest2
); 
3304         PKTOPT_EXTHDRCPY(ip6po_rthdr
); /* not copy the cached route */ 
3308         ip6_clearpktopts(dst
, -1); 
3311 #undef PKTOPT_EXTHDRCPY 
3313 struct ip6_pktopts 
* 
3314 ip6_copypktopts(struct ip6_pktopts 
*src
, int canwait
) 
3317         struct ip6_pktopts 
*dst
; 
3319         dst 
= _MALLOC(sizeof (*dst
), M_IP6OPT
, canwait
); 
3322         ip6_initpktopts(dst
); 
3324         if ((error 
= copypktopts(dst
, src
, canwait
)) != 0) { 
3325                 FREE(dst
, M_IP6OPT
); 
3333 ip6_freepcbopts(struct ip6_pktopts 
*pktopt
) 
3338         ip6_clearpktopts(pktopt
, -1); 
3340         FREE(pktopt
, M_IP6OPT
); 
3344 ip6_moptions_init(void) 
3346         PE_parse_boot_argn("ifa_debug", &im6o_debug
, sizeof (im6o_debug
)); 
3348         im6o_size 
= (im6o_debug 
== 0) ? sizeof (struct ip6_moptions
) : 
3349             sizeof (struct ip6_moptions_dbg
); 
3351         im6o_zone 
= zinit(im6o_size
, IM6O_ZONE_MAX 
* im6o_size
, 0, 
3353         if (im6o_zone 
== NULL
) { 
3354                 panic("%s: failed allocating %s", __func__
, IM6O_ZONE_NAME
); 
3357         zone_change(im6o_zone
, Z_EXPAND
, TRUE
); 
3361 im6o_addref(struct ip6_moptions 
*im6o
, int locked
) 
3366                 IM6O_LOCK_ASSERT_HELD(im6o
); 
3368         if (++im6o
->im6o_refcnt 
== 0) { 
3369                 panic("%s: im6o %p wraparound refcnt\n", __func__
, im6o
); 
3371         } else if (im6o
->im6o_trace 
!= NULL
) { 
3372                 (*im6o
->im6o_trace
)(im6o
, TRUE
); 
3380 im6o_remref(struct ip6_moptions 
*im6o
) 
3385         if (im6o
->im6o_refcnt 
== 0) { 
3386                 panic("%s: im6o %p negative refcnt", __func__
, im6o
); 
3388         } else if (im6o
->im6o_trace 
!= NULL
) { 
3389                 (*im6o
->im6o_trace
)(im6o
, FALSE
); 
3392         --im6o
->im6o_refcnt
; 
3393         if (im6o
->im6o_refcnt 
> 0) { 
3398         for (i 
= 0; i 
< im6o
->im6o_num_memberships
; ++i
) { 
3399                 struct in6_mfilter 
*imf
; 
3401                 imf 
= im6o
->im6o_mfilters 
? &im6o
->im6o_mfilters
[i
] : NULL
; 
3405                 (void) in6_mc_leave(im6o
->im6o_membership
[i
], imf
); 
3410                 IN6M_REMREF(im6o
->im6o_membership
[i
]); 
3411                 im6o
->im6o_membership
[i
] = NULL
; 
3413         im6o
->im6o_num_memberships 
= 0; 
3414         if (im6o
->im6o_mfilters 
!= NULL
) { 
3415                 FREE(im6o
->im6o_mfilters
, M_IN6MFILTER
); 
3416                 im6o
->im6o_mfilters 
= NULL
; 
3418         if (im6o
->im6o_membership 
!= NULL
) { 
3419                 FREE(im6o
->im6o_membership
, M_IP6MOPTS
); 
3420                 im6o
->im6o_membership 
= NULL
; 
3424         lck_mtx_destroy(&im6o
->im6o_lock
, ifa_mtx_grp
); 
3426         if (!(im6o
->im6o_debug 
& IFD_ALLOC
)) { 
3427                 panic("%s: im6o %p cannot be freed", __func__
, im6o
); 
3430         zfree(im6o_zone
, im6o
); 
3434 im6o_trace(struct ip6_moptions 
*im6o
, int refhold
) 
3436         struct ip6_moptions_dbg 
*im6o_dbg 
= (struct ip6_moptions_dbg 
*)im6o
; 
3441         if (!(im6o
->im6o_debug 
& IFD_DEBUG
)) { 
3442                 panic("%s: im6o %p has no debug structure", __func__
, im6o
); 
3446                 cnt 
= &im6o_dbg
->im6o_refhold_cnt
; 
3447                 tr 
= im6o_dbg
->im6o_refhold
; 
3449                 cnt 
= &im6o_dbg
->im6o_refrele_cnt
; 
3450                 tr 
= im6o_dbg
->im6o_refrele
; 
3453         idx 
= atomic_add_16_ov(cnt
, 1) % IM6O_TRACE_HIST_SIZE
; 
3454         ctrace_record(&tr
[idx
]); 
3457 struct ip6_moptions 
* 
3458 ip6_allocmoptions(int how
) 
3460         struct ip6_moptions 
*im6o
; 
3462         im6o 
= (how 
== M_WAITOK
) ? 
3463             zalloc(im6o_zone
) : zalloc_noblock(im6o_zone
); 
3465                 bzero(im6o
, im6o_size
); 
3466                 lck_mtx_init(&im6o
->im6o_lock
, ifa_mtx_grp
, ifa_mtx_attr
); 
3467                 im6o
->im6o_debug 
|= IFD_ALLOC
; 
3468                 if (im6o_debug 
!= 0) { 
3469                         im6o
->im6o_debug 
|= IFD_DEBUG
; 
3470                         im6o
->im6o_trace 
= im6o_trace
; 
3479  * Set IPv6 outgoing packet options based on advanced API. 
3482 ip6_setpktopts(struct mbuf 
*control
, struct ip6_pktopts 
*opt
, 
3483     struct ip6_pktopts 
*stickyopt
, int uproto
) 
3485         struct cmsghdr 
*cm 
= NULL
; 
3487         if (control 
== NULL 
|| opt 
== NULL
) 
3490         ip6_initpktopts(opt
); 
3495                  * If stickyopt is provided, make a local copy of the options 
3496                  * for this particular packet, then override them by ancillary 
3498                  * XXX: copypktopts() does not copy the cached route to a next 
3499                  * hop (if any).  This is not very good in terms of efficiency, 
3500                  * but we can allow this since this option should be rarely 
3503                 if ((error 
= copypktopts(opt
, stickyopt
, M_NOWAIT
)) != 0) 
3508          * XXX: Currently, we assume all the optional information is stored 
3511         if (control
->m_next
) 
3514         if (control
->m_len 
< CMSG_LEN(0)) 
3517         for (cm 
= M_FIRST_CMSGHDR(control
); cm 
!= NULL
; 
3518             cm 
= M_NXT_CMSGHDR(control
, cm
)) { 
3521                 if (cm
->cmsg_len 
< sizeof (struct cmsghdr
) || 
3522                     cm
->cmsg_len 
> control
->m_len
) 
3524                 if (cm
->cmsg_level 
!= IPPROTO_IPV6
) 
3527                 error 
= ip6_setpktopt(cm
->cmsg_type
, CMSG_DATA(cm
), 
3528                     cm
->cmsg_len 
- CMSG_LEN(0), opt
, 0, 1, uproto
); 
3536  * Set a particular packet option, as a sticky option or an ancillary data 
3537  * item.  "len" can be 0 only when it's a sticky option. 
3538  * We have 4 cases of combination of "sticky" and "cmsg": 
3539  * "sticky=0, cmsg=0": impossible 
3540  * "sticky=0, cmsg=1": RFC2292 or RFC3542 ancillary data 
3541  * "sticky=1, cmsg=0": RFC3542 socket option 
3542  * "sticky=1, cmsg=1": RFC2292 socket option 
3545 ip6_setpktopt(int optname
, u_char 
*buf
, int len
, struct ip6_pktopts 
*opt
, 
3546     int sticky
, int cmsg
, int uproto
) 
3548         int minmtupolicy
, preftemp
; 
3551         if (!sticky 
&& !cmsg
) { 
3553                 printf("ip6_setpktopt: impossible case\n"); 
3559          * Caller must have ensured that the buffer is at least 
3560          * aligned on 32-bit boundary. 
3562         VERIFY(IS_P2ALIGNED(buf
, sizeof (u_int32_t
))); 
3565          * IPV6_2292xxx is for backward compatibility to RFC2292, and should 
3566          * not be specified in the context of RFC3542.  Conversely, 
3567          * RFC3542 types should not be specified in the context of RFC2292. 
3571                 case IPV6_2292PKTINFO
: 
3572                 case IPV6_2292HOPLIMIT
: 
3573                 case IPV6_2292NEXTHOP
: 
3574                 case IPV6_2292HOPOPTS
: 
3575                 case IPV6_2292DSTOPTS
: 
3576                 case IPV6_2292RTHDR
: 
3577                 case IPV6_2292PKTOPTIONS
: 
3578                         return (ENOPROTOOPT
); 
3581         if (sticky 
&& cmsg
) { 
3588                 case IPV6_RTHDRDSTOPTS
: 
3590                 case IPV6_USE_MIN_MTU
: 
3593                 case IPV6_PREFER_TEMPADDR
: /* XXX: not an RFC3542 option */ 
3594                         return (ENOPROTOOPT
); 
3599         case IPV6_2292PKTINFO
: 
3600         case IPV6_PKTINFO
: { 
3601                 struct ifnet 
*ifp 
= NULL
; 
3602                 struct in6_pktinfo 
*pktinfo
; 
3604                 if (len 
!= sizeof (struct in6_pktinfo
)) 
3607                 pktinfo 
= (struct in6_pktinfo 
*)(void *)buf
; 
3610                  * An application can clear any sticky IPV6_PKTINFO option by 
3611                  * doing a "regular" setsockopt with ipi6_addr being 
3612                  * in6addr_any and ipi6_ifindex being zero. 
3613                  * [RFC 3542, Section 6] 
3615                 if (optname 
== IPV6_PKTINFO 
&& opt
->ip6po_pktinfo 
&& 
3616                     pktinfo
->ipi6_ifindex 
== 0 && 
3617                     IN6_IS_ADDR_UNSPECIFIED(&pktinfo
->ipi6_addr
)) { 
3618                         ip6_clearpktopts(opt
, optname
); 
3622                 if (uproto 
== IPPROTO_TCP 
&& optname 
== IPV6_PKTINFO 
&& 
3623                     sticky 
&& !IN6_IS_ADDR_UNSPECIFIED(&pktinfo
->ipi6_addr
)) { 
3627                 /* validate the interface index if specified. */ 
3628                 ifnet_head_lock_shared(); 
3630                 if (pktinfo
->ipi6_ifindex 
> if_index
) { 
3635                 if (pktinfo
->ipi6_ifindex
) { 
3636                         ifp 
= ifindex2ifnet
[pktinfo
->ipi6_ifindex
]; 
3646                  * We store the address anyway, and let in6_selectsrc() 
3647                  * validate the specified address.  This is because ipi6_addr 
3648                  * may not have enough information about its scope zone, and 
3649                  * we may need additional information (such as outgoing 
3650                  * interface or the scope zone of a destination address) to 
3651                  * disambiguate the scope. 
3652                  * XXX: the delay of the validation may confuse the 
3653                  * application when it is used as a sticky option. 
3655                 if (opt
->ip6po_pktinfo 
== NULL
) { 
3656                         opt
->ip6po_pktinfo 
= _MALLOC(sizeof (*pktinfo
), 
3657                             M_IP6OPT
, M_NOWAIT
); 
3658                         if (opt
->ip6po_pktinfo 
== NULL
) 
3661                 bcopy(pktinfo
, opt
->ip6po_pktinfo
, sizeof (*pktinfo
)); 
3665         case IPV6_2292HOPLIMIT
: 
3666         case IPV6_HOPLIMIT
: { 
3670                  * RFC 3542 deprecated the usage of sticky IPV6_HOPLIMIT 
3671                  * to simplify the ordering among hoplimit options. 
3673                 if (optname 
== IPV6_HOPLIMIT 
&& sticky
) 
3674                         return (ENOPROTOOPT
); 
3676                 if (len 
!= sizeof (int)) 
3678                 hlimp 
= (int *)(void *)buf
; 
3679                 if (*hlimp 
< -1 || *hlimp 
> 255) 
3682                 opt
->ip6po_hlim 
= *hlimp
; 
3689                 if (len 
!= sizeof (int)) 
3691                 tclass 
= *(int *)(void *)buf
; 
3692                 if (tclass 
< -1 || tclass 
> 255) 
3695                 opt
->ip6po_tclass 
= tclass
; 
3699         case IPV6_2292NEXTHOP
: 
3701                 error 
= suser(kauth_cred_get(), 0); 
3705                 if (len 
== 0) { /* just remove the option */ 
3706                         ip6_clearpktopts(opt
, IPV6_NEXTHOP
); 
3710                 /* check if cmsg_len is large enough for sa_len */ 
3711                 if (len 
< sizeof (struct sockaddr
) || len 
< *buf
) 
3714                 switch (SA(buf
)->sa_family
) { 
3716                         struct sockaddr_in6 
*sa6 
= SIN6(buf
); 
3718                         if (sa6
->sin6_len 
!= sizeof (struct sockaddr_in6
)) 
3721                         if (IN6_IS_ADDR_UNSPECIFIED(&sa6
->sin6_addr
) || 
3722                             IN6_IS_ADDR_MULTICAST(&sa6
->sin6_addr
)) { 
3725                         if ((error 
= sa6_embedscope(sa6
, ip6_use_defzone
)) 
3731                 case AF_LINK
:   /* should eventually be supported */ 
3733                         return (EAFNOSUPPORT
); 
3736                 /* turn off the previous option, then set the new option. */ 
3737                 ip6_clearpktopts(opt
, IPV6_NEXTHOP
); 
3738                 opt
->ip6po_nexthop 
= _MALLOC(*buf
, M_IP6OPT
, M_NOWAIT
); 
3739                 if (opt
->ip6po_nexthop 
== NULL
) 
3741                 bcopy(buf
, opt
->ip6po_nexthop
, *buf
); 
3744         case IPV6_2292HOPOPTS
: 
3745         case IPV6_HOPOPTS
: { 
3746                 struct ip6_hbh 
*hbh
; 
3750                  * XXX: We don't allow a non-privileged user to set ANY HbH 
3751                  * options, since per-option restriction has too much 
3754                 error 
= suser(kauth_cred_get(), 0); 
3759                         ip6_clearpktopts(opt
, IPV6_HOPOPTS
); 
3760                         break;  /* just remove the option */ 
3763                 /* message length validation */ 
3764                 if (len 
< sizeof (struct ip6_hbh
)) 
3766                 hbh 
= (struct ip6_hbh 
*)(void *)buf
; 
3767                 hbhlen 
= (hbh
->ip6h_len 
+ 1) << 3; 
3771                 /* turn off the previous option, then set the new option. */ 
3772                 ip6_clearpktopts(opt
, IPV6_HOPOPTS
); 
3773                 opt
->ip6po_hbh 
= _MALLOC(hbhlen
, M_IP6OPT
, M_NOWAIT
); 
3774                 if (opt
->ip6po_hbh 
== NULL
) 
3776                 bcopy(hbh
, opt
->ip6po_hbh
, hbhlen
); 
3781         case IPV6_2292DSTOPTS
: 
3783         case IPV6_RTHDRDSTOPTS
: { 
3784                 struct ip6_dest 
*dest
, **newdest 
= NULL
; 
3787                 error 
= suser(kauth_cred_get(), 0); 
3792                         ip6_clearpktopts(opt
, optname
); 
3793                         break;  /* just remove the option */ 
3796                 /* message length validation */ 
3797                 if (len 
< sizeof (struct ip6_dest
)) 
3799                 dest 
= (struct ip6_dest 
*)(void *)buf
; 
3800                 destlen 
= (dest
->ip6d_len 
+ 1) << 3; 
3805                  * Determine the position that the destination options header 
3806                  * should be inserted; before or after the routing header. 
3809                 case IPV6_2292DSTOPTS
: 
3811                          * The old advacned API is ambiguous on this point. 
3812                          * Our approach is to determine the position based 
3813                          * according to the existence of a routing header. 
3814                          * Note, however, that this depends on the order of the 
3815                          * extension headers in the ancillary data; the 1st 
3816                          * part of the destination options header must appear 
3817                          * before the routing header in the ancillary data, 
3819                          * RFC3542 solved the ambiguity by introducing 
3820                          * separate ancillary data or option types. 
3822                         if (opt
->ip6po_rthdr 
== NULL
) 
3823                                 newdest 
= &opt
->ip6po_dest1
; 
3825                                 newdest 
= &opt
->ip6po_dest2
; 
3827                 case IPV6_RTHDRDSTOPTS
: 
3828                         newdest 
= &opt
->ip6po_dest1
; 
3831                         newdest 
= &opt
->ip6po_dest2
; 
3835                 /* turn off the previous option, then set the new option. */ 
3836                 ip6_clearpktopts(opt
, optname
); 
3837                 *newdest 
= _MALLOC(destlen
, M_IP6OPT
, M_NOWAIT
); 
3838                 if (*newdest 
== NULL
) 
3840                 bcopy(dest
, *newdest
, destlen
); 
3844         case IPV6_2292RTHDR
: 
3846                 struct ip6_rthdr 
*rth
; 
3850                         ip6_clearpktopts(opt
, IPV6_RTHDR
); 
3851                         break;  /* just remove the option */ 
3854                 /* message length validation */ 
3855                 if (len 
< sizeof (struct ip6_rthdr
)) 
3857                 rth 
= (struct ip6_rthdr 
*)(void *)buf
; 
3858                 rthlen 
= (rth
->ip6r_len 
+ 1) << 3; 
3862                 switch (rth
->ip6r_type
) { 
3863                 case IPV6_RTHDR_TYPE_0
: 
3864                         if (rth
->ip6r_len 
== 0) /* must contain one addr */ 
3866                         if (rth
->ip6r_len 
% 2) /* length must be even */ 
3868                         if (rth
->ip6r_len 
/ 2 != rth
->ip6r_segleft
) 
3872                         return (EINVAL
);        /* not supported */ 
3875                 /* turn off the previous option */ 
3876                 ip6_clearpktopts(opt
, IPV6_RTHDR
); 
3877                 opt
->ip6po_rthdr 
= _MALLOC(rthlen
, M_IP6OPT
, M_NOWAIT
); 
3878                 if (opt
->ip6po_rthdr 
== NULL
) 
3880                 bcopy(rth
, opt
->ip6po_rthdr
, rthlen
); 
3884         case IPV6_USE_MIN_MTU
: 
3885                 if (len 
!= sizeof (int)) 
3887                 minmtupolicy 
= *(int *)(void *)buf
; 
3888                 if (minmtupolicy 
!= IP6PO_MINMTU_MCASTONLY 
&& 
3889                     minmtupolicy 
!= IP6PO_MINMTU_DISABLE 
&& 
3890                     minmtupolicy 
!= IP6PO_MINMTU_ALL
) { 
3893                 opt
->ip6po_minmtu 
= minmtupolicy
; 
3897                 if (len 
!= sizeof (int)) 
3900                 if (uproto 
== IPPROTO_TCP 
|| *(int *)(void *)buf 
== 0) { 
3902                          * we ignore this option for TCP sockets. 
3903                          * (RFC3542 leaves this case unspecified.) 
3905                         opt
->ip6po_flags 
&= ~IP6PO_DONTFRAG
; 
3907                         opt
->ip6po_flags 
|= IP6PO_DONTFRAG
; 
3911         case IPV6_PREFER_TEMPADDR
: 
3912                 if (len 
!= sizeof (int)) 
3914                 preftemp 
= *(int *)(void *)buf
; 
3915                 if (preftemp 
!= IP6PO_TEMPADDR_SYSTEM 
&& 
3916                     preftemp 
!= IP6PO_TEMPADDR_NOTPREFER 
&& 
3917                     preftemp 
!= IP6PO_TEMPADDR_PREFER
) { 
3920                 opt
->ip6po_prefer_tempaddr 
= preftemp
; 
3924                 return (ENOPROTOOPT
); 
3925         } /* end of switch */ 
3931  * Routine called from ip6_output() to loop back a copy of an IP6 multicast 
3932  * packet to the input queue of a specified interface.  Note that this 
3933  * calls the output routine of the loopback "driver", but with an interface 
3934  * pointer that might NOT be &loif -- easier than replicating that code here. 
3937 ip6_mloopback(struct ifnet 
*srcifp
, struct ifnet 
*origifp
, struct mbuf 
*m
, 
3938     struct sockaddr_in6 
*dst
, uint32_t optlen
, int32_t nxt0
) 
3941         struct ip6_hdr 
*ip6
; 
3942         struct in6_addr src
; 
3948          * Copy the packet header as it's needed for the checksum. 
3949          * Make sure to deep-copy IPv6 header portion in case the data 
3950          * is in an mbuf cluster, so that we can safely override the IPv6 
3951          * header portion later. 
3953         copym 
= m_copym_mode(m
, 0, M_COPYALL
, M_DONTWAIT
, M_COPYM_COPY_HDR
); 
3954         if (copym 
!= NULL 
&& ((copym
->m_flags 
& M_EXT
) || 
3955             copym
->m_len 
< sizeof (struct ip6_hdr
))) 
3956                 copym 
= m_pullup(copym
, sizeof (struct ip6_hdr
)); 
3961         ip6 
= mtod(copym
, struct ip6_hdr 
*); 
3964          * clear embedded scope identifiers if necessary. 
3965          * in6_clearscope will touch the addresses only when necessary. 
3967         in6_clearscope(&ip6
->ip6_src
); 
3968         in6_clearscope(&ip6
->ip6_dst
); 
3970         if (copym
->m_pkthdr
.csum_flags 
& CSUM_DELAY_IPV6_DATA
) 
3971                 in6_delayed_cksum_offset(copym
, 0, optlen
, nxt0
); 
3974          * Stuff the 'real' ifp into the pkthdr, to be used in matching 
3975          * in ip6_input(); we need the loopback ifp/dl_tag passed as args 
3976          * to make the loopback driver compliant with the data link 
3979         copym
->m_pkthdr
.rcvif 
= origifp
; 
3982          * Also record the source interface (which owns the source address). 
3983          * This is basically a stripped down version of ifa_foraddr6(). 
3985         if (srcifp 
== NULL
) { 
3986                 struct in6_ifaddr 
*ia
; 
3988                 lck_rw_lock_shared(&in6_ifaddr_rwlock
); 
3989                 for (ia 
= in6_ifaddrs
; ia 
!= NULL
; ia 
= ia
->ia_next
) { 
3990                         IFA_LOCK_SPIN(&ia
->ia_ifa
); 
3991                         /* compare against src addr with embedded scope */ 
3992                         if (IN6_ARE_ADDR_EQUAL(&ia
->ia_addr
.sin6_addr
, &src
)) { 
3993                                 srcifp 
= ia
->ia_ifp
; 
3994                                 IFA_UNLOCK(&ia
->ia_ifa
); 
3997                         IFA_UNLOCK(&ia
->ia_ifa
); 
3999                 lck_rw_done(&in6_ifaddr_rwlock
); 
4002                 ip6_setsrcifaddr_info(copym
, srcifp
->if_index
, NULL
); 
4003         ip6_setdstifaddr_info(copym
, origifp
->if_index
, NULL
); 
4005         dlil_output(lo_ifp
, PF_INET6
, copym
, NULL
, SA(dst
), 0, NULL
); 
4009  * Chop IPv6 header off from the payload. 
4012 ip6_splithdr(struct mbuf 
*m
, struct ip6_exthdrs 
*exthdrs
) 
4015         struct ip6_hdr 
*ip6
; 
4017         ip6 
= mtod(m
, struct ip6_hdr 
*); 
4018         if (m
->m_len 
> sizeof (*ip6
)) { 
4019                 MGETHDR(mh
, M_DONTWAIT
, MT_HEADER
);     /* MAC-OK */ 
4024                 M_COPY_PKTHDR(mh
, m
); 
4025                 MH_ALIGN(mh
, sizeof (*ip6
)); 
4026                 m
->m_flags 
&= ~M_PKTHDR
; 
4027                 m
->m_len 
-= sizeof (*ip6
); 
4028                 m
->m_data 
+= sizeof (*ip6
); 
4031                 m
->m_len 
= sizeof (*ip6
); 
4032                 bcopy((caddr_t
)ip6
, mtod(m
, caddr_t
), sizeof (*ip6
)); 
4034         exthdrs
->ip6e_ip6 
= m
; 
4039 ip6_output_checksum(struct ifnet 
*ifp
, uint32_t mtu
, struct mbuf 
*m
, 
4040     int nxt0
, uint32_t tlen
, uint32_t optlen
) 
4042         uint32_t sw_csum
, hwcap 
= ifp
->if_hwassist
; 
4043         int tso 
= TSO_IPV6_OK(ifp
, m
); 
4046                 /* do all in software; checksum offload is disabled */ 
4047                 sw_csum 
= CSUM_DELAY_IPV6_DATA 
& m
->m_pkthdr
.csum_flags
; 
4049                 /* do in software what the hardware cannot */ 
4050                 sw_csum 
= m
->m_pkthdr
.csum_flags 
& 
4051                     ~IF_HWASSIST_CSUM_FLAGS(hwcap
); 
4055                 sw_csum 
|= (CSUM_DELAY_IPV6_DATA 
& 
4056                     m
->m_pkthdr
.csum_flags
); 
4057         } else if (!(sw_csum 
& CSUM_DELAY_IPV6_DATA
) && 
4058             (hwcap 
& CSUM_PARTIAL
)) { 
4060                  * Partial checksum offload, ere), if no extension 
4061                  * headers, and TCP only (no UDP support, as the 
4062                  * hardware may not be able to convert +0 to 
4063                  * -0 (0xffff) per RFC1122 4.1.3.4.) 
4065                 if (hwcksum_tx 
&& !tso 
&& 
4066                     (m
->m_pkthdr
.csum_flags 
& CSUM_TCPIPV6
) && 
4068                         uint16_t start 
= sizeof (struct ip6_hdr
); 
4070                             m
->m_pkthdr
.csum_data 
& 0xffff; 
4071                         m
->m_pkthdr
.csum_flags 
|= 
4072                             (CSUM_DATA_VALID 
| CSUM_PARTIAL
); 
4073                         m
->m_pkthdr
.csum_tx_stuff 
= (ulpoff 
+ start
); 
4074                         m
->m_pkthdr
.csum_tx_start 
= start
; 
4077                         sw_csum 
|= (CSUM_DELAY_IPV6_DATA 
& 
4078                             m
->m_pkthdr
.csum_flags
); 
4082         if (sw_csum 
& CSUM_DELAY_IPV6_DATA
) { 
4083                 in6_delayed_cksum_offset(m
, 0, optlen
, nxt0
); 
4084                 sw_csum 
&= ~CSUM_DELAY_IPV6_DATA
; 
4089                  * Drop off bits that aren't supported by hardware; 
4090                  * also make sure to preserve non-checksum related bits. 
4092                 m
->m_pkthdr
.csum_flags 
= 
4093                     ((m
->m_pkthdr
.csum_flags 
& 
4094                     (IF_HWASSIST_CSUM_FLAGS(hwcap
) | CSUM_DATA_VALID
)) | 
4095                     (m
->m_pkthdr
.csum_flags 
& ~IF_HWASSIST_CSUM_MASK
)); 
4097                 /* drop all bits; checksum offload is disabled */ 
4098                 m
->m_pkthdr
.csum_flags 
= 0; 
4103  * Compute IPv6 extension header length. 
4106 ip6_optlen(struct in6pcb 
*in6p
) 
4110         if (!in6p
->in6p_outputopts
) 
4115         (((struct ip6_ext *)(x)) ?                                      \ 
4116         (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0) 
4118         len 
+= elen(in6p
->in6p_outputopts
->ip6po_hbh
); 
4119         if (in6p
->in6p_outputopts
->ip6po_rthdr
) { 
4120                 /* dest1 is valid with rthdr only */ 
4121                 len 
+= elen(in6p
->in6p_outputopts
->ip6po_dest1
); 
4123         len 
+= elen(in6p
->in6p_outputopts
->ip6po_rthdr
); 
4124         len 
+= elen(in6p
->in6p_outputopts
->ip6po_dest2
); 
4130 sysctl_reset_ip6_output_stats SYSCTL_HANDLER_ARGS
 
4132 #pragma unused(arg1, arg2) 
4135         i 
= ip6_output_measure
; 
4136         error 
= sysctl_handle_int(oidp
, &i
, 0, req
); 
4137         if (error 
|| req
->newptr 
== USER_ADDR_NULL
) 
4140         if (i 
< 0 || i 
> 1) { 
4144         if (ip6_output_measure 
!= i 
&& i 
== 1) { 
4145                 net_perf_initialize(&net_perf
, ip6_output_measure_bins
); 
4147         ip6_output_measure 
= i
; 
4153 sysctl_ip6_output_measure_bins SYSCTL_HANDLER_ARGS
 
4155 #pragma unused(arg1, arg2) 
4159         i 
= ip6_output_measure_bins
; 
4160         error 
= sysctl_handle_quad(oidp
, &i
, 0, req
); 
4161         if (error 
|| req
->newptr 
== USER_ADDR_NULL
) 
4164         if (!net_perf_validate_bins(i
)) { 
4168         ip6_output_measure_bins 
= i
; 
4174 sysctl_ip6_output_getperf SYSCTL_HANDLER_ARGS
 
4176 #pragma unused(oidp, arg1, arg2) 
4177         if (req
->oldptr 
== USER_ADDR_NULL
) 
4178                 req
->oldlen 
= (size_t)sizeof (struct ipstat
); 
4180         return (SYSCTL_OUT(req
, &net_perf
, MIN(sizeof (net_perf
), req
->oldlen
)));