Wed Mar 10 22:28:27 2021 UTC ()
byte-flipping a random number is not very useful.


(christos)
diff -r1.226 -r1.227 src/sys/netinet6/ip6_output.c

cvs diff -r1.226 -r1.227 src/sys/netinet6/ip6_output.c (switch to unified diff)

--- src/sys/netinet6/ip6_output.c 2020/09/08 14:12:57 1.226
+++ src/sys/netinet6/ip6_output.c 2021/03/10 22:28:26 1.227
@@ -1,1891 +1,1891 @@ @@ -1,1891 +1,1891 @@
1/* $NetBSD: ip6_output.c,v 1.226 2020/09/08 14:12:57 christos Exp $ */ 1/* $NetBSD: ip6_output.c,v 1.227 2021/03/10 22:28:26 christos Exp $ */
2/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ 2/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors 16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1982, 1986, 1988, 1990, 1993 34 * Copyright (c) 1982, 1986, 1988, 1990, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors 45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software 46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission. 47 * without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 61 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.226 2020/09/08 14:12:57 christos Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.227 2021/03/10 22:28:26 christos Exp $");
66 66
67#ifdef _KERNEL_OPT 67#ifdef _KERNEL_OPT
68#include "opt_inet.h" 68#include "opt_inet.h"
69#include "opt_inet6.h" 69#include "opt_inet6.h"
70#include "opt_ipsec.h" 70#include "opt_ipsec.h"
71#endif 71#endif
72 72
73#include <sys/param.h> 73#include <sys/param.h>
74#include <sys/malloc.h> 74#include <sys/malloc.h>
75#include <sys/mbuf.h> 75#include <sys/mbuf.h>
76#include <sys/errno.h> 76#include <sys/errno.h>
77#include <sys/socket.h> 77#include <sys/socket.h>
78#include <sys/socketvar.h> 78#include <sys/socketvar.h>
79#include <sys/syslog.h> 79#include <sys/syslog.h>
80#include <sys/systm.h> 80#include <sys/systm.h>
81#include <sys/proc.h> 81#include <sys/proc.h>
82#include <sys/kauth.h> 82#include <sys/kauth.h>
83 83
84#include <net/if.h> 84#include <net/if.h>
85#include <net/route.h> 85#include <net/route.h>
86#include <net/pfil.h> 86#include <net/pfil.h>
87 87
88#include <netinet/in.h> 88#include <netinet/in.h>
89#include <netinet/in_var.h> 89#include <netinet/in_var.h>
90#include <netinet/ip6.h> 90#include <netinet/ip6.h>
91#include <netinet/ip_var.h> 91#include <netinet/ip_var.h>
92#include <netinet/icmp6.h> 92#include <netinet/icmp6.h>
93#include <netinet/in_offload.h> 93#include <netinet/in_offload.h>
94#include <netinet/portalgo.h> 94#include <netinet/portalgo.h>
95#include <netinet6/in6_offload.h> 95#include <netinet6/in6_offload.h>
96#include <netinet6/ip6_var.h> 96#include <netinet6/ip6_var.h>
97#include <netinet6/ip6_private.h> 97#include <netinet6/ip6_private.h>
98#include <netinet6/in6_pcb.h> 98#include <netinet6/in6_pcb.h>
99#include <netinet6/nd6.h> 99#include <netinet6/nd6.h>
100#include <netinet6/ip6protosw.h> 100#include <netinet6/ip6protosw.h>
101#include <netinet6/scope6_var.h> 101#include <netinet6/scope6_var.h>
102 102
103#ifdef IPSEC 103#ifdef IPSEC
104#include <netipsec/ipsec.h> 104#include <netipsec/ipsec.h>
105#include <netipsec/ipsec6.h> 105#include <netipsec/ipsec6.h>
106#include <netipsec/key.h> 106#include <netipsec/key.h>
107#endif 107#endif
108 108
109extern pfil_head_t *inet6_pfil_hook; /* XXX */ 109extern pfil_head_t *inet6_pfil_hook; /* XXX */
110 110
111struct ip6_exthdrs { 111struct ip6_exthdrs {
112 struct mbuf *ip6e_ip6; 112 struct mbuf *ip6e_ip6;
113 struct mbuf *ip6e_hbh; 113 struct mbuf *ip6e_hbh;
114 struct mbuf *ip6e_dest1; 114 struct mbuf *ip6e_dest1;
115 struct mbuf *ip6e_rthdr; 115 struct mbuf *ip6e_rthdr;
116 struct mbuf *ip6e_dest2; 116 struct mbuf *ip6e_dest2;
117}; 117};
118 118
119static int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **, 119static int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **,
120 kauth_cred_t, int); 120 kauth_cred_t, int);
121static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *); 121static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *);
122static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, kauth_cred_t, 122static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, kauth_cred_t,
123 int, int, int); 123 int, int, int);
124static int ip6_setmoptions(const struct sockopt *, struct in6pcb *); 124static int ip6_setmoptions(const struct sockopt *, struct in6pcb *);
125static int ip6_getmoptions(struct sockopt *, struct in6pcb *); 125static int ip6_getmoptions(struct sockopt *, struct in6pcb *);
126static int ip6_copyexthdr(struct mbuf **, void *, int); 126static int ip6_copyexthdr(struct mbuf **, void *, int);
127static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int, 127static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int,
128 struct ip6_frag **); 128 struct ip6_frag **);
129static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t); 129static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t);
130static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *); 130static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *);
131static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *); 131static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *);
132static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); 132static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
133static int ip6_ifaddrvalid(const struct in6_addr *, const struct in6_addr *); 133static int ip6_ifaddrvalid(const struct in6_addr *, const struct in6_addr *);
134static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *); 134static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *);
135 135
136#ifdef RFC2292 136#ifdef RFC2292
137static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *); 137static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *);
138#endif 138#endif
139 139
140static int 140static int
141ip6_handle_rthdr(struct ip6_rthdr *rh, struct ip6_hdr *ip6) 141ip6_handle_rthdr(struct ip6_rthdr *rh, struct ip6_hdr *ip6)
142{ 142{
143 int error = 0; 143 int error = 0;
144 144
145 switch (rh->ip6r_type) { 145 switch (rh->ip6r_type) {
146 case IPV6_RTHDR_TYPE_0: 146 case IPV6_RTHDR_TYPE_0:
147 /* Dropped, RFC5095. */ 147 /* Dropped, RFC5095. */
148 default: /* is it possible? */ 148 default: /* is it possible? */
149 error = EINVAL; 149 error = EINVAL;
150 } 150 }
151 151
152 return error; 152 return error;
153} 153}
154 154
155/* 155/*
156 * Send an IP packet to a host. 156 * Send an IP packet to a host.
157 */ 157 */
158int 158int
159ip6_if_output(struct ifnet * const ifp, struct ifnet * const origifp, 159ip6_if_output(struct ifnet * const ifp, struct ifnet * const origifp,
160 struct mbuf * const m, const struct sockaddr_in6 * const dst, 160 struct mbuf * const m, const struct sockaddr_in6 * const dst,
161 const struct rtentry *rt) 161 const struct rtentry *rt)
162{ 162{
163 int error = 0; 163 int error = 0;
164 164
165 if (rt != NULL) { 165 if (rt != NULL) {
166 error = rt_check_reject_route(rt, ifp); 166 error = rt_check_reject_route(rt, ifp);
167 if (error != 0) { 167 if (error != 0) {
168 IP6_STATINC(IP6_STAT_RTREJECT); 168 IP6_STATINC(IP6_STAT_RTREJECT);
169 m_freem(m); 169 m_freem(m);
170 return error; 170 return error;
171 } 171 }
172 } 172 }
173 173
174 if ((ifp->if_flags & IFF_LOOPBACK) != 0) 174 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
175 error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt); 175 error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt);
176 else 176 else
177 error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt); 177 error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt);
178 return error; 178 return error;
179} 179}
180 180
181/* 181/*
182 * IP6 output. The packet in mbuf chain m contains a skeletal IP6 182 * IP6 output. The packet in mbuf chain m contains a skeletal IP6
183 * header (with pri, len, nxt, hlim, src, dst). 183 * header (with pri, len, nxt, hlim, src, dst).
184 * 184 *
185 * This function may modify ver and hlim only. The mbuf chain containing the 185 * This function may modify ver and hlim only. The mbuf chain containing the
186 * packet will be freed. The mbuf opt, if present, will not be freed. 186 * packet will be freed. The mbuf opt, if present, will not be freed.
187 * 187 *
188 * Type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and 188 * Type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and
189 * nd_ifinfo.linkmtu is u_int32_t. So we use u_long to hold largest one, 189 * nd_ifinfo.linkmtu is u_int32_t. So we use u_long to hold largest one,
190 * which is rt_rmx.rmx_mtu. 190 * which is rt_rmx.rmx_mtu.
191 */ 191 */
192int 192int
193ip6_output( 193ip6_output(
194 struct mbuf *m0, 194 struct mbuf *m0,
195 struct ip6_pktopts *opt, 195 struct ip6_pktopts *opt,
196 struct route *ro, 196 struct route *ro,
197 int flags, 197 int flags,
198 struct ip6_moptions *im6o, 198 struct ip6_moptions *im6o,
199 struct in6pcb *in6p, 199 struct in6pcb *in6p,
200 struct ifnet **ifpp /* XXX: just for statistics */ 200 struct ifnet **ifpp /* XXX: just for statistics */
201) 201)
202{ 202{
203 struct ip6_hdr *ip6, *mhip6; 203 struct ip6_hdr *ip6, *mhip6;
204 struct ifnet *ifp = NULL, *origifp = NULL; 204 struct ifnet *ifp = NULL, *origifp = NULL;
205 struct mbuf *m = m0; 205 struct mbuf *m = m0;
206 int tlen, len, off; 206 int tlen, len, off;
207 bool tso; 207 bool tso;
208 struct route ip6route; 208 struct route ip6route;
209 struct rtentry *rt = NULL, *rt_pmtu; 209 struct rtentry *rt = NULL, *rt_pmtu;
210 const struct sockaddr_in6 *dst; 210 const struct sockaddr_in6 *dst;
211 struct sockaddr_in6 src_sa, dst_sa; 211 struct sockaddr_in6 src_sa, dst_sa;
212 int error = 0; 212 int error = 0;
213 struct in6_ifaddr *ia = NULL; 213 struct in6_ifaddr *ia = NULL;
214 u_long mtu; 214 u_long mtu;
215 int alwaysfrag, dontfrag; 215 int alwaysfrag, dontfrag;
216 u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; 216 u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
217 struct ip6_exthdrs exthdrs; 217 struct ip6_exthdrs exthdrs;
218 struct in6_addr finaldst, src0, dst0; 218 struct in6_addr finaldst, src0, dst0;
219 u_int32_t zone; 219 u_int32_t zone;
220 struct route *ro_pmtu = NULL; 220 struct route *ro_pmtu = NULL;
221 int hdrsplit = 0; 221 int hdrsplit = 0;
222 int needipsec = 0; 222 int needipsec = 0;
223#ifdef IPSEC 223#ifdef IPSEC
224 struct secpolicy *sp = NULL; 224 struct secpolicy *sp = NULL;
225#endif 225#endif
226 struct psref psref, psref_ia; 226 struct psref psref, psref_ia;
227 int bound = curlwp_bind(); 227 int bound = curlwp_bind();
228 bool release_psref_ia = false; 228 bool release_psref_ia = false;
229 229
230#ifdef DIAGNOSTIC 230#ifdef DIAGNOSTIC
231 if ((m->m_flags & M_PKTHDR) == 0) 231 if ((m->m_flags & M_PKTHDR) == 0)
232 panic("ip6_output: no HDR"); 232 panic("ip6_output: no HDR");
233 if ((m->m_pkthdr.csum_flags & 233 if ((m->m_pkthdr.csum_flags &
234 (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) != 0) { 234 (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) != 0) {
235 panic("ip6_output: IPv4 checksum offload flags: %d", 235 panic("ip6_output: IPv4 checksum offload flags: %d",
236 m->m_pkthdr.csum_flags); 236 m->m_pkthdr.csum_flags);
237 } 237 }
238 if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) == 238 if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) ==
239 (M_CSUM_TCPv6|M_CSUM_UDPv6)) { 239 (M_CSUM_TCPv6|M_CSUM_UDPv6)) {
240 panic("ip6_output: conflicting checksum offload flags: %d", 240 panic("ip6_output: conflicting checksum offload flags: %d",
241 m->m_pkthdr.csum_flags); 241 m->m_pkthdr.csum_flags);
242 } 242 }
243#endif 243#endif
244 244
245 M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data, sizeof(struct ip6_hdr)); 245 M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data, sizeof(struct ip6_hdr));
246 246
247#define MAKE_EXTHDR(hp, mp) \ 247#define MAKE_EXTHDR(hp, mp) \
248 do { \ 248 do { \
249 if (hp) { \ 249 if (hp) { \
250 struct ip6_ext *eh = (struct ip6_ext *)(hp); \ 250 struct ip6_ext *eh = (struct ip6_ext *)(hp); \
251 error = ip6_copyexthdr((mp), (void *)(hp), \ 251 error = ip6_copyexthdr((mp), (void *)(hp), \
252 ((eh)->ip6e_len + 1) << 3); \ 252 ((eh)->ip6e_len + 1) << 3); \
253 if (error) \ 253 if (error) \
254 goto freehdrs; \ 254 goto freehdrs; \
255 } \ 255 } \
256 } while (/*CONSTCOND*/ 0) 256 } while (/*CONSTCOND*/ 0)
257 257
258 memset(&exthdrs, 0, sizeof(exthdrs)); 258 memset(&exthdrs, 0, sizeof(exthdrs));
259 if (opt) { 259 if (opt) {
260 /* Hop-by-Hop options header */ 260 /* Hop-by-Hop options header */
261 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh); 261 MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh);
262 /* Destination options header (1st part) */ 262 /* Destination options header (1st part) */
263 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1); 263 MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
264 /* Routing header */ 264 /* Routing header */
265 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr); 265 MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr);
266 /* Destination options header (2nd part) */ 266 /* Destination options header (2nd part) */
267 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2); 267 MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2);
268 } 268 }
269 269
270 /* 270 /*
271 * Calculate the total length of the extension header chain. 271 * Calculate the total length of the extension header chain.
272 * Keep the length of the unfragmentable part for fragmentation. 272 * Keep the length of the unfragmentable part for fragmentation.
273 */ 273 */
274 optlen = 0; 274 optlen = 0;
275 if (exthdrs.ip6e_hbh) 275 if (exthdrs.ip6e_hbh)
276 optlen += exthdrs.ip6e_hbh->m_len; 276 optlen += exthdrs.ip6e_hbh->m_len;
277 if (exthdrs.ip6e_dest1) 277 if (exthdrs.ip6e_dest1)
278 optlen += exthdrs.ip6e_dest1->m_len; 278 optlen += exthdrs.ip6e_dest1->m_len;
279 if (exthdrs.ip6e_rthdr) 279 if (exthdrs.ip6e_rthdr)
280 optlen += exthdrs.ip6e_rthdr->m_len; 280 optlen += exthdrs.ip6e_rthdr->m_len;
281 unfragpartlen = optlen + sizeof(struct ip6_hdr); 281 unfragpartlen = optlen + sizeof(struct ip6_hdr);
282 /* NOTE: we don't add AH/ESP length here. do that later. */ 282 /* NOTE: we don't add AH/ESP length here. do that later. */
283 if (exthdrs.ip6e_dest2) 283 if (exthdrs.ip6e_dest2)
284 optlen += exthdrs.ip6e_dest2->m_len; 284 optlen += exthdrs.ip6e_dest2->m_len;
285 285
286#ifdef IPSEC 286#ifdef IPSEC
287 if (ipsec_used) { 287 if (ipsec_used) {
288 /* Check the security policy (SP) for the packet */ 288 /* Check the security policy (SP) for the packet */
289 sp = ipsec6_check_policy(m, in6p, flags, &needipsec, &error); 289 sp = ipsec6_check_policy(m, in6p, flags, &needipsec, &error);
290 if (error != 0) { 290 if (error != 0) {
291 /* 291 /*
292 * Hack: -EINVAL is used to signal that a packet 292 * Hack: -EINVAL is used to signal that a packet
293 * should be silently discarded. This is typically 293 * should be silently discarded. This is typically
294 * because we asked key management for an SA and 294 * because we asked key management for an SA and
295 * it was delayed (e.g. kicked up to IKE). 295 * it was delayed (e.g. kicked up to IKE).
296 */ 296 */
297 if (error == -EINVAL) 297 if (error == -EINVAL)
298 error = 0; 298 error = 0;
299 IP6_STATINC(IP6_STAT_IPSECDROP_OUT); 299 IP6_STATINC(IP6_STAT_IPSECDROP_OUT);
300 goto freehdrs; 300 goto freehdrs;
301 } 301 }
302 } 302 }
303#endif 303#endif
304 304
305 if (needipsec && 305 if (needipsec &&
306 (m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { 306 (m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) {
307 in6_undefer_cksum_tcpudp(m); 307 in6_undefer_cksum_tcpudp(m);
308 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 308 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
309 } 309 }
310 310
311 /* 311 /*
312 * If we need IPsec, or there is at least one extension header, 312 * If we need IPsec, or there is at least one extension header,
313 * separate IP6 header from the payload. 313 * separate IP6 header from the payload.
314 */ 314 */
315 if ((needipsec || optlen) && !hdrsplit) { 315 if ((needipsec || optlen) && !hdrsplit) {
316 if ((error = ip6_splithdr(m, &exthdrs)) != 0) { 316 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
317 IP6_STATINC(IP6_STAT_ODROPPED); 317 IP6_STATINC(IP6_STAT_ODROPPED);
318 m = NULL; 318 m = NULL;
319 goto freehdrs; 319 goto freehdrs;
320 } 320 }
321 m = exthdrs.ip6e_ip6; 321 m = exthdrs.ip6e_ip6;
322 hdrsplit++; 322 hdrsplit++;
323 } 323 }
324 324
325 /* adjust pointer */ 325 /* adjust pointer */
326 ip6 = mtod(m, struct ip6_hdr *); 326 ip6 = mtod(m, struct ip6_hdr *);
327 327
328 /* adjust mbuf packet header length */ 328 /* adjust mbuf packet header length */
329 m->m_pkthdr.len += optlen; 329 m->m_pkthdr.len += optlen;
330 plen = m->m_pkthdr.len - sizeof(*ip6); 330 plen = m->m_pkthdr.len - sizeof(*ip6);
331 331
332 /* If this is a jumbo payload, insert a jumbo payload option. */ 332 /* If this is a jumbo payload, insert a jumbo payload option. */
333 if (plen > IPV6_MAXPACKET) { 333 if (plen > IPV6_MAXPACKET) {
334 if (!hdrsplit) { 334 if (!hdrsplit) {
335 if ((error = ip6_splithdr(m, &exthdrs)) != 0) { 335 if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
336 IP6_STATINC(IP6_STAT_ODROPPED); 336 IP6_STATINC(IP6_STAT_ODROPPED);
337 m = NULL; 337 m = NULL;
338 goto freehdrs; 338 goto freehdrs;
339 } 339 }
340 m = exthdrs.ip6e_ip6; 340 m = exthdrs.ip6e_ip6;
341 hdrsplit++; 341 hdrsplit++;
342 } 342 }
343 /* adjust pointer */ 343 /* adjust pointer */
344 ip6 = mtod(m, struct ip6_hdr *); 344 ip6 = mtod(m, struct ip6_hdr *);
345 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0) { 345 if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0) {
346 IP6_STATINC(IP6_STAT_ODROPPED); 346 IP6_STATINC(IP6_STAT_ODROPPED);
347 goto freehdrs; 347 goto freehdrs;
348 } 348 }
349 optlen += 8; /* XXX JUMBOOPTLEN */ 349 optlen += 8; /* XXX JUMBOOPTLEN */
350 ip6->ip6_plen = 0; 350 ip6->ip6_plen = 0;
351 } else 351 } else
352 ip6->ip6_plen = htons(plen); 352 ip6->ip6_plen = htons(plen);
353 353
354 /* 354 /*
355 * Concatenate headers and fill in next header fields. 355 * Concatenate headers and fill in next header fields.
356 * Here we have, on "m" 356 * Here we have, on "m"
357 * IPv6 payload 357 * IPv6 payload
358 * and we insert headers accordingly. Finally, we should be getting: 358 * and we insert headers accordingly. Finally, we should be getting:
359 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload] 359 * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]
360 * 360 *
361 * during the header composing process, "m" points to IPv6 header. 361 * during the header composing process, "m" points to IPv6 header.
362 * "mprev" points to an extension header prior to esp. 362 * "mprev" points to an extension header prior to esp.
363 */ 363 */
364 { 364 {
365 u_char *nexthdrp = &ip6->ip6_nxt; 365 u_char *nexthdrp = &ip6->ip6_nxt;
366 struct mbuf *mprev = m; 366 struct mbuf *mprev = m;
367 367
368 /* 368 /*
369 * we treat dest2 specially. this makes IPsec processing 369 * we treat dest2 specially. this makes IPsec processing
370 * much easier. the goal here is to make mprev point the 370 * much easier. the goal here is to make mprev point the
371 * mbuf prior to dest2. 371 * mbuf prior to dest2.
372 * 372 *
373 * result: IPv6 dest2 payload 373 * result: IPv6 dest2 payload
374 * m and mprev will point to IPv6 header. 374 * m and mprev will point to IPv6 header.
375 */ 375 */
376 if (exthdrs.ip6e_dest2) { 376 if (exthdrs.ip6e_dest2) {
377 if (!hdrsplit) 377 if (!hdrsplit)
378 panic("assumption failed: hdr not split"); 378 panic("assumption failed: hdr not split");
379 exthdrs.ip6e_dest2->m_next = m->m_next; 379 exthdrs.ip6e_dest2->m_next = m->m_next;
380 m->m_next = exthdrs.ip6e_dest2; 380 m->m_next = exthdrs.ip6e_dest2;
381 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt; 381 *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
382 ip6->ip6_nxt = IPPROTO_DSTOPTS; 382 ip6->ip6_nxt = IPPROTO_DSTOPTS;
383 } 383 }
384 384
385#define MAKE_CHAIN(m, mp, p, i)\ 385#define MAKE_CHAIN(m, mp, p, i)\
386 do {\ 386 do {\
387 if (m) {\ 387 if (m) {\
388 if (!hdrsplit) \ 388 if (!hdrsplit) \
389 panic("assumption failed: hdr not split"); \ 389 panic("assumption failed: hdr not split"); \
390 *mtod((m), u_char *) = *(p);\ 390 *mtod((m), u_char *) = *(p);\
391 *(p) = (i);\ 391 *(p) = (i);\
392 p = mtod((m), u_char *);\ 392 p = mtod((m), u_char *);\
393 (m)->m_next = (mp)->m_next;\ 393 (m)->m_next = (mp)->m_next;\
394 (mp)->m_next = (m);\ 394 (mp)->m_next = (m);\
395 (mp) = (m);\ 395 (mp) = (m);\
396 }\ 396 }\
397 } while (/*CONSTCOND*/ 0) 397 } while (/*CONSTCOND*/ 0)
398 /* 398 /*
399 * result: IPv6 hbh dest1 rthdr dest2 payload 399 * result: IPv6 hbh dest1 rthdr dest2 payload
400 * m will point to IPv6 header. mprev will point to the 400 * m will point to IPv6 header. mprev will point to the
401 * extension header prior to dest2 (rthdr in the above case). 401 * extension header prior to dest2 (rthdr in the above case).
402 */ 402 */
403 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS); 403 MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
404 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp, 404 MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
405 IPPROTO_DSTOPTS); 405 IPPROTO_DSTOPTS);
406 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp, 406 MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
407 IPPROTO_ROUTING); 407 IPPROTO_ROUTING);
408 408
409 M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data, 409 M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data,
410 sizeof(struct ip6_hdr) + optlen); 410 sizeof(struct ip6_hdr) + optlen);
411 } 411 }
412 412
413 /* Need to save for pmtu */ 413 /* Need to save for pmtu */
414 finaldst = ip6->ip6_dst; 414 finaldst = ip6->ip6_dst;
415 415
416 /* 416 /*
417 * If there is a routing header, replace destination address field 417 * If there is a routing header, replace destination address field
418 * with the first hop of the routing header. 418 * with the first hop of the routing header.
419 */ 419 */
420 if (exthdrs.ip6e_rthdr) { 420 if (exthdrs.ip6e_rthdr) {
421 struct ip6_rthdr *rh; 421 struct ip6_rthdr *rh;
422 422
423 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *); 423 rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *);
424 424
425 error = ip6_handle_rthdr(rh, ip6); 425 error = ip6_handle_rthdr(rh, ip6);
426 if (error != 0) { 426 if (error != 0) {
427 IP6_STATINC(IP6_STAT_ODROPPED); 427 IP6_STATINC(IP6_STAT_ODROPPED);
428 goto bad; 428 goto bad;
429 } 429 }
430 } 430 }
431 431
432 /* Source address validation */ 432 /* Source address validation */
433 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && 433 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
434 (flags & IPV6_UNSPECSRC) == 0) { 434 (flags & IPV6_UNSPECSRC) == 0) {
435 error = EOPNOTSUPP; 435 error = EOPNOTSUPP;
436 IP6_STATINC(IP6_STAT_BADSCOPE); 436 IP6_STATINC(IP6_STAT_BADSCOPE);
437 goto bad; 437 goto bad;
438 } 438 }
439 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { 439 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
440 error = EOPNOTSUPP; 440 error = EOPNOTSUPP;
441 IP6_STATINC(IP6_STAT_BADSCOPE); 441 IP6_STATINC(IP6_STAT_BADSCOPE);
442 goto bad; 442 goto bad;
443 } 443 }
444 444
445 IP6_STATINC(IP6_STAT_LOCALOUT); 445 IP6_STATINC(IP6_STAT_LOCALOUT);
446 446
447 /* 447 /*
448 * Route packet. 448 * Route packet.
449 */ 449 */
450 /* initialize cached route */ 450 /* initialize cached route */
451 if (ro == NULL) { 451 if (ro == NULL) {
452 memset(&ip6route, 0, sizeof(ip6route)); 452 memset(&ip6route, 0, sizeof(ip6route));
453 ro = &ip6route; 453 ro = &ip6route;
454 } 454 }
455 ro_pmtu = ro; 455 ro_pmtu = ro;
456 if (opt && opt->ip6po_rthdr) 456 if (opt && opt->ip6po_rthdr)
457 ro = &opt->ip6po_route; 457 ro = &opt->ip6po_route;
458 458
459 /* 459 /*
460 * if specified, try to fill in the traffic class field. 460 * if specified, try to fill in the traffic class field.
461 * do not override if a non-zero value is already set. 461 * do not override if a non-zero value is already set.
462 * we check the diffserv field and the ecn field separately. 462 * we check the diffserv field and the ecn field separately.
463 */ 463 */
464 if (opt && opt->ip6po_tclass >= 0) { 464 if (opt && opt->ip6po_tclass >= 0) {
465 int mask = 0; 465 int mask = 0;
466 466
467 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0) 467 if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0)
468 mask |= 0xfc; 468 mask |= 0xfc;
469 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0) 469 if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0)
470 mask |= 0x03; 470 mask |= 0x03;
471 if (mask != 0) 471 if (mask != 0)
472 ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20); 472 ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20);
473 } 473 }
474 474
475 /* fill in or override the hop limit field, if necessary. */ 475 /* fill in or override the hop limit field, if necessary. */
476 if (opt && opt->ip6po_hlim != -1) 476 if (opt && opt->ip6po_hlim != -1)
477 ip6->ip6_hlim = opt->ip6po_hlim & 0xff; 477 ip6->ip6_hlim = opt->ip6po_hlim & 0xff;
478 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 478 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
479 if (im6o != NULL) 479 if (im6o != NULL)
480 ip6->ip6_hlim = im6o->im6o_multicast_hlim; 480 ip6->ip6_hlim = im6o->im6o_multicast_hlim;
481 else 481 else
482 ip6->ip6_hlim = ip6_defmcasthlim; 482 ip6->ip6_hlim = ip6_defmcasthlim;
483 } 483 }
484 484
485#ifdef IPSEC 485#ifdef IPSEC
486 if (needipsec) { 486 if (needipsec) {
487 int s = splsoftnet(); 487 int s = splsoftnet();
488 error = ipsec6_process_packet(m, sp->req, flags); 488 error = ipsec6_process_packet(m, sp->req, flags);
489 splx(s); 489 splx(s);
490 490
491 /* 491 /*
492 * Preserve KAME behaviour: ENOENT can be returned 492 * Preserve KAME behaviour: ENOENT can be returned
493 * when an SA acquire is in progress. Don't propagate 493 * when an SA acquire is in progress. Don't propagate
494 * this to user-level; it confuses applications. 494 * this to user-level; it confuses applications.
495 * XXX this will go away when the SADB is redone. 495 * XXX this will go away when the SADB is redone.
496 */ 496 */
497 if (error == ENOENT) 497 if (error == ENOENT)
498 error = 0; 498 error = 0;
499 499
500 goto done; 500 goto done;
501 } 501 }
502#endif 502#endif
503 503
504 /* adjust pointer */ 504 /* adjust pointer */
505 ip6 = mtod(m, struct ip6_hdr *); 505 ip6 = mtod(m, struct ip6_hdr *);
506 506
507 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0); 507 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
508 508
509 /* We do not need a route for multicast */ 509 /* We do not need a route for multicast */
510 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 510 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
511 struct in6_pktinfo *pi = NULL; 511 struct in6_pktinfo *pi = NULL;
512 512
513 /* 513 /*
514 * If the outgoing interface for the address is specified by 514 * If the outgoing interface for the address is specified by
515 * the caller, use it. 515 * the caller, use it.
516 */ 516 */
517 if (opt && (pi = opt->ip6po_pktinfo) != NULL) { 517 if (opt && (pi = opt->ip6po_pktinfo) != NULL) {
518 /* XXX boundary check is assumed to be already done. */ 518 /* XXX boundary check is assumed to be already done. */
519 ifp = if_get_byindex(pi->ipi6_ifindex, &psref); 519 ifp = if_get_byindex(pi->ipi6_ifindex, &psref);
520 } else if (im6o != NULL) { 520 } else if (im6o != NULL) {
521 ifp = if_get_byindex(im6o->im6o_multicast_if_index, 521 ifp = if_get_byindex(im6o->im6o_multicast_if_index,
522 &psref); 522 &psref);
523 } 523 }
524 } 524 }
525 525
526 if (ifp == NULL) { 526 if (ifp == NULL) {
527 error = in6_selectroute(&dst_sa, opt, &ro, &rt, true); 527 error = in6_selectroute(&dst_sa, opt, &ro, &rt, true);
528 if (error != 0) 528 if (error != 0)
529 goto bad; 529 goto bad;
530 ifp = if_get_byindex(rt->rt_ifp->if_index, &psref); 530 ifp = if_get_byindex(rt->rt_ifp->if_index, &psref);
531 } 531 }
532 532
533 if (rt == NULL) { 533 if (rt == NULL) {
534 /* 534 /*
535 * If in6_selectroute() does not return a route entry, 535 * If in6_selectroute() does not return a route entry,
536 * dst may not have been updated. 536 * dst may not have been updated.
537 */ 537 */
538 error = rtcache_setdst(ro, sin6tosa(&dst_sa)); 538 error = rtcache_setdst(ro, sin6tosa(&dst_sa));
539 if (error) { 539 if (error) {
540 IP6_STATINC(IP6_STAT_ODROPPED); 540 IP6_STATINC(IP6_STAT_ODROPPED);
541 goto bad; 541 goto bad;
542 } 542 }
543 } 543 }
544 544
545 /* 545 /*
546 * then rt (for unicast) and ifp must be non-NULL valid values. 546 * then rt (for unicast) and ifp must be non-NULL valid values.
547 */ 547 */
548 if ((flags & IPV6_FORWARDING) == 0) { 548 if ((flags & IPV6_FORWARDING) == 0) {
549 /* XXX: the FORWARDING flag can be set for mrouting. */ 549 /* XXX: the FORWARDING flag can be set for mrouting. */
550 in6_ifstat_inc(ifp, ifs6_out_request); 550 in6_ifstat_inc(ifp, ifs6_out_request);
551 } 551 }
552 if (rt != NULL) { 552 if (rt != NULL) {
553 ia = (struct in6_ifaddr *)(rt->rt_ifa); 553 ia = (struct in6_ifaddr *)(rt->rt_ifa);
554 rt->rt_use++; 554 rt->rt_use++;
555 } 555 }
556 556
557 /* 557 /*
558 * The outgoing interface must be in the zone of source and 558 * The outgoing interface must be in the zone of source and
559 * destination addresses. We should use ia_ifp to support the 559 * destination addresses. We should use ia_ifp to support the
560 * case of sending packets to an address of our own. 560 * case of sending packets to an address of our own.
561 */ 561 */
562 if (ia != NULL) { 562 if (ia != NULL) {
563 origifp = ia->ia_ifp; 563 origifp = ia->ia_ifp;
564 if (if_is_deactivated(origifp)) { 564 if (if_is_deactivated(origifp)) {
565 IP6_STATINC(IP6_STAT_ODROPPED); 565 IP6_STATINC(IP6_STAT_ODROPPED);
566 goto bad; 566 goto bad;
567 } 567 }
568 if_acquire(origifp, &psref_ia); 568 if_acquire(origifp, &psref_ia);
569 release_psref_ia = true; 569 release_psref_ia = true;
570 } else 570 } else
571 origifp = ifp; 571 origifp = ifp;
572 572
573 src0 = ip6->ip6_src; 573 src0 = ip6->ip6_src;
574 if (in6_setscope(&src0, origifp, &zone)) 574 if (in6_setscope(&src0, origifp, &zone))
575 goto badscope; 575 goto badscope;
576 sockaddr_in6_init(&src_sa, &ip6->ip6_src, 0, 0, 0); 576 sockaddr_in6_init(&src_sa, &ip6->ip6_src, 0, 0, 0);
577 if (sa6_recoverscope(&src_sa) || zone != src_sa.sin6_scope_id) 577 if (sa6_recoverscope(&src_sa) || zone != src_sa.sin6_scope_id)
578 goto badscope; 578 goto badscope;
579 579
580 dst0 = ip6->ip6_dst; 580 dst0 = ip6->ip6_dst;
581 if (in6_setscope(&dst0, origifp, &zone)) 581 if (in6_setscope(&dst0, origifp, &zone))
582 goto badscope; 582 goto badscope;
583 /* re-initialize to be sure */ 583 /* re-initialize to be sure */
584 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0); 584 sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0);
585 if (sa6_recoverscope(&dst_sa) || zone != dst_sa.sin6_scope_id) 585 if (sa6_recoverscope(&dst_sa) || zone != dst_sa.sin6_scope_id)
586 goto badscope; 586 goto badscope;
587 587
588 /* scope check is done. */ 588 /* scope check is done. */
589 589
590 /* Ensure we only send from a valid address. */ 590 /* Ensure we only send from a valid address. */
591 if ((ifp->if_flags & IFF_LOOPBACK) == 0 && 591 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
592 (flags & IPV6_FORWARDING) == 0 && 592 (flags & IPV6_FORWARDING) == 0 &&
593 (error = ip6_ifaddrvalid(&src0, &dst0)) != 0) 593 (error = ip6_ifaddrvalid(&src0, &dst0)) != 0)
594 { 594 {
595 char ip6buf[INET6_ADDRSTRLEN]; 595 char ip6buf[INET6_ADDRSTRLEN];
596 nd6log(LOG_ERR, 596 nd6log(LOG_ERR,
597 "refusing to send from invalid address %s (pid %d)\n", 597 "refusing to send from invalid address %s (pid %d)\n",
598 IN6_PRINT(ip6buf, &src0), curproc->p_pid); 598 IN6_PRINT(ip6buf, &src0), curproc->p_pid);
599 IP6_STATINC(IP6_STAT_ODROPPED); 599 IP6_STATINC(IP6_STAT_ODROPPED);
600 in6_ifstat_inc(origifp, ifs6_out_discard); 600 in6_ifstat_inc(origifp, ifs6_out_discard);
601 if (error == 1) 601 if (error == 1)
602 /* 602 /*
603 * Address exists, but is tentative or detached. 603 * Address exists, but is tentative or detached.
604 * We can't send from it because it's invalid, 604 * We can't send from it because it's invalid,
605 * so we drop the packet. 605 * so we drop the packet.
606 */ 606 */
607 error = 0; 607 error = 0;
608 else 608 else
609 error = EADDRNOTAVAIL; 609 error = EADDRNOTAVAIL;
610 goto bad; 610 goto bad;
611 } 611 }
612 612
613 if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) && 613 if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) &&
614 !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) 614 !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
615 dst = satocsin6(rt->rt_gateway); 615 dst = satocsin6(rt->rt_gateway);
616 else 616 else
617 dst = satocsin6(rtcache_getdst(ro)); 617 dst = satocsin6(rtcache_getdst(ro));
618 618
619 /* 619 /*
620 * XXXXXX: original code follows: 620 * XXXXXX: original code follows:
621 */ 621 */
622 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) 622 if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
623 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */ 623 m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
624 else { 624 else {
625 bool ingroup; 625 bool ingroup;
626 626
627 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST; 627 m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST;
628 628
629 in6_ifstat_inc(ifp, ifs6_out_mcast); 629 in6_ifstat_inc(ifp, ifs6_out_mcast);
630 630
631 /* 631 /*
632 * Confirm that the outgoing interface supports multicast. 632 * Confirm that the outgoing interface supports multicast.
633 */ 633 */
634 if (!(ifp->if_flags & IFF_MULTICAST)) { 634 if (!(ifp->if_flags & IFF_MULTICAST)) {
635 IP6_STATINC(IP6_STAT_NOROUTE); 635 IP6_STATINC(IP6_STAT_NOROUTE);
636 in6_ifstat_inc(ifp, ifs6_out_discard); 636 in6_ifstat_inc(ifp, ifs6_out_discard);
637 error = ENETUNREACH; 637 error = ENETUNREACH;
638 goto bad; 638 goto bad;
639 } 639 }
640 640
641 ingroup = in6_multi_group(&ip6->ip6_dst, ifp); 641 ingroup = in6_multi_group(&ip6->ip6_dst, ifp);
642 if (ingroup && (im6o == NULL || im6o->im6o_multicast_loop)) { 642 if (ingroup && (im6o == NULL || im6o->im6o_multicast_loop)) {
643 /* 643 /*
644 * If we belong to the destination multicast group 644 * If we belong to the destination multicast group
645 * on the outgoing interface, and the caller did not 645 * on the outgoing interface, and the caller did not
646 * forbid loopback, loop back a copy. 646 * forbid loopback, loop back a copy.
647 */ 647 */
648 KASSERT(dst != NULL); 648 KASSERT(dst != NULL);
649 ip6_mloopback(ifp, m, dst); 649 ip6_mloopback(ifp, m, dst);
650 } else { 650 } else {
651 /* 651 /*
652 * If we are acting as a multicast router, perform 652 * If we are acting as a multicast router, perform
653 * multicast forwarding as if the packet had just 653 * multicast forwarding as if the packet had just
654 * arrived on the interface to which we are about 654 * arrived on the interface to which we are about
655 * to send. The multicast forwarding function 655 * to send. The multicast forwarding function
656 * recursively calls this function, using the 656 * recursively calls this function, using the
657 * IPV6_FORWARDING flag to prevent infinite recursion. 657 * IPV6_FORWARDING flag to prevent infinite recursion.
658 * 658 *
659 * Multicasts that are looped back by ip6_mloopback(), 659 * Multicasts that are looped back by ip6_mloopback(),
660 * above, will be forwarded by the ip6_input() routine, 660 * above, will be forwarded by the ip6_input() routine,
661 * if necessary. 661 * if necessary.
662 */ 662 */
663 if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) { 663 if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) {
664 if (ip6_mforward(ip6, ifp, m) != 0) { 664 if (ip6_mforward(ip6, ifp, m) != 0) {
665 m_freem(m); 665 m_freem(m);
666 goto done; 666 goto done;
667 } 667 }
668 } 668 }
669 } 669 }
670 /* 670 /*
671 * Multicasts with a hoplimit of zero may be looped back, 671 * Multicasts with a hoplimit of zero may be looped back,
672 * above, but must not be transmitted on a network. 672 * above, but must not be transmitted on a network.
673 * Also, multicasts addressed to the loopback interface 673 * Also, multicasts addressed to the loopback interface
674 * are not sent -- the above call to ip6_mloopback() will 674 * are not sent -- the above call to ip6_mloopback() will
675 * loop back a copy if this host actually belongs to the 675 * loop back a copy if this host actually belongs to the
676 * destination group on the loopback interface. 676 * destination group on the loopback interface.
677 */ 677 */
678 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) || 678 if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) ||
679 IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) { 679 IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) {
680 m_freem(m); 680 m_freem(m);
681 goto done; 681 goto done;
682 } 682 }
683 } 683 }
684 684
685 /* 685 /*
686 * Fill the outgoing inteface to tell the upper layer 686 * Fill the outgoing inteface to tell the upper layer
687 * to increment per-interface statistics. 687 * to increment per-interface statistics.
688 */ 688 */
689 if (ifpp) 689 if (ifpp)
690 *ifpp = ifp; 690 *ifpp = ifp;
691 691
692 /* Determine path MTU. */ 692 /* Determine path MTU. */
693 /* 693 /*
694 * ro_pmtu represent final destination while 694 * ro_pmtu represent final destination while
695 * ro might represent immediate destination. 695 * ro might represent immediate destination.
696 * Use ro_pmtu destination since MTU might differ. 696 * Use ro_pmtu destination since MTU might differ.
697 */ 697 */
698 if (ro_pmtu != ro) { 698 if (ro_pmtu != ro) {
699 union { 699 union {
700 struct sockaddr dst; 700 struct sockaddr dst;
701 struct sockaddr_in6 dst6; 701 struct sockaddr_in6 dst6;
702 } u; 702 } u;
703 703
704 /* ro_pmtu may not have a cache */ 704 /* ro_pmtu may not have a cache */
705 sockaddr_in6_init(&u.dst6, &finaldst, 0, 0, 0); 705 sockaddr_in6_init(&u.dst6, &finaldst, 0, 0, 0);
706 rt_pmtu = rtcache_lookup(ro_pmtu, &u.dst); 706 rt_pmtu = rtcache_lookup(ro_pmtu, &u.dst);
707 } else 707 } else
708 rt_pmtu = rt; 708 rt_pmtu = rt;
709 error = ip6_getpmtu(rt_pmtu, ifp, &mtu, &alwaysfrag); 709 error = ip6_getpmtu(rt_pmtu, ifp, &mtu, &alwaysfrag);
710 if (rt_pmtu != NULL && rt_pmtu != rt) 710 if (rt_pmtu != NULL && rt_pmtu != rt)
711 rtcache_unref(rt_pmtu, ro_pmtu); 711 rtcache_unref(rt_pmtu, ro_pmtu);
712 KASSERT(error == 0); /* ip6_getpmtu never fail if ifp is passed */ 712 KASSERT(error == 0); /* ip6_getpmtu never fail if ifp is passed */
713 713
714 /* 714 /*
715 * The caller of this function may specify to use the minimum MTU 715 * The caller of this function may specify to use the minimum MTU
716 * in some cases. 716 * in some cases.
717 * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU 717 * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU
718 * setting. The logic is a bit complicated; by default, unicast 718 * setting. The logic is a bit complicated; by default, unicast
719 * packets will follow path MTU while multicast packets will be sent at 719 * packets will follow path MTU while multicast packets will be sent at
720 * the minimum MTU. If IP6PO_MINMTU_ALL is specified, all packets 720 * the minimum MTU. If IP6PO_MINMTU_ALL is specified, all packets
721 * including unicast ones will be sent at the minimum MTU. Multicast 721 * including unicast ones will be sent at the minimum MTU. Multicast
722 * packets will always be sent at the minimum MTU unless 722 * packets will always be sent at the minimum MTU unless
723 * IP6PO_MINMTU_DISABLE is explicitly specified. 723 * IP6PO_MINMTU_DISABLE is explicitly specified.
724 * See RFC 3542 for more details. 724 * See RFC 3542 for more details.
725 */ 725 */
726 if (mtu > IPV6_MMTU) { 726 if (mtu > IPV6_MMTU) {
727 if ((flags & IPV6_MINMTU)) 727 if ((flags & IPV6_MINMTU))
728 mtu = IPV6_MMTU; 728 mtu = IPV6_MMTU;
729 else if (opt && opt->ip6po_minmtu == IP6PO_MINMTU_ALL) 729 else if (opt && opt->ip6po_minmtu == IP6PO_MINMTU_ALL)
730 mtu = IPV6_MMTU; 730 mtu = IPV6_MMTU;
731 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && 731 else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) &&
732 (opt == NULL || 732 (opt == NULL ||
733 opt->ip6po_minmtu != IP6PO_MINMTU_DISABLE)) { 733 opt->ip6po_minmtu != IP6PO_MINMTU_DISABLE)) {
734 mtu = IPV6_MMTU; 734 mtu = IPV6_MMTU;
735 } 735 }
736 } 736 }
737 737
738 /* 738 /*
739 * clear embedded scope identifiers if necessary. 739 * clear embedded scope identifiers if necessary.
740 * in6_clearscope will touch the addresses only when necessary. 740 * in6_clearscope will touch the addresses only when necessary.
741 */ 741 */
742 in6_clearscope(&ip6->ip6_src); 742 in6_clearscope(&ip6->ip6_src);
743 in6_clearscope(&ip6->ip6_dst); 743 in6_clearscope(&ip6->ip6_dst);
744 744
745 /* 745 /*
746 * If the outgoing packet contains a hop-by-hop options header, 746 * If the outgoing packet contains a hop-by-hop options header,
747 * it must be examined and processed even by the source node. 747 * it must be examined and processed even by the source node.
748 * (RFC 2460, section 4.) 748 * (RFC 2460, section 4.)
749 * 749 *
750 * XXX Is this really necessary? 750 * XXX Is this really necessary?
751 */ 751 */
752 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 752 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
753 u_int32_t dummy1; /* XXX unused */ 753 u_int32_t dummy1; /* XXX unused */
754 u_int32_t dummy2; /* XXX unused */ 754 u_int32_t dummy2; /* XXX unused */
755 int hoff = sizeof(struct ip6_hdr); 755 int hoff = sizeof(struct ip6_hdr);
756 756
757 if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) { 757 if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) {
758 /* m was already freed at this point */ 758 /* m was already freed at this point */
759 error = EINVAL; 759 error = EINVAL;
760 goto done; 760 goto done;
761 } 761 }
762 762
763 ip6 = mtod(m, struct ip6_hdr *); 763 ip6 = mtod(m, struct ip6_hdr *);
764 } 764 }
765 765
766 /* 766 /*
767 * Run through list of hooks for output packets. 767 * Run through list of hooks for output packets.
768 */ 768 */
769 error = pfil_run_hooks(inet6_pfil_hook, &m, ifp, PFIL_OUT); 769 error = pfil_run_hooks(inet6_pfil_hook, &m, ifp, PFIL_OUT);
770 if (error != 0 || m == NULL) { 770 if (error != 0 || m == NULL) {
771 IP6_STATINC(IP6_STAT_PFILDROP_OUT); 771 IP6_STATINC(IP6_STAT_PFILDROP_OUT);
772 goto done; 772 goto done;
773 } 773 }
774 ip6 = mtod(m, struct ip6_hdr *); 774 ip6 = mtod(m, struct ip6_hdr *);
775 775
776 /* 776 /*
777 * Send the packet to the outgoing interface. 777 * Send the packet to the outgoing interface.
778 * If necessary, do IPv6 fragmentation before sending. 778 * If necessary, do IPv6 fragmentation before sending.
779 * 779 *
780 * the logic here is rather complex: 780 * the logic here is rather complex:
781 * 1: normal case (dontfrag == 0, alwaysfrag == 0) 781 * 1: normal case (dontfrag == 0, alwaysfrag == 0)
782 * 1-a: send as is if tlen <= path mtu 782 * 1-a: send as is if tlen <= path mtu
783 * 1-b: fragment if tlen > path mtu 783 * 1-b: fragment if tlen > path mtu
784 * 784 *
785 * 2: if user asks us not to fragment (dontfrag == 1) 785 * 2: if user asks us not to fragment (dontfrag == 1)
786 * 2-a: send as is if tlen <= interface mtu 786 * 2-a: send as is if tlen <= interface mtu
787 * 2-b: error if tlen > interface mtu 787 * 2-b: error if tlen > interface mtu
788 * 788 *
789 * 3: if we always need to attach fragment header (alwaysfrag == 1) 789 * 3: if we always need to attach fragment header (alwaysfrag == 1)
790 * always fragment 790 * always fragment
791 * 791 *
792 * 4: if dontfrag == 1 && alwaysfrag == 1 792 * 4: if dontfrag == 1 && alwaysfrag == 1
793 * error, as we cannot handle this conflicting request 793 * error, as we cannot handle this conflicting request
794 */ 794 */
795 tlen = m->m_pkthdr.len; 795 tlen = m->m_pkthdr.len;
796 tso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv6) != 0; 796 tso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv6) != 0;
797 if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG)) 797 if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG))
798 dontfrag = 1; 798 dontfrag = 1;
799 else 799 else
800 dontfrag = 0; 800 dontfrag = 0;
801 801
802 if (dontfrag && alwaysfrag) { /* case 4 */ 802 if (dontfrag && alwaysfrag) { /* case 4 */
803 /* conflicting request - can't transmit */ 803 /* conflicting request - can't transmit */
804 IP6_STATINC(IP6_STAT_CANTFRAG); 804 IP6_STATINC(IP6_STAT_CANTFRAG);
805 error = EMSGSIZE; 805 error = EMSGSIZE;
806 goto bad; 806 goto bad;
807 } 807 }
808 if (dontfrag && (!tso && tlen > ifp->if_mtu)) { /* case 2-b */ 808 if (dontfrag && (!tso && tlen > ifp->if_mtu)) { /* case 2-b */
809 /* 809 /*
810 * Even if the DONTFRAG option is specified, we cannot send the 810 * Even if the DONTFRAG option is specified, we cannot send the
811 * packet when the data length is larger than the MTU of the 811 * packet when the data length is larger than the MTU of the
812 * outgoing interface. 812 * outgoing interface.
813 * Notify the error by sending IPV6_PATHMTU ancillary data as 813 * Notify the error by sending IPV6_PATHMTU ancillary data as
814 * well as returning an error code (the latter is not described 814 * well as returning an error code (the latter is not described
815 * in the API spec.) 815 * in the API spec.)
816 */ 816 */
817 u_int32_t mtu32; 817 u_int32_t mtu32;
818 struct ip6ctlparam ip6cp; 818 struct ip6ctlparam ip6cp;
819 819
820 mtu32 = (u_int32_t)mtu; 820 mtu32 = (u_int32_t)mtu;
821 memset(&ip6cp, 0, sizeof(ip6cp)); 821 memset(&ip6cp, 0, sizeof(ip6cp));
822 ip6cp.ip6c_cmdarg = (void *)&mtu32; 822 ip6cp.ip6c_cmdarg = (void *)&mtu32;
823 pfctlinput2(PRC_MSGSIZE, 823 pfctlinput2(PRC_MSGSIZE,
824 rtcache_getdst(ro_pmtu), &ip6cp); 824 rtcache_getdst(ro_pmtu), &ip6cp);
825 825
826 IP6_STATINC(IP6_STAT_CANTFRAG); 826 IP6_STATINC(IP6_STAT_CANTFRAG);
827 error = EMSGSIZE; 827 error = EMSGSIZE;
828 goto bad; 828 goto bad;
829 } 829 }
830 830
831 /* 831 /*
832 * transmit packet without fragmentation 832 * transmit packet without fragmentation
833 */ 833 */
834 if (dontfrag || (!alwaysfrag && (tlen <= mtu || tso))) { 834 if (dontfrag || (!alwaysfrag && (tlen <= mtu || tso))) {
835 /* case 1-a and 2-a */ 835 /* case 1-a and 2-a */
836 struct in6_ifaddr *ia6; 836 struct in6_ifaddr *ia6;
837 int sw_csum; 837 int sw_csum;
838 int s; 838 int s;
839 839
840 ip6 = mtod(m, struct ip6_hdr *); 840 ip6 = mtod(m, struct ip6_hdr *);
841 s = pserialize_read_enter(); 841 s = pserialize_read_enter();
842 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src); 842 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
843 if (ia6) { 843 if (ia6) {
844 /* Record statistics for this interface address. */ 844 /* Record statistics for this interface address. */
845 ia6->ia_ifa.ifa_data.ifad_outbytes += m->m_pkthdr.len; 845 ia6->ia_ifa.ifa_data.ifad_outbytes += m->m_pkthdr.len;
846 } 846 }
847 pserialize_read_exit(s); 847 pserialize_read_exit(s);
848 848
849 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx; 849 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx;
850 if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { 850 if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) {
851 if (IN6_NEED_CHECKSUM(ifp, 851 if (IN6_NEED_CHECKSUM(ifp,
852 sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) { 852 sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) {
853 in6_undefer_cksum_tcpudp(m); 853 in6_undefer_cksum_tcpudp(m);
854 } 854 }
855 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 855 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
856 } 856 }
857 857
858 KASSERT(dst != NULL); 858 KASSERT(dst != NULL);
859 if (__predict_false(sw_csum & M_CSUM_TSOv6)) { 859 if (__predict_false(sw_csum & M_CSUM_TSOv6)) {
860 /* 860 /*
861 * TSO6 is required by a packet, but disabled for 861 * TSO6 is required by a packet, but disabled for
862 * the interface. 862 * the interface.
863 */ 863 */
864 error = ip6_tso_output(ifp, origifp, m, dst, rt); 864 error = ip6_tso_output(ifp, origifp, m, dst, rt);
865 } else 865 } else
866 error = ip6_if_output(ifp, origifp, m, dst, rt); 866 error = ip6_if_output(ifp, origifp, m, dst, rt);
867 goto done; 867 goto done;
868 } 868 }
869 869
870 if (tso) { 870 if (tso) {
871 IP6_STATINC(IP6_STAT_CANTFRAG); /* XXX */ 871 IP6_STATINC(IP6_STAT_CANTFRAG); /* XXX */
872 error = EINVAL; /* XXX */ 872 error = EINVAL; /* XXX */
873 goto bad; 873 goto bad;
874 } 874 }
875 875
876 /* 876 /*
877 * try to fragment the packet. case 1-b and 3 877 * try to fragment the packet. case 1-b and 3
878 */ 878 */
879 if (mtu < IPV6_MMTU) { 879 if (mtu < IPV6_MMTU) {
880 /* path MTU cannot be less than IPV6_MMTU */ 880 /* path MTU cannot be less than IPV6_MMTU */
881 IP6_STATINC(IP6_STAT_CANTFRAG); 881 IP6_STATINC(IP6_STAT_CANTFRAG);
882 error = EMSGSIZE; 882 error = EMSGSIZE;
883 in6_ifstat_inc(ifp, ifs6_out_fragfail); 883 in6_ifstat_inc(ifp, ifs6_out_fragfail);
884 goto bad; 884 goto bad;
885 } else if (ip6->ip6_plen == 0) { 885 } else if (ip6->ip6_plen == 0) {
886 /* jumbo payload cannot be fragmented */ 886 /* jumbo payload cannot be fragmented */
887 IP6_STATINC(IP6_STAT_CANTFRAG); 887 IP6_STATINC(IP6_STAT_CANTFRAG);
888 error = EMSGSIZE; 888 error = EMSGSIZE;
889 in6_ifstat_inc(ifp, ifs6_out_fragfail); 889 in6_ifstat_inc(ifp, ifs6_out_fragfail);
890 goto bad; 890 goto bad;
891 } else { 891 } else {
892 const u_int32_t id = htonl(ip6_randomid()); 892 const uint32_t id = ip6_randomid();
893 struct mbuf **mnext, *m_frgpart; 893 struct mbuf **mnext, *m_frgpart;
894 const int hlen = unfragpartlen; 894 const int hlen = unfragpartlen;
895 struct ip6_frag *ip6f; 895 struct ip6_frag *ip6f;
896 u_char nextproto; 896 u_char nextproto;
897 897
898 if (mtu > IPV6_MAXPACKET) 898 if (mtu > IPV6_MAXPACKET)
899 mtu = IPV6_MAXPACKET; 899 mtu = IPV6_MAXPACKET;
900 900
901 /* 901 /*
902 * Must be able to put at least 8 bytes per fragment. 902 * Must be able to put at least 8 bytes per fragment.
903 */ 903 */
904 len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7; 904 len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7;
905 if (len < 8) { 905 if (len < 8) {
906 IP6_STATINC(IP6_STAT_CANTFRAG); 906 IP6_STATINC(IP6_STAT_CANTFRAG);
907 error = EMSGSIZE; 907 error = EMSGSIZE;
908 in6_ifstat_inc(ifp, ifs6_out_fragfail); 908 in6_ifstat_inc(ifp, ifs6_out_fragfail);
909 goto bad; 909 goto bad;
910 } 910 }
911 911
912 mnext = &m->m_nextpkt; 912 mnext = &m->m_nextpkt;
913 913
914 /* 914 /*
915 * Change the next header field of the last header in the 915 * Change the next header field of the last header in the
916 * unfragmentable part. 916 * unfragmentable part.
917 */ 917 */
918 if (exthdrs.ip6e_rthdr) { 918 if (exthdrs.ip6e_rthdr) {
919 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *); 919 nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *);
920 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT; 920 *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT;
921 } else if (exthdrs.ip6e_dest1) { 921 } else if (exthdrs.ip6e_dest1) {
922 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *); 922 nextproto = *mtod(exthdrs.ip6e_dest1, u_char *);
923 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT; 923 *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT;
924 } else if (exthdrs.ip6e_hbh) { 924 } else if (exthdrs.ip6e_hbh) {
925 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *); 925 nextproto = *mtod(exthdrs.ip6e_hbh, u_char *);
926 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT; 926 *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT;
927 } else { 927 } else {
928 nextproto = ip6->ip6_nxt; 928 nextproto = ip6->ip6_nxt;
929 ip6->ip6_nxt = IPPROTO_FRAGMENT; 929 ip6->ip6_nxt = IPPROTO_FRAGMENT;
930 } 930 }
931 931
932 if ((m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) 932 if ((m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6))
933 != 0) { 933 != 0) {
934 if (IN6_NEED_CHECKSUM(ifp, 934 if (IN6_NEED_CHECKSUM(ifp,
935 m->m_pkthdr.csum_flags & 935 m->m_pkthdr.csum_flags &
936 (M_CSUM_UDPv6|M_CSUM_TCPv6))) { 936 (M_CSUM_UDPv6|M_CSUM_TCPv6))) {
937 in6_undefer_cksum_tcpudp(m); 937 in6_undefer_cksum_tcpudp(m);
938 } 938 }
939 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 939 m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6);
940 } 940 }
941 941
942 /* 942 /*
943 * Loop through length of segment after first fragment, 943 * Loop through length of segment after first fragment,
944 * make new header and copy data of each part and link onto 944 * make new header and copy data of each part and link onto
945 * chain. 945 * chain.
946 */ 946 */
947 m0 = m; 947 m0 = m;
948 for (off = hlen; off < tlen; off += len) { 948 for (off = hlen; off < tlen; off += len) {
949 struct mbuf *mlast; 949 struct mbuf *mlast;
950 950
951 MGETHDR(m, M_DONTWAIT, MT_HEADER); 951 MGETHDR(m, M_DONTWAIT, MT_HEADER);
952 if (!m) { 952 if (!m) {
953 error = ENOBUFS; 953 error = ENOBUFS;
954 IP6_STATINC(IP6_STAT_ODROPPED); 954 IP6_STATINC(IP6_STAT_ODROPPED);
955 goto sendorfree; 955 goto sendorfree;
956 } 956 }
957 m_reset_rcvif(m); 957 m_reset_rcvif(m);
958 m->m_flags = m0->m_flags & M_COPYFLAGS; 958 m->m_flags = m0->m_flags & M_COPYFLAGS;
959 *mnext = m; 959 *mnext = m;
960 mnext = &m->m_nextpkt; 960 mnext = &m->m_nextpkt;
961 m->m_data += max_linkhdr; 961 m->m_data += max_linkhdr;
962 mhip6 = mtod(m, struct ip6_hdr *); 962 mhip6 = mtod(m, struct ip6_hdr *);
963 *mhip6 = *ip6; 963 *mhip6 = *ip6;
964 m->m_len = sizeof(*mhip6); 964 m->m_len = sizeof(*mhip6);
965 965
966 ip6f = NULL; 966 ip6f = NULL;
967 error = ip6_insertfraghdr(m0, m, hlen, &ip6f); 967 error = ip6_insertfraghdr(m0, m, hlen, &ip6f);
968 if (error) { 968 if (error) {
969 IP6_STATINC(IP6_STAT_ODROPPED); 969 IP6_STATINC(IP6_STAT_ODROPPED);
970 goto sendorfree; 970 goto sendorfree;
971 } 971 }
972 972
973 /* Fill in the Frag6 Header */ 973 /* Fill in the Frag6 Header */
974 ip6f->ip6f_offlg = htons((u_int16_t)((off - hlen) & ~7)); 974 ip6f->ip6f_offlg = htons((u_int16_t)((off - hlen) & ~7));
975 if (off + len >= tlen) 975 if (off + len >= tlen)
976 len = tlen - off; 976 len = tlen - off;
977 else 977 else
978 ip6f->ip6f_offlg |= IP6F_MORE_FRAG; 978 ip6f->ip6f_offlg |= IP6F_MORE_FRAG;
979 ip6f->ip6f_reserved = 0; 979 ip6f->ip6f_reserved = 0;
980 ip6f->ip6f_ident = id; 980 ip6f->ip6f_ident = id;
981 ip6f->ip6f_nxt = nextproto; 981 ip6f->ip6f_nxt = nextproto;
982 982
983 mhip6->ip6_plen = htons((u_int16_t)(len + hlen + 983 mhip6->ip6_plen = htons((u_int16_t)(len + hlen +
984 sizeof(*ip6f) - sizeof(struct ip6_hdr))); 984 sizeof(*ip6f) - sizeof(struct ip6_hdr)));
985 if ((m_frgpart = m_copym(m0, off, len, M_DONTWAIT)) == NULL) { 985 if ((m_frgpart = m_copym(m0, off, len, M_DONTWAIT)) == NULL) {
986 error = ENOBUFS; 986 error = ENOBUFS;
987 IP6_STATINC(IP6_STAT_ODROPPED); 987 IP6_STATINC(IP6_STAT_ODROPPED);
988 goto sendorfree; 988 goto sendorfree;
989 } 989 }
990 for (mlast = m; mlast->m_next; mlast = mlast->m_next) 990 for (mlast = m; mlast->m_next; mlast = mlast->m_next)
991 ; 991 ;
992 mlast->m_next = m_frgpart; 992 mlast->m_next = m_frgpart;
993 993
994 m->m_pkthdr.len = len + hlen + sizeof(*ip6f); 994 m->m_pkthdr.len = len + hlen + sizeof(*ip6f);
995 m_reset_rcvif(m); 995 m_reset_rcvif(m);
996 IP6_STATINC(IP6_STAT_OFRAGMENTS); 996 IP6_STATINC(IP6_STAT_OFRAGMENTS);
997 in6_ifstat_inc(ifp, ifs6_out_fragcreat); 997 in6_ifstat_inc(ifp, ifs6_out_fragcreat);
998 } 998 }
999 999
1000 in6_ifstat_inc(ifp, ifs6_out_fragok); 1000 in6_ifstat_inc(ifp, ifs6_out_fragok);
1001 } 1001 }
1002 1002
1003sendorfree: 1003sendorfree:
1004 m = m0->m_nextpkt; 1004 m = m0->m_nextpkt;
1005 m0->m_nextpkt = 0; 1005 m0->m_nextpkt = 0;
1006 m_freem(m0); 1006 m_freem(m0);
1007 for (m0 = m; m; m = m0) { 1007 for (m0 = m; m; m = m0) {
1008 m0 = m->m_nextpkt; 1008 m0 = m->m_nextpkt;
1009 m->m_nextpkt = 0; 1009 m->m_nextpkt = 0;
1010 if (error == 0) { 1010 if (error == 0) {
1011 struct in6_ifaddr *ia6; 1011 struct in6_ifaddr *ia6;
1012 int s; 1012 int s;
1013 ip6 = mtod(m, struct ip6_hdr *); 1013 ip6 = mtod(m, struct ip6_hdr *);
1014 s = pserialize_read_enter(); 1014 s = pserialize_read_enter();
1015 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src); 1015 ia6 = in6_ifawithifp(ifp, &ip6->ip6_src);
1016 if (ia6) { 1016 if (ia6) {
1017 /* 1017 /*
1018 * Record statistics for this interface 1018 * Record statistics for this interface
1019 * address. 1019 * address.
1020 */ 1020 */
1021 ia6->ia_ifa.ifa_data.ifad_outbytes += 1021 ia6->ia_ifa.ifa_data.ifad_outbytes +=
1022 m->m_pkthdr.len; 1022 m->m_pkthdr.len;
1023 } 1023 }
1024 pserialize_read_exit(s); 1024 pserialize_read_exit(s);
1025 KASSERT(dst != NULL); 1025 KASSERT(dst != NULL);
1026 error = ip6_if_output(ifp, origifp, m, dst, rt); 1026 error = ip6_if_output(ifp, origifp, m, dst, rt);
1027 } else 1027 } else
1028 m_freem(m); 1028 m_freem(m);
1029 } 1029 }
1030 1030
1031 if (error == 0) 1031 if (error == 0)
1032 IP6_STATINC(IP6_STAT_FRAGMENTED); 1032 IP6_STATINC(IP6_STAT_FRAGMENTED);
1033 1033
1034done: 1034done:
1035 rtcache_unref(rt, ro); 1035 rtcache_unref(rt, ro);
1036 if (ro == &ip6route) 1036 if (ro == &ip6route)
1037 rtcache_free(&ip6route); 1037 rtcache_free(&ip6route);
1038#ifdef IPSEC 1038#ifdef IPSEC
1039 if (sp != NULL) 1039 if (sp != NULL)
1040 KEY_SP_UNREF(&sp); 1040 KEY_SP_UNREF(&sp);
1041#endif 1041#endif
1042 if_put(ifp, &psref); 1042 if_put(ifp, &psref);
1043 if (release_psref_ia) 1043 if (release_psref_ia)
1044 if_put(origifp, &psref_ia); 1044 if_put(origifp, &psref_ia);
1045 curlwp_bindx(bound); 1045 curlwp_bindx(bound);
1046 1046
1047 return error; 1047 return error;
1048 1048
1049freehdrs: 1049freehdrs:
1050 m_freem(exthdrs.ip6e_hbh); 1050 m_freem(exthdrs.ip6e_hbh);
1051 m_freem(exthdrs.ip6e_dest1); 1051 m_freem(exthdrs.ip6e_dest1);
1052 m_freem(exthdrs.ip6e_rthdr); 1052 m_freem(exthdrs.ip6e_rthdr);
1053 m_freem(exthdrs.ip6e_dest2); 1053 m_freem(exthdrs.ip6e_dest2);
1054 /* FALLTHROUGH */ 1054 /* FALLTHROUGH */
1055bad: 1055bad:
1056 m_freem(m); 1056 m_freem(m);
1057 goto done; 1057 goto done;
1058 1058
1059badscope: 1059badscope:
1060 IP6_STATINC(IP6_STAT_BADSCOPE); 1060 IP6_STATINC(IP6_STAT_BADSCOPE);
1061 in6_ifstat_inc(origifp, ifs6_out_discard); 1061 in6_ifstat_inc(origifp, ifs6_out_discard);
1062 if (error == 0) 1062 if (error == 0)
1063 error = EHOSTUNREACH; /* XXX */ 1063 error = EHOSTUNREACH; /* XXX */
1064 goto bad; 1064 goto bad;
1065} 1065}
1066 1066
1067static int 1067static int
1068ip6_copyexthdr(struct mbuf **mp, void *hdr, int hlen) 1068ip6_copyexthdr(struct mbuf **mp, void *hdr, int hlen)
1069{ 1069{
1070 struct mbuf *m; 1070 struct mbuf *m;
1071 1071
1072 if (hlen > MCLBYTES) 1072 if (hlen > MCLBYTES)
1073 return ENOBUFS; /* XXX */ 1073 return ENOBUFS; /* XXX */
1074 1074
1075 MGET(m, M_DONTWAIT, MT_DATA); 1075 MGET(m, M_DONTWAIT, MT_DATA);
1076 if (!m) 1076 if (!m)
1077 return ENOBUFS; 1077 return ENOBUFS;
1078 1078
1079 if (hlen > MLEN) { 1079 if (hlen > MLEN) {
1080 MCLGET(m, M_DONTWAIT); 1080 MCLGET(m, M_DONTWAIT);
1081 if ((m->m_flags & M_EXT) == 0) { 1081 if ((m->m_flags & M_EXT) == 0) {
1082 m_free(m); 1082 m_free(m);
1083 return ENOBUFS; 1083 return ENOBUFS;
1084 } 1084 }
1085 } 1085 }
1086 m->m_len = hlen; 1086 m->m_len = hlen;
1087 if (hdr) 1087 if (hdr)
1088 memcpy(mtod(m, void *), hdr, hlen); 1088 memcpy(mtod(m, void *), hdr, hlen);
1089 1089
1090 *mp = m; 1090 *mp = m;
1091 return 0; 1091 return 0;
1092} 1092}
1093 1093
1094/* 1094/*
1095 * Insert jumbo payload option. 1095 * Insert jumbo payload option.
1096 */ 1096 */
1097static int 1097static int
1098ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen) 1098ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen)
1099{ 1099{
1100 struct mbuf *mopt; 1100 struct mbuf *mopt;
1101 u_int8_t *optbuf; 1101 u_int8_t *optbuf;
1102 u_int32_t v; 1102 u_int32_t v;
1103 1103
1104#define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */ 1104#define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
1105 1105
1106 /* 1106 /*
1107 * If there is no hop-by-hop options header, allocate new one. 1107 * If there is no hop-by-hop options header, allocate new one.
1108 * If there is one but it doesn't have enough space to store the 1108 * If there is one but it doesn't have enough space to store the
1109 * jumbo payload option, allocate a cluster to store the whole options. 1109 * jumbo payload option, allocate a cluster to store the whole options.
1110 * Otherwise, use it to store the options. 1110 * Otherwise, use it to store the options.
1111 */ 1111 */
1112 if (exthdrs->ip6e_hbh == NULL) { 1112 if (exthdrs->ip6e_hbh == NULL) {
1113 MGET(mopt, M_DONTWAIT, MT_DATA); 1113 MGET(mopt, M_DONTWAIT, MT_DATA);
1114 if (mopt == 0) 1114 if (mopt == 0)
1115 return (ENOBUFS); 1115 return (ENOBUFS);
1116 mopt->m_len = JUMBOOPTLEN; 1116 mopt->m_len = JUMBOOPTLEN;
1117 optbuf = mtod(mopt, u_int8_t *); 1117 optbuf = mtod(mopt, u_int8_t *);
1118 optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */ 1118 optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */
1119 exthdrs->ip6e_hbh = mopt; 1119 exthdrs->ip6e_hbh = mopt;
1120 } else { 1120 } else {
1121 struct ip6_hbh *hbh; 1121 struct ip6_hbh *hbh;
1122 1122
1123 mopt = exthdrs->ip6e_hbh; 1123 mopt = exthdrs->ip6e_hbh;
1124 if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) { 1124 if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
1125 const int oldoptlen = mopt->m_len; 1125 const int oldoptlen = mopt->m_len;
1126 struct mbuf *n; 1126 struct mbuf *n;
1127 1127
1128 /* 1128 /*
1129 * Assumptions: 1129 * Assumptions:
1130 * - exthdrs->ip6e_hbh is not referenced from places 1130 * - exthdrs->ip6e_hbh is not referenced from places
1131 * other than exthdrs. 1131 * other than exthdrs.
1132 * - exthdrs->ip6e_hbh is not an mbuf chain. 1132 * - exthdrs->ip6e_hbh is not an mbuf chain.
1133 */ 1133 */
1134 KASSERT(mopt->m_next == NULL); 1134 KASSERT(mopt->m_next == NULL);
1135 1135
1136 /* 1136 /*
1137 * Give up if the whole (new) hbh header does not fit 1137 * Give up if the whole (new) hbh header does not fit
1138 * even in an mbuf cluster. 1138 * even in an mbuf cluster.
1139 */ 1139 */
1140 if (oldoptlen + JUMBOOPTLEN > MCLBYTES) 1140 if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
1141 return ENOBUFS; 1141 return ENOBUFS;
1142 1142
1143 /* 1143 /*
1144 * At this point, we must always prepare a cluster. 1144 * At this point, we must always prepare a cluster.
1145 */ 1145 */
1146 MGET(n, M_DONTWAIT, MT_DATA); 1146 MGET(n, M_DONTWAIT, MT_DATA);
1147 if (n) { 1147 if (n) {
1148 MCLGET(n, M_DONTWAIT); 1148 MCLGET(n, M_DONTWAIT);
1149 if ((n->m_flags & M_EXT) == 0) { 1149 if ((n->m_flags & M_EXT) == 0) {
1150 m_freem(n); 1150 m_freem(n);
1151 n = NULL; 1151 n = NULL;
1152 } 1152 }
1153 } 1153 }
1154 if (!n) 1154 if (!n)
1155 return ENOBUFS; 1155 return ENOBUFS;
1156 1156
1157 n->m_len = oldoptlen + JUMBOOPTLEN; 1157 n->m_len = oldoptlen + JUMBOOPTLEN;
1158 bcopy(mtod(mopt, void *), mtod(n, void *), 1158 bcopy(mtod(mopt, void *), mtod(n, void *),
1159 oldoptlen); 1159 oldoptlen);
1160 optbuf = mtod(n, u_int8_t *) + oldoptlen; 1160 optbuf = mtod(n, u_int8_t *) + oldoptlen;
1161 m_freem(mopt); 1161 m_freem(mopt);
1162 mopt = exthdrs->ip6e_hbh = n; 1162 mopt = exthdrs->ip6e_hbh = n;
1163 } else { 1163 } else {
1164 optbuf = mtod(mopt, u_int8_t *) + mopt->m_len; 1164 optbuf = mtod(mopt, u_int8_t *) + mopt->m_len;
1165 mopt->m_len += JUMBOOPTLEN; 1165 mopt->m_len += JUMBOOPTLEN;
1166 } 1166 }
1167 optbuf[0] = IP6OPT_PADN; 1167 optbuf[0] = IP6OPT_PADN;
1168 optbuf[1] = 0; 1168 optbuf[1] = 0;
1169 1169
1170 /* 1170 /*
1171 * Adjust the header length according to the pad and 1171 * Adjust the header length according to the pad and
1172 * the jumbo payload option. 1172 * the jumbo payload option.
1173 */ 1173 */
1174 hbh = mtod(mopt, struct ip6_hbh *); 1174 hbh = mtod(mopt, struct ip6_hbh *);
1175 hbh->ip6h_len += (JUMBOOPTLEN >> 3); 1175 hbh->ip6h_len += (JUMBOOPTLEN >> 3);
1176 } 1176 }
1177 1177
1178 /* fill in the option. */ 1178 /* fill in the option. */
1179 optbuf[2] = IP6OPT_JUMBO; 1179 optbuf[2] = IP6OPT_JUMBO;
1180 optbuf[3] = 4; 1180 optbuf[3] = 4;
1181 v = (u_int32_t)htonl(plen + JUMBOOPTLEN); 1181 v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
1182 memcpy(&optbuf[4], &v, sizeof(u_int32_t)); 1182 memcpy(&optbuf[4], &v, sizeof(u_int32_t));
1183 1183
1184 /* finally, adjust the packet header length */ 1184 /* finally, adjust the packet header length */
1185 exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN; 1185 exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
1186 1186
1187 return 0; 1187 return 0;
1188#undef JUMBOOPTLEN 1188#undef JUMBOOPTLEN
1189} 1189}
1190 1190
1191/* 1191/*
1192 * Insert fragment header and copy unfragmentable header portions. 1192 * Insert fragment header and copy unfragmentable header portions.
1193 * 1193 *
1194 * *frghdrp will not be read, and it is guaranteed that either an 1194 * *frghdrp will not be read, and it is guaranteed that either an
1195 * error is returned or that *frghdrp will point to space allocated 1195 * error is returned or that *frghdrp will point to space allocated
1196 * for the fragment header. 1196 * for the fragment header.
1197 * 1197 *
1198 * On entry, m contains: 1198 * On entry, m contains:
1199 * IPv6 Header 1199 * IPv6 Header
1200 * On exit, it contains: 1200 * On exit, it contains:
1201 * IPv6 Header -> Unfragmentable Part -> Frag6 Header 1201 * IPv6 Header -> Unfragmentable Part -> Frag6 Header
1202 */ 1202 */
1203static int 1203static int
1204ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen, 1204ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen,
1205 struct ip6_frag **frghdrp) 1205 struct ip6_frag **frghdrp)
1206{ 1206{
1207 struct mbuf *n, *mlast; 1207 struct mbuf *n, *mlast;
1208 1208
1209 if (hlen > sizeof(struct ip6_hdr)) { 1209 if (hlen > sizeof(struct ip6_hdr)) {
1210 n = m_copym(m0, sizeof(struct ip6_hdr), 1210 n = m_copym(m0, sizeof(struct ip6_hdr),
1211 hlen - sizeof(struct ip6_hdr), M_DONTWAIT); 1211 hlen - sizeof(struct ip6_hdr), M_DONTWAIT);
1212 if (n == NULL) 1212 if (n == NULL)
1213 return ENOBUFS; 1213 return ENOBUFS;
1214 m->m_next = n; 1214 m->m_next = n;
1215 } else 1215 } else
1216 n = m; 1216 n = m;
1217 1217
1218 /* Search for the last mbuf of unfragmentable part. */ 1218 /* Search for the last mbuf of unfragmentable part. */
1219 for (mlast = n; mlast->m_next; mlast = mlast->m_next) 1219 for (mlast = n; mlast->m_next; mlast = mlast->m_next)
1220 ; 1220 ;
1221 1221
1222 if ((mlast->m_flags & M_EXT) == 0 && 1222 if ((mlast->m_flags & M_EXT) == 0 &&
1223 M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) { 1223 M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) {
1224 /* use the trailing space of the last mbuf for the fragment hdr */ 1224 /* use the trailing space of the last mbuf for the fragment hdr */
1225 *frghdrp = (struct ip6_frag *)(mtod(mlast, char *) + 1225 *frghdrp = (struct ip6_frag *)(mtod(mlast, char *) +
1226 mlast->m_len); 1226 mlast->m_len);
1227 mlast->m_len += sizeof(struct ip6_frag); 1227 mlast->m_len += sizeof(struct ip6_frag);
1228 } else { 1228 } else {
1229 /* allocate a new mbuf for the fragment header */ 1229 /* allocate a new mbuf for the fragment header */
1230 struct mbuf *mfrg; 1230 struct mbuf *mfrg;
1231 1231
1232 MGET(mfrg, M_DONTWAIT, MT_DATA); 1232 MGET(mfrg, M_DONTWAIT, MT_DATA);
1233 if (mfrg == NULL) 1233 if (mfrg == NULL)
1234 return ENOBUFS; 1234 return ENOBUFS;
1235 mfrg->m_len = sizeof(struct ip6_frag); 1235 mfrg->m_len = sizeof(struct ip6_frag);
1236 *frghdrp = mtod(mfrg, struct ip6_frag *); 1236 *frghdrp = mtod(mfrg, struct ip6_frag *);
1237 mlast->m_next = mfrg; 1237 mlast->m_next = mfrg;
1238 } 1238 }
1239 1239
1240 return 0; 1240 return 0;
1241} 1241}
1242 1242
1243static int 1243static int
1244ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup, 1244ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup,
1245 int *alwaysfragp) 1245 int *alwaysfragp)
1246{ 1246{
1247 u_int32_t mtu = 0; 1247 u_int32_t mtu = 0;
1248 int alwaysfrag = 0; 1248 int alwaysfrag = 0;
1249 int error = 0; 1249 int error = 0;
1250 1250
1251 if (rt != NULL) { 1251 if (rt != NULL) {
1252 if (ifp == NULL) 1252 if (ifp == NULL)
1253 ifp = rt->rt_ifp; 1253 ifp = rt->rt_ifp;
1254 mtu = rt->rt_rmx.rmx_mtu; 1254 mtu = rt->rt_rmx.rmx_mtu;
1255 if (mtu == 0) 1255 if (mtu == 0)
1256 mtu = ifp->if_mtu; 1256 mtu = ifp->if_mtu;
1257 else if (mtu < IPV6_MMTU) { 1257 else if (mtu < IPV6_MMTU) {
1258 /* 1258 /*
1259 * RFC2460 section 5, last paragraph: 1259 * RFC2460 section 5, last paragraph:
1260 * if we record ICMPv6 too big message with 1260 * if we record ICMPv6 too big message with
1261 * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU 1261 * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU
1262 * or smaller, with fragment header attached. 1262 * or smaller, with fragment header attached.
1263 * (fragment header is needed regardless from the 1263 * (fragment header is needed regardless from the
1264 * packet size, for translators to identify packets) 1264 * packet size, for translators to identify packets)
1265 */ 1265 */
1266 alwaysfrag = 1; 1266 alwaysfrag = 1;
1267 mtu = IPV6_MMTU; 1267 mtu = IPV6_MMTU;
1268 } else if (mtu > ifp->if_mtu) { 1268 } else if (mtu > ifp->if_mtu) {
1269 /* 1269 /*
1270 * The MTU on the route is larger than the MTU on 1270 * The MTU on the route is larger than the MTU on
1271 * the interface! This shouldn't happen, unless the 1271 * the interface! This shouldn't happen, unless the
1272 * MTU of the interface has been changed after the 1272 * MTU of the interface has been changed after the
1273 * interface was brought up. Change the MTU in the 1273 * interface was brought up. Change the MTU in the
1274 * route to match the interface MTU (as long as the 1274 * route to match the interface MTU (as long as the
1275 * field isn't locked). 1275 * field isn't locked).
1276 */ 1276 */
1277 mtu = ifp->if_mtu; 1277 mtu = ifp->if_mtu;
1278 if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) 1278 if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
1279 rt->rt_rmx.rmx_mtu = mtu; 1279 rt->rt_rmx.rmx_mtu = mtu;
1280 } 1280 }
1281 } else if (ifp) { 1281 } else if (ifp) {
1282 mtu = ifp->if_mtu; 1282 mtu = ifp->if_mtu;
1283 } else 1283 } else
1284 error = EHOSTUNREACH; /* XXX */ 1284 error = EHOSTUNREACH; /* XXX */
1285 1285
1286 *mtup = mtu; 1286 *mtup = mtu;
1287 if (alwaysfragp) 1287 if (alwaysfragp)
1288 *alwaysfragp = alwaysfrag; 1288 *alwaysfragp = alwaysfrag;
1289 return (error); 1289 return (error);
1290} 1290}
1291 1291
1292/* 1292/*
1293 * IP6 socket option processing. 1293 * IP6 socket option processing.
1294 */ 1294 */
1295int 1295int
1296ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1296ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt)
1297{ 1297{
1298 int optdatalen, uproto; 1298 int optdatalen, uproto;
1299 void *optdata; 1299 void *optdata;
1300 struct in6pcb *in6p = sotoin6pcb(so); 1300 struct in6pcb *in6p = sotoin6pcb(so);
1301 struct ip_moptions **mopts; 1301 struct ip_moptions **mopts;
1302 int error, optval; 1302 int error, optval;
1303 int level, optname; 1303 int level, optname;
1304 1304
1305 KASSERT(solocked(so)); 1305 KASSERT(solocked(so));
1306 KASSERT(sopt != NULL); 1306 KASSERT(sopt != NULL);
1307 1307
1308 level = sopt->sopt_level; 1308 level = sopt->sopt_level;
1309 optname = sopt->sopt_name; 1309 optname = sopt->sopt_name;
1310 1310
1311 error = optval = 0; 1311 error = optval = 0;
1312 uproto = (int)so->so_proto->pr_protocol; 1312 uproto = (int)so->so_proto->pr_protocol;
1313 1313
1314 switch (level) { 1314 switch (level) {
1315 case IPPROTO_IP: 1315 case IPPROTO_IP:
1316 switch (optname) { 1316 switch (optname) {
1317 case IP_ADD_MEMBERSHIP: 1317 case IP_ADD_MEMBERSHIP:
1318 case IP_DROP_MEMBERSHIP: 1318 case IP_DROP_MEMBERSHIP:
1319 case IP_MULTICAST_IF: 1319 case IP_MULTICAST_IF:
1320 case IP_MULTICAST_LOOP: 1320 case IP_MULTICAST_LOOP:
1321 case IP_MULTICAST_TTL: 1321 case IP_MULTICAST_TTL:
1322 mopts = &in6p->in6p_v4moptions; 1322 mopts = &in6p->in6p_v4moptions;
1323 switch (op) { 1323 switch (op) {
1324 case PRCO_GETOPT: 1324 case PRCO_GETOPT:
1325 return ip_getmoptions(*mopts, sopt); 1325 return ip_getmoptions(*mopts, sopt);
1326 case PRCO_SETOPT: 1326 case PRCO_SETOPT:
1327 return ip_setmoptions(mopts, sopt); 1327 return ip_setmoptions(mopts, sopt);
1328 default: 1328 default:
1329 return EINVAL; 1329 return EINVAL;
1330 } 1330 }
1331 default: 1331 default:
1332 return ENOPROTOOPT; 1332 return ENOPROTOOPT;
1333 } 1333 }
1334 case IPPROTO_IPV6: 1334 case IPPROTO_IPV6:
1335 break; 1335 break;
1336 default: 1336 default:
1337 return ENOPROTOOPT; 1337 return ENOPROTOOPT;
1338 } 1338 }
1339 switch (op) { 1339 switch (op) {
1340 case PRCO_SETOPT: 1340 case PRCO_SETOPT:
1341 switch (optname) { 1341 switch (optname) {
1342#ifdef RFC2292 1342#ifdef RFC2292
1343 case IPV6_2292PKTOPTIONS: 1343 case IPV6_2292PKTOPTIONS:
1344 error = ip6_pcbopts(&in6p->in6p_outputopts, so, sopt); 1344 error = ip6_pcbopts(&in6p->in6p_outputopts, so, sopt);
1345 break; 1345 break;
1346#endif 1346#endif
1347 1347
1348 /* 1348 /*
1349 * Use of some Hop-by-Hop options or some 1349 * Use of some Hop-by-Hop options or some
1350 * Destination options, might require special 1350 * Destination options, might require special
1351 * privilege. That is, normal applications 1351 * privilege. That is, normal applications
1352 * (without special privilege) might be forbidden 1352 * (without special privilege) might be forbidden
1353 * from setting certain options in outgoing packets, 1353 * from setting certain options in outgoing packets,
1354 * and might never see certain options in received 1354 * and might never see certain options in received
1355 * packets. [RFC 2292 Section 6] 1355 * packets. [RFC 2292 Section 6]
1356 * KAME specific note: 1356 * KAME specific note:
1357 * KAME prevents non-privileged users from sending or 1357 * KAME prevents non-privileged users from sending or
1358 * receiving ANY hbh/dst options in order to avoid 1358 * receiving ANY hbh/dst options in order to avoid
1359 * overhead of parsing options in the kernel. 1359 * overhead of parsing options in the kernel.
1360 */ 1360 */
1361 case IPV6_RECVHOPOPTS: 1361 case IPV6_RECVHOPOPTS:
1362 case IPV6_RECVDSTOPTS: 1362 case IPV6_RECVDSTOPTS:
1363 case IPV6_RECVRTHDRDSTOPTS: 1363 case IPV6_RECVRTHDRDSTOPTS:
1364 error = kauth_authorize_network(kauth_cred_get(), 1364 error = kauth_authorize_network(kauth_cred_get(),
1365 KAUTH_NETWORK_IPV6, KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, 1365 KAUTH_NETWORK_IPV6, KAUTH_REQ_NETWORK_IPV6_HOPBYHOP,
1366 NULL, NULL, NULL); 1366 NULL, NULL, NULL);
1367 if (error) 1367 if (error)
1368 break; 1368 break;
1369 /* FALLTHROUGH */ 1369 /* FALLTHROUGH */
1370 case IPV6_UNICAST_HOPS: 1370 case IPV6_UNICAST_HOPS:
1371 case IPV6_HOPLIMIT: 1371 case IPV6_HOPLIMIT:
1372 case IPV6_FAITH: 1372 case IPV6_FAITH:
1373 1373
1374 case IPV6_RECVPKTINFO: 1374 case IPV6_RECVPKTINFO:
1375 case IPV6_RECVHOPLIMIT: 1375 case IPV6_RECVHOPLIMIT:
1376 case IPV6_RECVRTHDR: 1376 case IPV6_RECVRTHDR:
1377 case IPV6_RECVPATHMTU: 1377 case IPV6_RECVPATHMTU:
1378 case IPV6_RECVTCLASS: 1378 case IPV6_RECVTCLASS:
1379 case IPV6_V6ONLY: 1379 case IPV6_V6ONLY:
1380 case IPV6_BINDANY: 1380 case IPV6_BINDANY:
1381 error = sockopt_getint(sopt, &optval); 1381 error = sockopt_getint(sopt, &optval);
1382 if (error) 1382 if (error)
1383 break; 1383 break;
1384 switch (optname) { 1384 switch (optname) {
1385 case IPV6_UNICAST_HOPS: 1385 case IPV6_UNICAST_HOPS:
1386 if (optval < -1 || optval >= 256) 1386 if (optval < -1 || optval >= 256)
1387 error = EINVAL; 1387 error = EINVAL;
1388 else { 1388 else {
1389 /* -1 = kernel default */ 1389 /* -1 = kernel default */
1390 in6p->in6p_hops = optval; 1390 in6p->in6p_hops = optval;
1391 } 1391 }
1392 break; 1392 break;
1393#define OPTSET(bit) \ 1393#define OPTSET(bit) \
1394do { \ 1394do { \
1395if (optval) \ 1395if (optval) \
1396 in6p->in6p_flags |= (bit); \ 1396 in6p->in6p_flags |= (bit); \
1397else \ 1397else \
1398 in6p->in6p_flags &= ~(bit); \ 1398 in6p->in6p_flags &= ~(bit); \
1399} while (/*CONSTCOND*/ 0) 1399} while (/*CONSTCOND*/ 0)
1400 1400
1401#ifdef RFC2292 1401#ifdef RFC2292
1402#define OPTSET2292(bit) \ 1402#define OPTSET2292(bit) \
1403do { \ 1403do { \
1404in6p->in6p_flags |= IN6P_RFC2292; \ 1404in6p->in6p_flags |= IN6P_RFC2292; \
1405if (optval) \ 1405if (optval) \
1406 in6p->in6p_flags |= (bit); \ 1406 in6p->in6p_flags |= (bit); \
1407else \ 1407else \
1408 in6p->in6p_flags &= ~(bit); \ 1408 in6p->in6p_flags &= ~(bit); \
1409} while (/*CONSTCOND*/ 0) 1409} while (/*CONSTCOND*/ 0)
1410#endif 1410#endif
1411 1411
1412#define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0) 1412#define OPTBIT(bit) (in6p->in6p_flags & (bit) ? 1 : 0)
1413 1413
1414 case IPV6_RECVPKTINFO: 1414 case IPV6_RECVPKTINFO:
1415#ifdef RFC2292 1415#ifdef RFC2292
1416 /* cannot mix with RFC2292 */ 1416 /* cannot mix with RFC2292 */
1417 if (OPTBIT(IN6P_RFC2292)) { 1417 if (OPTBIT(IN6P_RFC2292)) {
1418 error = EINVAL; 1418 error = EINVAL;
1419 break; 1419 break;
1420 } 1420 }
1421#endif 1421#endif
1422 OPTSET(IN6P_PKTINFO); 1422 OPTSET(IN6P_PKTINFO);
1423 break; 1423 break;
1424 1424
1425 case IPV6_HOPLIMIT: 1425 case IPV6_HOPLIMIT:
1426 { 1426 {
1427 struct ip6_pktopts **optp; 1427 struct ip6_pktopts **optp;
1428 1428
1429#ifdef RFC2292 1429#ifdef RFC2292
1430 /* cannot mix with RFC2292 */ 1430 /* cannot mix with RFC2292 */
1431 if (OPTBIT(IN6P_RFC2292)) { 1431 if (OPTBIT(IN6P_RFC2292)) {
1432 error = EINVAL; 1432 error = EINVAL;
1433 break; 1433 break;
1434 } 1434 }
1435#endif 1435#endif
1436 optp = &in6p->in6p_outputopts; 1436 optp = &in6p->in6p_outputopts;
1437 error = ip6_pcbopt(IPV6_HOPLIMIT, 1437 error = ip6_pcbopt(IPV6_HOPLIMIT,
1438 (u_char *)&optval, 1438 (u_char *)&optval,
1439 sizeof(optval), 1439 sizeof(optval),
1440 optp, 1440 optp,
1441 kauth_cred_get(), uproto); 1441 kauth_cred_get(), uproto);
1442 break; 1442 break;
1443 } 1443 }
1444 1444
1445 case IPV6_RECVHOPLIMIT: 1445 case IPV6_RECVHOPLIMIT:
1446#ifdef RFC2292 1446#ifdef RFC2292
1447 /* cannot mix with RFC2292 */ 1447 /* cannot mix with RFC2292 */
1448 if (OPTBIT(IN6P_RFC2292)) { 1448 if (OPTBIT(IN6P_RFC2292)) {
1449 error = EINVAL; 1449 error = EINVAL;
1450 break; 1450 break;
1451 } 1451 }
1452#endif 1452#endif
1453 OPTSET(IN6P_HOPLIMIT); 1453 OPTSET(IN6P_HOPLIMIT);
1454 break; 1454 break;
1455 1455
1456 case IPV6_RECVHOPOPTS: 1456 case IPV6_RECVHOPOPTS:
1457#ifdef RFC2292 1457#ifdef RFC2292
1458 /* cannot mix with RFC2292 */ 1458 /* cannot mix with RFC2292 */
1459 if (OPTBIT(IN6P_RFC2292)) { 1459 if (OPTBIT(IN6P_RFC2292)) {
1460 error = EINVAL; 1460 error = EINVAL;
1461 break; 1461 break;
1462 } 1462 }
1463#endif 1463#endif
1464 OPTSET(IN6P_HOPOPTS); 1464 OPTSET(IN6P_HOPOPTS);
1465 break; 1465 break;
1466 1466
1467 case IPV6_RECVDSTOPTS: 1467 case IPV6_RECVDSTOPTS:
1468#ifdef RFC2292 1468#ifdef RFC2292
1469 /* cannot mix with RFC2292 */ 1469 /* cannot mix with RFC2292 */
1470 if (OPTBIT(IN6P_RFC2292)) { 1470 if (OPTBIT(IN6P_RFC2292)) {
1471 error = EINVAL; 1471 error = EINVAL;
1472 break; 1472 break;
1473 } 1473 }
1474#endif 1474#endif
1475 OPTSET(IN6P_DSTOPTS); 1475 OPTSET(IN6P_DSTOPTS);
1476 break; 1476 break;
1477 1477
1478 case IPV6_RECVRTHDRDSTOPTS: 1478 case IPV6_RECVRTHDRDSTOPTS:
1479#ifdef RFC2292 1479#ifdef RFC2292
1480 /* cannot mix with RFC2292 */ 1480 /* cannot mix with RFC2292 */
1481 if (OPTBIT(IN6P_RFC2292)) { 1481 if (OPTBIT(IN6P_RFC2292)) {
1482 error = EINVAL; 1482 error = EINVAL;
1483 break; 1483 break;
1484 } 1484 }
1485#endif 1485#endif
1486 OPTSET(IN6P_RTHDRDSTOPTS); 1486 OPTSET(IN6P_RTHDRDSTOPTS);
1487 break; 1487 break;
1488 1488
1489 case IPV6_RECVRTHDR: 1489 case IPV6_RECVRTHDR:
1490#ifdef RFC2292 1490#ifdef RFC2292
1491 /* cannot mix with RFC2292 */ 1491 /* cannot mix with RFC2292 */
1492 if (OPTBIT(IN6P_RFC2292)) { 1492 if (OPTBIT(IN6P_RFC2292)) {
1493 error = EINVAL; 1493 error = EINVAL;
1494 break; 1494 break;
1495 } 1495 }
1496#endif 1496#endif
1497 OPTSET(IN6P_RTHDR); 1497 OPTSET(IN6P_RTHDR);
1498 break; 1498 break;
1499 1499
1500 case IPV6_FAITH: 1500 case IPV6_FAITH:
1501 OPTSET(IN6P_FAITH); 1501 OPTSET(IN6P_FAITH);
1502 break; 1502 break;
1503 1503
1504 case IPV6_RECVPATHMTU: 1504 case IPV6_RECVPATHMTU:
1505 /* 1505 /*
1506 * We ignore this option for TCP 1506 * We ignore this option for TCP
1507 * sockets. 1507 * sockets.
1508 * (RFC3542 leaves this case 1508 * (RFC3542 leaves this case
1509 * unspecified.) 1509 * unspecified.)
1510 */ 1510 */
1511 if (uproto != IPPROTO_TCP) 1511 if (uproto != IPPROTO_TCP)
1512 OPTSET(IN6P_MTU); 1512 OPTSET(IN6P_MTU);
1513 break; 1513 break;
1514 1514
1515 case IPV6_V6ONLY: 1515 case IPV6_V6ONLY:
1516 /* 1516 /*
1517 * make setsockopt(IPV6_V6ONLY) 1517 * make setsockopt(IPV6_V6ONLY)
1518 * available only prior to bind(2). 1518 * available only prior to bind(2).
1519 * see ipng mailing list, Jun 22 2001. 1519 * see ipng mailing list, Jun 22 2001.
1520 */ 1520 */
1521 if (in6p->in6p_lport || 1521 if (in6p->in6p_lport ||
1522 !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) { 1522 !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
1523 error = EINVAL; 1523 error = EINVAL;
1524 break; 1524 break;
1525 } 1525 }
1526#ifdef INET6_BINDV6ONLY 1526#ifdef INET6_BINDV6ONLY
1527 if (!optval) 1527 if (!optval)
1528 error = EINVAL; 1528 error = EINVAL;
1529#else 1529#else
1530 OPTSET(IN6P_IPV6_V6ONLY); 1530 OPTSET(IN6P_IPV6_V6ONLY);
1531#endif 1531#endif
1532 break; 1532 break;
1533 1533
1534 case IPV6_RECVTCLASS: 1534 case IPV6_RECVTCLASS:
1535#ifdef RFC2292 1535#ifdef RFC2292
1536 /* cannot mix with RFC2292 XXX */ 1536 /* cannot mix with RFC2292 XXX */
1537 if (OPTBIT(IN6P_RFC2292)) { 1537 if (OPTBIT(IN6P_RFC2292)) {
1538 error = EINVAL; 1538 error = EINVAL;
1539 break; 1539 break;
1540 } 1540 }
1541#endif 1541#endif
1542 OPTSET(IN6P_TCLASS); 1542 OPTSET(IN6P_TCLASS);
1543 break; 1543 break;
1544 1544
1545 case IPV6_BINDANY: 1545 case IPV6_BINDANY:
1546 error = kauth_authorize_network( 1546 error = kauth_authorize_network(
1547 kauth_cred_get(), KAUTH_NETWORK_BIND, 1547 kauth_cred_get(), KAUTH_NETWORK_BIND,
1548 KAUTH_REQ_NETWORK_BIND_ANYADDR, so, NULL, 1548 KAUTH_REQ_NETWORK_BIND_ANYADDR, so, NULL,
1549 NULL); 1549 NULL);
1550 if (error) 1550 if (error)
1551 break; 1551 break;
1552 OPTSET(IN6P_BINDANY); 1552 OPTSET(IN6P_BINDANY);
1553 break; 1553 break;
1554 } 1554 }
1555 break; 1555 break;
1556 1556
1557 case IPV6_OTCLASS: 1557 case IPV6_OTCLASS:
1558 { 1558 {
1559 struct ip6_pktopts **optp; 1559 struct ip6_pktopts **optp;
1560 u_int8_t tclass; 1560 u_int8_t tclass;
1561 1561
1562 error = sockopt_get(sopt, &tclass, sizeof(tclass)); 1562 error = sockopt_get(sopt, &tclass, sizeof(tclass));
1563 if (error) 1563 if (error)
1564 break; 1564 break;
1565 optp = &in6p->in6p_outputopts; 1565 optp = &in6p->in6p_outputopts;
1566 error = ip6_pcbopt(optname, 1566 error = ip6_pcbopt(optname,
1567 (u_char *)&tclass, 1567 (u_char *)&tclass,
1568 sizeof(tclass), 1568 sizeof(tclass),
1569 optp, 1569 optp,
1570 kauth_cred_get(), uproto); 1570 kauth_cred_get(), uproto);
1571 break; 1571 break;
1572 } 1572 }
1573 1573
1574 case IPV6_TCLASS: 1574 case IPV6_TCLASS:
1575 case IPV6_DONTFRAG: 1575 case IPV6_DONTFRAG:
1576 case IPV6_USE_MIN_MTU: 1576 case IPV6_USE_MIN_MTU:
1577 case IPV6_PREFER_TEMPADDR: 1577 case IPV6_PREFER_TEMPADDR:
1578 error = sockopt_getint(sopt, &optval); 1578 error = sockopt_getint(sopt, &optval);
1579 if (error) 1579 if (error)
1580 break; 1580 break;
1581 { 1581 {
1582 struct ip6_pktopts **optp; 1582 struct ip6_pktopts **optp;
1583 optp = &in6p->in6p_outputopts; 1583 optp = &in6p->in6p_outputopts;
1584 error = ip6_pcbopt(optname, 1584 error = ip6_pcbopt(optname,
1585 (u_char *)&optval, 1585 (u_char *)&optval,
1586 sizeof(optval), 1586 sizeof(optval),
1587 optp, 1587 optp,
1588 kauth_cred_get(), uproto); 1588 kauth_cred_get(), uproto);
1589 break; 1589 break;
1590 } 1590 }
1591 1591
1592#ifdef RFC2292 1592#ifdef RFC2292
1593 case IPV6_2292PKTINFO: 1593 case IPV6_2292PKTINFO:
1594 case IPV6_2292HOPLIMIT: 1594 case IPV6_2292HOPLIMIT:
1595 case IPV6_2292HOPOPTS: 1595 case IPV6_2292HOPOPTS:
1596 case IPV6_2292DSTOPTS: 1596 case IPV6_2292DSTOPTS:
1597 case IPV6_2292RTHDR: 1597 case IPV6_2292RTHDR:
1598 /* RFC 2292 */ 1598 /* RFC 2292 */
1599 error = sockopt_getint(sopt, &optval); 1599 error = sockopt_getint(sopt, &optval);
1600 if (error) 1600 if (error)
1601 break; 1601 break;
1602 1602
1603 switch (optname) { 1603 switch (optname) {
1604 case IPV6_2292PKTINFO: 1604 case IPV6_2292PKTINFO:
1605 OPTSET2292(IN6P_PKTINFO); 1605 OPTSET2292(IN6P_PKTINFO);
1606 break; 1606 break;
1607 case IPV6_2292HOPLIMIT: 1607 case IPV6_2292HOPLIMIT:
1608 OPTSET2292(IN6P_HOPLIMIT); 1608 OPTSET2292(IN6P_HOPLIMIT);
1609 break; 1609 break;
1610 case IPV6_2292HOPOPTS: 1610 case IPV6_2292HOPOPTS:
1611 /* 1611 /*
1612 * Check super-user privilege. 1612 * Check super-user privilege.
1613 * See comments for IPV6_RECVHOPOPTS. 1613 * See comments for IPV6_RECVHOPOPTS.
1614 */ 1614 */
1615 error = 1615 error =
1616 kauth_authorize_network(kauth_cred_get(), 1616 kauth_authorize_network(kauth_cred_get(),
1617 KAUTH_NETWORK_IPV6, 1617 KAUTH_NETWORK_IPV6,
1618 KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, 1618 KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL,
1619 NULL, NULL); 1619 NULL, NULL);
1620 if (error) 1620 if (error)
1621 return (error); 1621 return (error);
1622 OPTSET2292(IN6P_HOPOPTS); 1622 OPTSET2292(IN6P_HOPOPTS);
1623 break; 1623 break;
1624 case IPV6_2292DSTOPTS: 1624 case IPV6_2292DSTOPTS:
1625 error = 1625 error =
1626 kauth_authorize_network(kauth_cred_get(), 1626 kauth_authorize_network(kauth_cred_get(),
1627 KAUTH_NETWORK_IPV6, 1627 KAUTH_NETWORK_IPV6,
1628 KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, 1628 KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL,
1629 NULL, NULL); 1629 NULL, NULL);
1630 if (error) 1630 if (error)
1631 return (error); 1631 return (error);
1632 OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */ 1632 OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */
1633 break; 1633 break;
1634 case IPV6_2292RTHDR: 1634 case IPV6_2292RTHDR:
1635 OPTSET2292(IN6P_RTHDR); 1635 OPTSET2292(IN6P_RTHDR);
1636 break; 1636 break;
1637 } 1637 }
1638 break; 1638 break;
1639#endif 1639#endif
1640 case IPV6_PKTINFO: 1640 case IPV6_PKTINFO:
1641 case IPV6_HOPOPTS: 1641 case IPV6_HOPOPTS:
1642 case IPV6_RTHDR: 1642 case IPV6_RTHDR:
1643 case IPV6_DSTOPTS: 1643 case IPV6_DSTOPTS:
1644 case IPV6_RTHDRDSTOPTS: 1644 case IPV6_RTHDRDSTOPTS:
1645 case IPV6_NEXTHOP: { 1645 case IPV6_NEXTHOP: {
1646 /* new advanced API (RFC3542) */ 1646 /* new advanced API (RFC3542) */
1647 void *optbuf; 1647 void *optbuf;
1648 int optbuflen; 1648 int optbuflen;
1649 struct ip6_pktopts **optp; 1649 struct ip6_pktopts **optp;
1650 1650
1651#ifdef RFC2292 1651#ifdef RFC2292
1652 /* cannot mix with RFC2292 */ 1652 /* cannot mix with RFC2292 */
1653 if (OPTBIT(IN6P_RFC2292)) { 1653 if (OPTBIT(IN6P_RFC2292)) {
1654 error = EINVAL; 1654 error = EINVAL;
1655 break; 1655 break;
1656 } 1656 }
1657#endif 1657#endif
1658 1658
1659 optbuflen = sopt->sopt_size; 1659 optbuflen = sopt->sopt_size;
1660 optbuf = malloc(optbuflen, M_IP6OPT, M_NOWAIT); 1660 optbuf = malloc(optbuflen, M_IP6OPT, M_NOWAIT);
1661 if (optbuf == NULL) { 1661 if (optbuf == NULL) {
1662 error = ENOBUFS; 1662 error = ENOBUFS;
1663 break; 1663 break;
1664 } 1664 }
1665 1665
1666 error = sockopt_get(sopt, optbuf, optbuflen); 1666 error = sockopt_get(sopt, optbuf, optbuflen);
1667 if (error) { 1667 if (error) {
1668 free(optbuf, M_IP6OPT); 1668 free(optbuf, M_IP6OPT);
1669 break; 1669 break;
1670 } 1670 }
1671 optp = &in6p->in6p_outputopts; 1671 optp = &in6p->in6p_outputopts;
1672 error = ip6_pcbopt(optname, optbuf, optbuflen, 1672 error = ip6_pcbopt(optname, optbuf, optbuflen,
1673 optp, kauth_cred_get(), uproto); 1673 optp, kauth_cred_get(), uproto);
1674 1674
1675 free(optbuf, M_IP6OPT); 1675 free(optbuf, M_IP6OPT);
1676 break; 1676 break;
1677 } 1677 }
1678#undef OPTSET 1678#undef OPTSET
1679 1679
1680 case IPV6_MULTICAST_IF: 1680 case IPV6_MULTICAST_IF:
1681 case IPV6_MULTICAST_HOPS: 1681 case IPV6_MULTICAST_HOPS:
1682 case IPV6_MULTICAST_LOOP: 1682 case IPV6_MULTICAST_LOOP:
1683 case IPV6_JOIN_GROUP: 1683 case IPV6_JOIN_GROUP:
1684 case IPV6_LEAVE_GROUP: 1684 case IPV6_LEAVE_GROUP:
1685 error = ip6_setmoptions(sopt, in6p); 1685 error = ip6_setmoptions(sopt, in6p);
1686 break; 1686 break;
1687 1687
1688 case IPV6_PORTRANGE: 1688 case IPV6_PORTRANGE:
1689 error = sockopt_getint(sopt, &optval); 1689 error = sockopt_getint(sopt, &optval);
1690 if (error) 1690 if (error)
1691 break; 1691 break;
1692 1692
1693 switch (optval) { 1693 switch (optval) {
1694 case IPV6_PORTRANGE_DEFAULT: 1694 case IPV6_PORTRANGE_DEFAULT:
1695 in6p->in6p_flags &= ~(IN6P_LOWPORT); 1695 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1696 in6p->in6p_flags &= ~(IN6P_HIGHPORT); 1696 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1697 break; 1697 break;
1698 1698
1699 case IPV6_PORTRANGE_HIGH: 1699 case IPV6_PORTRANGE_HIGH:
1700 in6p->in6p_flags &= ~(IN6P_LOWPORT); 1700 in6p->in6p_flags &= ~(IN6P_LOWPORT);
1701 in6p->in6p_flags |= IN6P_HIGHPORT; 1701 in6p->in6p_flags |= IN6P_HIGHPORT;
1702 break; 1702 break;
1703 1703
1704 case IPV6_PORTRANGE_LOW: 1704 case IPV6_PORTRANGE_LOW:
1705 in6p->in6p_flags &= ~(IN6P_HIGHPORT); 1705 in6p->in6p_flags &= ~(IN6P_HIGHPORT);
1706 in6p->in6p_flags |= IN6P_LOWPORT; 1706 in6p->in6p_flags |= IN6P_LOWPORT;
1707 break; 1707 break;
1708 1708
1709 default: 1709 default:
1710 error = EINVAL; 1710 error = EINVAL;
1711 break; 1711 break;
1712 } 1712 }
1713 break; 1713 break;
1714 1714
1715 case IPV6_PORTALGO: 1715 case IPV6_PORTALGO:
1716 error = sockopt_getint(sopt, &optval); 1716 error = sockopt_getint(sopt, &optval);
1717 if (error) 1717 if (error)
1718 break; 1718 break;
1719 1719
1720 error = portalgo_algo_index_select( 1720 error = portalgo_algo_index_select(
1721 (struct inpcb_hdr *)in6p, optval); 1721 (struct inpcb_hdr *)in6p, optval);
1722 break; 1722 break;
1723 1723
1724#if defined(IPSEC) 1724#if defined(IPSEC)
1725 case IPV6_IPSEC_POLICY: 1725 case IPV6_IPSEC_POLICY:
1726 if (ipsec_enabled) { 1726 if (ipsec_enabled) {
1727 error = ipsec_set_policy(in6p, 1727 error = ipsec_set_policy(in6p,
1728 sopt->sopt_data, sopt->sopt_size, 1728 sopt->sopt_data, sopt->sopt_size,
1729 kauth_cred_get()); 1729 kauth_cred_get());
1730 } else 1730 } else
1731 error = ENOPROTOOPT; 1731 error = ENOPROTOOPT;
1732 break; 1732 break;
1733#endif /* IPSEC */ 1733#endif /* IPSEC */
1734 1734
1735 default: 1735 default:
1736 error = ENOPROTOOPT; 1736 error = ENOPROTOOPT;
1737 break; 1737 break;
1738 } 1738 }
1739 break; 1739 break;
1740 1740
1741 case PRCO_GETOPT: 1741 case PRCO_GETOPT:
1742 switch (optname) { 1742 switch (optname) {
1743#ifdef RFC2292 1743#ifdef RFC2292
1744 case IPV6_2292PKTOPTIONS: 1744 case IPV6_2292PKTOPTIONS:
1745 /* 1745 /*
1746 * RFC3542 (effectively) deprecated the 1746 * RFC3542 (effectively) deprecated the
1747 * semantics of the 2292-style pktoptions. 1747 * semantics of the 2292-style pktoptions.
1748 * Since it was not reliable in nature (i.e., 1748 * Since it was not reliable in nature (i.e.,
1749 * applications had to expect the lack of some 1749 * applications had to expect the lack of some
1750 * information after all), it would make sense 1750 * information after all), it would make sense
1751 * to simplify this part by always returning 1751 * to simplify this part by always returning
1752 * empty data. 1752 * empty data.
1753 */ 1753 */
1754 break; 1754 break;
1755#endif 1755#endif
1756 1756
1757 case IPV6_RECVHOPOPTS: 1757 case IPV6_RECVHOPOPTS:
1758 case IPV6_RECVDSTOPTS: 1758 case IPV6_RECVDSTOPTS:
1759 case IPV6_RECVRTHDRDSTOPTS: 1759 case IPV6_RECVRTHDRDSTOPTS:
1760 case IPV6_UNICAST_HOPS: 1760 case IPV6_UNICAST_HOPS:
1761 case IPV6_RECVPKTINFO: 1761 case IPV6_RECVPKTINFO:
1762 case IPV6_RECVHOPLIMIT: 1762 case IPV6_RECVHOPLIMIT:
1763 case IPV6_RECVRTHDR: 1763 case IPV6_RECVRTHDR:
1764 case IPV6_RECVPATHMTU: 1764 case IPV6_RECVPATHMTU:
1765 1765
1766 case IPV6_FAITH: 1766 case IPV6_FAITH:
1767 case IPV6_V6ONLY: 1767 case IPV6_V6ONLY:
1768 case IPV6_PORTRANGE: 1768 case IPV6_PORTRANGE:
1769 case IPV6_RECVTCLASS: 1769 case IPV6_RECVTCLASS:
1770 case IPV6_BINDANY: 1770 case IPV6_BINDANY:
1771 switch (optname) { 1771 switch (optname) {
1772 1772
1773 case IPV6_RECVHOPOPTS: 1773 case IPV6_RECVHOPOPTS:
1774 optval = OPTBIT(IN6P_HOPOPTS); 1774 optval = OPTBIT(IN6P_HOPOPTS);
1775 break; 1775 break;
1776 1776
1777 case IPV6_RECVDSTOPTS: 1777 case IPV6_RECVDSTOPTS:
1778 optval = OPTBIT(IN6P_DSTOPTS); 1778 optval = OPTBIT(IN6P_DSTOPTS);
1779 break; 1779 break;
1780 1780
1781 case IPV6_RECVRTHDRDSTOPTS: 1781 case IPV6_RECVRTHDRDSTOPTS:
1782 optval = OPTBIT(IN6P_RTHDRDSTOPTS); 1782 optval = OPTBIT(IN6P_RTHDRDSTOPTS);
1783 break; 1783 break;
1784 1784
1785 case IPV6_UNICAST_HOPS: 1785 case IPV6_UNICAST_HOPS:
1786 optval = in6p->in6p_hops; 1786 optval = in6p->in6p_hops;
1787 break; 1787 break;
1788 1788
1789 case IPV6_RECVPKTINFO: 1789 case IPV6_RECVPKTINFO:
1790 optval = OPTBIT(IN6P_PKTINFO); 1790 optval = OPTBIT(IN6P_PKTINFO);
1791 break; 1791 break;
1792 1792
1793 case IPV6_RECVHOPLIMIT: 1793 case IPV6_RECVHOPLIMIT:
1794 optval = OPTBIT(IN6P_HOPLIMIT); 1794 optval = OPTBIT(IN6P_HOPLIMIT);
1795 break; 1795 break;
1796 1796
1797 case IPV6_RECVRTHDR: 1797 case IPV6_RECVRTHDR:
1798 optval = OPTBIT(IN6P_RTHDR); 1798 optval = OPTBIT(IN6P_RTHDR);
1799 break; 1799 break;
1800 1800
1801 case IPV6_RECVPATHMTU: 1801 case IPV6_RECVPATHMTU:
1802 optval = OPTBIT(IN6P_MTU); 1802 optval = OPTBIT(IN6P_MTU);
1803 break; 1803 break;
1804 1804
1805 case IPV6_FAITH: 1805 case IPV6_FAITH:
1806 optval = OPTBIT(IN6P_FAITH); 1806 optval = OPTBIT(IN6P_FAITH);
1807 break; 1807 break;
1808 1808
1809 case IPV6_V6ONLY: 1809 case IPV6_V6ONLY:
1810 optval = OPTBIT(IN6P_IPV6_V6ONLY); 1810 optval = OPTBIT(IN6P_IPV6_V6ONLY);
1811 break; 1811 break;
1812 1812
1813 case IPV6_PORTRANGE: 1813 case IPV6_PORTRANGE:
1814 { 1814 {
1815 int flags; 1815 int flags;
1816 flags = in6p->in6p_flags; 1816 flags = in6p->in6p_flags;
1817 if (flags & IN6P_HIGHPORT) 1817 if (flags & IN6P_HIGHPORT)
1818 optval = IPV6_PORTRANGE_HIGH; 1818 optval = IPV6_PORTRANGE_HIGH;
1819 else if (flags & IN6P_LOWPORT) 1819 else if (flags & IN6P_LOWPORT)
1820 optval = IPV6_PORTRANGE_LOW; 1820 optval = IPV6_PORTRANGE_LOW;
1821 else 1821 else
1822 optval = 0; 1822 optval = 0;
1823 break; 1823 break;
1824 } 1824 }
1825 case IPV6_RECVTCLASS: 1825 case IPV6_RECVTCLASS:
1826 optval = OPTBIT(IN6P_TCLASS); 1826 optval = OPTBIT(IN6P_TCLASS);
1827 break; 1827 break;
1828 1828
1829 case IPV6_BINDANY: 1829 case IPV6_BINDANY:
1830 optval = OPTBIT(IN6P_BINDANY); 1830 optval = OPTBIT(IN6P_BINDANY);
1831 break; 1831 break;
1832 } 1832 }
1833 1833
1834 if (error) 1834 if (error)
1835 break; 1835 break;
1836 error = sockopt_setint(sopt, optval); 1836 error = sockopt_setint(sopt, optval);
1837 break; 1837 break;
1838 1838
1839 case IPV6_PATHMTU: 1839 case IPV6_PATHMTU:
1840 { 1840 {
1841 u_long pmtu = 0; 1841 u_long pmtu = 0;
1842 struct ip6_mtuinfo mtuinfo; 1842 struct ip6_mtuinfo mtuinfo;
1843 struct route *ro = &in6p->in6p_route; 1843 struct route *ro = &in6p->in6p_route;
1844 struct rtentry *rt; 1844 struct rtentry *rt;
1845 union { 1845 union {
1846 struct sockaddr dst; 1846 struct sockaddr dst;
1847 struct sockaddr_in6 dst6; 1847 struct sockaddr_in6 dst6;
1848 } u; 1848 } u;
1849 1849
1850 if (!(so->so_state & SS_ISCONNECTED)) 1850 if (!(so->so_state & SS_ISCONNECTED))
1851 return (ENOTCONN); 1851 return (ENOTCONN);
1852 /* 1852 /*
1853 * XXX: we dot not consider the case of source 1853 * XXX: we dot not consider the case of source
1854 * routing, or optional information to specify 1854 * routing, or optional information to specify
1855 * the outgoing interface. 1855 * the outgoing interface.
1856 */ 1856 */
1857 sockaddr_in6_init(&u.dst6, &in6p->in6p_faddr, 0, 0, 0); 1857 sockaddr_in6_init(&u.dst6, &in6p->in6p_faddr, 0, 0, 0);
1858 rt = rtcache_lookup(ro, &u.dst); 1858 rt = rtcache_lookup(ro, &u.dst);
1859 error = ip6_getpmtu(rt, NULL, &pmtu, NULL); 1859 error = ip6_getpmtu(rt, NULL, &pmtu, NULL);
1860 rtcache_unref(rt, ro); 1860 rtcache_unref(rt, ro);
1861 if (error) 1861 if (error)
1862 break; 1862 break;
1863 if (pmtu > IPV6_MAXPACKET) 1863 if (pmtu > IPV6_MAXPACKET)
1864 pmtu = IPV6_MAXPACKET; 1864 pmtu = IPV6_MAXPACKET;
1865 1865
1866 memset(&mtuinfo, 0, sizeof(mtuinfo)); 1866 memset(&mtuinfo, 0, sizeof(mtuinfo));
1867 mtuinfo.ip6m_mtu = (u_int32_t)pmtu; 1867 mtuinfo.ip6m_mtu = (u_int32_t)pmtu;
1868 optdata = (void *)&mtuinfo; 1868 optdata = (void *)&mtuinfo;
1869 optdatalen = sizeof(mtuinfo); 1869 optdatalen = sizeof(mtuinfo);
1870 if (optdatalen > MCLBYTES) 1870 if (optdatalen > MCLBYTES)
1871 return (EMSGSIZE); /* XXX */ 1871 return (EMSGSIZE); /* XXX */
1872 error = sockopt_set(sopt, optdata, optdatalen); 1872 error = sockopt_set(sopt, optdata, optdatalen);
1873 break; 1873 break;
1874 } 1874 }
1875 1875
1876#ifdef RFC2292 1876#ifdef RFC2292
1877 case IPV6_2292PKTINFO: 1877 case IPV6_2292PKTINFO:
1878 case IPV6_2292HOPLIMIT: 1878 case IPV6_2292HOPLIMIT:
1879 case IPV6_2292HOPOPTS: 1879 case IPV6_2292HOPOPTS:
1880 case IPV6_2292RTHDR: 1880 case IPV6_2292RTHDR:
1881 case IPV6_2292DSTOPTS: 1881 case IPV6_2292DSTOPTS:
1882 switch (optname) { 1882 switch (optname) {
1883 case IPV6_2292PKTINFO: 1883 case IPV6_2292PKTINFO:
1884 optval = OPTBIT(IN6P_PKTINFO); 1884 optval = OPTBIT(IN6P_PKTINFO);
1885 break; 1885 break;
1886 case IPV6_2292HOPLIMIT: 1886 case IPV6_2292HOPLIMIT:
1887 optval = OPTBIT(IN6P_HOPLIMIT); 1887 optval = OPTBIT(IN6P_HOPLIMIT);
1888 break; 1888 break;
1889 case IPV6_2292HOPOPTS: 1889 case IPV6_2292HOPOPTS:
1890 optval = OPTBIT(IN6P_HOPOPTS); 1890 optval = OPTBIT(IN6P_HOPOPTS);
1891 break; 1891 break;