1 1.235 riastrad /* $NetBSD: ip6_output.c,v 1.235 2024/04/19 00:55:35 riastradh Exp $ */ 2 1.33 itojun /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ 3 1.3 thorpej 4 1.2 itojun /* 5 1.2 itojun * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 1.2 itojun * All rights reserved. 7 1.19 itojun * 8 1.2 itojun * Redistribution and use in source and binary forms, with or without 9 1.2 itojun * modification, are permitted provided that the following conditions 10 1.2 itojun * are met: 11 1.2 itojun * 1. Redistributions of source code must retain the above copyright 12 1.2 itojun * notice, this list of conditions and the following disclaimer. 13 1.2 itojun * 2. Redistributions in binary form must reproduce the above copyright 14 1.2 itojun * notice, this list of conditions and the following disclaimer in the 15 1.2 itojun * documentation and/or other materials provided with the distribution. 16 1.2 itojun * 3. Neither the name of the project nor the names of its contributors 17 1.2 itojun * may be used to endorse or promote products derived from this software 18 1.2 itojun * without specific prior written permission. 19 1.19 itojun * 20 1.2 itojun * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 1.2 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 1.2 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 1.2 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 1.2 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 1.2 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 1.2 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.2 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.2 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.2 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.2 itojun * SUCH DAMAGE. 31 1.2 itojun */ 32 1.2 itojun 33 1.2 itojun /* 34 1.2 itojun * Copyright (c) 1982, 1986, 1988, 1990, 1993 35 1.2 itojun * The Regents of the University of California. All rights reserved. 36 1.2 itojun * 37 1.2 itojun * Redistribution and use in source and binary forms, with or without 38 1.2 itojun * modification, are permitted provided that the following conditions 39 1.2 itojun * are met: 40 1.2 itojun * 1. Redistributions of source code must retain the above copyright 41 1.2 itojun * notice, this list of conditions and the following disclaimer. 42 1.2 itojun * 2. Redistributions in binary form must reproduce the above copyright 43 1.2 itojun * notice, this list of conditions and the following disclaimer in the 44 1.2 itojun * documentation and/or other materials provided with the distribution. 45 1.62 agc * 3. Neither the name of the University nor the names of its contributors 46 1.2 itojun * may be used to endorse or promote products derived from this software 47 1.2 itojun * without specific prior written permission. 48 1.2 itojun * 49 1.2 itojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 1.2 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 1.2 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 1.2 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 1.2 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 1.2 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 1.2 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 1.2 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 1.2 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 1.2 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 1.2 itojun * SUCH DAMAGE. 60 1.2 itojun * 61 1.2 itojun * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 62 1.2 itojun */ 63 1.41 lukem 64 1.41 lukem #include <sys/cdefs.h> 65 1.235 riastrad __KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.235 2024/04/19 00:55:35 riastradh Exp $"); 66 1.2 itojun 67 1.166 pooka #ifdef _KERNEL_OPT 68 1.2 itojun #include "opt_inet.h" 69 1.97 rpaulo #include "opt_inet6.h" 70 1.4 thorpej #include "opt_ipsec.h" 71 1.166 pooka #endif 72 1.2 itojun 73 1.2 itojun #include <sys/param.h> 74 1.2 itojun #include <sys/malloc.h> 75 1.2 itojun #include <sys/mbuf.h> 76 1.2 itojun #include <sys/errno.h> 77 1.2 itojun #include <sys/socket.h> 78 1.2 itojun #include <sys/socketvar.h> 79 1.174 roy #include <sys/syslog.h> 80 1.2 itojun #include <sys/systm.h> 81 1.2 itojun #include <sys/proc.h> 82 1.98 elad #include <sys/kauth.h> 83 1.2 itojun 84 1.2 itojun #include <net/if.h> 85 1.2 itojun #include <net/route.h> 86 1.15 darrenr #include <net/pfil.h> 87 1.2 itojun 88 1.2 itojun #include <netinet/in.h> 89 1.2 itojun #include <netinet/in_var.h> 90 1.14 itojun #include <netinet/ip6.h> 91 1.159 christos #include <netinet/ip_var.h> 92 1.14 itojun #include <netinet/icmp6.h> 93 1.90 yamt #include <netinet/in_offload.h> 94 1.149 christos #include <netinet/portalgo.h> 95 1.105 yamt #include <netinet6/in6_offload.h> 96 1.10 itojun #include <netinet6/ip6_var.h> 97 1.128 thorpej #include <netinet6/ip6_private.h> 98 1.2 itojun #include <netinet6/in6_pcb.h> 99 1.2 itojun #include <netinet6/nd6.h> 100 1.78 itojun #include <netinet6/ip6protosw.h> 101 1.94 rpaulo #include <netinet6/scope6_var.h> 102 1.2 itojun 103 1.153 christos #ifdef IPSEC 104 1.114 degroote #include <netipsec/ipsec.h> 105 1.114 degroote #include <netipsec/ipsec6.h> 106 1.114 degroote #include <netipsec/key.h> 107 1.114 degroote #endif 108 1.114 degroote 109 1.154 rmind extern pfil_head_t *inet6_pfil_hook; /* XXX */ 110 1.27 thorpej 111 1.2 itojun struct ip6_exthdrs { 112 1.2 itojun struct mbuf *ip6e_ip6; 113 1.2 itojun struct mbuf *ip6e_hbh; 114 1.2 itojun struct mbuf *ip6e_dest1; 115 1.2 itojun struct mbuf *ip6e_rthdr; 116 1.2 itojun struct mbuf *ip6e_dest2; 117 1.2 itojun }; 118 1.2 itojun 119 1.122 dyoung static int ip6_pcbopt(int, u_char *, int, struct ip6_pktopts **, 120 1.138 elad kauth_cred_t, int); 121 1.130 plunky static int ip6_getpcbopt(struct ip6_pktopts *, int, struct sockopt *); 122 1.138 elad static int ip6_setpktopt(int, u_char *, int, struct ip6_pktopts *, kauth_cred_t, 123 1.122 dyoung int, int, int); 124 1.230 ozaki static int ip6_setmoptions(const struct sockopt *, struct inpcb *); 125 1.230 ozaki static int ip6_getmoptions(struct sockopt *, struct inpcb *); 126 1.122 dyoung static int ip6_copyexthdr(struct mbuf **, void *, int); 127 1.122 dyoung static int ip6_insertfraghdr(struct mbuf *, struct mbuf *, int, 128 1.122 dyoung struct ip6_frag **); 129 1.122 dyoung static int ip6_insert_jumboopt(struct ip6_exthdrs *, u_int32_t); 130 1.122 dyoung static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *); 131 1.176 ozaki static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *); 132 1.122 dyoung static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); 133 1.194 roy static int ip6_ifaddrvalid(const struct in6_addr *, const struct in6_addr *); 134 1.177 ozaki static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *); 135 1.97 rpaulo 136 1.97 rpaulo #ifdef RFC2292 137 1.130 plunky static int ip6_pcbopts(struct ip6_pktopts **, struct socket *, struct sockopt *); 138 1.97 rpaulo #endif 139 1.2 itojun 140 1.177 ozaki static int 141 1.177 ozaki ip6_handle_rthdr(struct ip6_rthdr *rh, struct ip6_hdr *ip6) 142 1.177 ozaki { 143 1.177 ozaki int error = 0; 144 1.177 ozaki 145 1.177 ozaki switch (rh->ip6r_type) { 146 1.177 ozaki case IPV6_RTHDR_TYPE_0: 147 1.205 maxv /* Dropped, RFC5095. */ 148 1.177 ozaki default: /* is it possible? */ 149 1.197 maxv error = EINVAL; 150 1.177 ozaki } 151 1.177 ozaki 152 1.177 ozaki return error; 153 1.177 ozaki } 154 1.177 ozaki 155 1.2 itojun /* 156 1.183 ozaki * Send an IP packet to a host. 157 1.183 ozaki */ 158 1.183 ozaki int 159 1.183 ozaki ip6_if_output(struct ifnet * const ifp, struct ifnet * const origifp, 160 1.197 maxv struct mbuf * const m, const struct sockaddr_in6 * const dst, 161 1.197 maxv const struct rtentry *rt) 162 1.183 ozaki { 163 1.183 ozaki int error = 0; 164 1.183 ozaki 165 1.183 ozaki if (rt != NULL) { 166 1.183 ozaki error = rt_check_reject_route(rt, ifp); 167 1.183 ozaki if (error != 0) { 168 1.225 ozaki IP6_STATINC(IP6_STAT_RTREJECT); 169 1.183 ozaki m_freem(m); 170 1.183 ozaki return error; 171 1.183 ozaki } 172 1.183 ozaki } 173 1.183 ozaki 174 1.234 ozaki /* discard the packet if IPv6 operation is disabled on the interface */ 175 1.234 ozaki if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { 176 1.234 ozaki m_freem(m); 177 1.234 ozaki return ENETDOWN; /* better error? */ 178 1.234 ozaki } 179 1.234 ozaki 180 1.183 ozaki if ((ifp->if_flags & IFF_LOOPBACK) != 0) 181 1.183 ozaki error = if_output_lock(ifp, origifp, m, sin6tocsa(dst), rt); 182 1.183 ozaki else 183 1.183 ozaki error = if_output_lock(ifp, ifp, m, sin6tocsa(dst), rt); 184 1.183 ozaki return error; 185 1.183 ozaki } 186 1.183 ozaki 187 1.183 ozaki /* 188 1.2 itojun * IP6 output. The packet in mbuf chain m contains a skeletal IP6 189 1.2 itojun * header (with pri, len, nxt, hlim, src, dst). 190 1.52 itojun * 191 1.197 maxv * This function may modify ver and hlim only. The mbuf chain containing the 192 1.197 maxv * packet will be freed. The mbuf opt, if present, will not be freed. 193 1.197 maxv * 194 1.197 maxv * Type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and 195 1.197 maxv * nd_ifinfo.linkmtu is u_int32_t. So we use u_long to hold largest one, 196 1.52 itojun * which is rt_rmx.rmx_mtu. 197 1.2 itojun */ 198 1.2 itojun int 199 1.103 christos ip6_output( 200 1.103 christos struct mbuf *m0, 201 1.103 christos struct ip6_pktopts *opt, 202 1.118 dyoung struct route *ro, 203 1.103 christos int flags, 204 1.103 christos struct ip6_moptions *im6o, 205 1.230 ozaki struct inpcb *inp, 206 1.103 christos struct ifnet **ifpp /* XXX: just for statistics */ 207 1.103 christos ) 208 1.2 itojun { 209 1.2 itojun struct ip6_hdr *ip6, *mhip6; 210 1.171 christos struct ifnet *ifp = NULL, *origifp = NULL; 211 1.2 itojun struct mbuf *m = m0; 212 1.197 maxv int tlen, len, off; 213 1.116 thorpej bool tso; 214 1.118 dyoung struct route ip6route; 215 1.176 ozaki struct rtentry *rt = NULL, *rt_pmtu; 216 1.164 ozaki const struct sockaddr_in6 *dst; 217 1.118 dyoung struct sockaddr_in6 src_sa, dst_sa; 218 1.2 itojun int error = 0; 219 1.94 rpaulo struct in6_ifaddr *ia = NULL; 220 1.2 itojun u_long mtu; 221 1.78 itojun int alwaysfrag, dontfrag; 222 1.2 itojun u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; 223 1.2 itojun struct ip6_exthdrs exthdrs; 224 1.94 rpaulo struct in6_addr finaldst, src0, dst0; 225 1.94 rpaulo u_int32_t zone; 226 1.118 dyoung struct route *ro_pmtu = NULL; 227 1.2 itojun int hdrsplit = 0; 228 1.2 itojun int needipsec = 0; 229 1.153 christos #ifdef IPSEC 230 1.114 degroote struct secpolicy *sp = NULL; 231 1.114 degroote #endif 232 1.170 ozaki struct psref psref, psref_ia; 233 1.170 ozaki int bound = curlwp_bind(); 234 1.170 ozaki bool release_psref_ia = false; 235 1.114 degroote 236 1.197 maxv #ifdef DIAGNOSTIC 237 1.100 tron if ((m->m_flags & M_PKTHDR) == 0) 238 1.100 tron panic("ip6_output: no HDR"); 239 1.100 tron if ((m->m_pkthdr.csum_flags & 240 1.100 tron (M_CSUM_TCPv4|M_CSUM_UDPv4|M_CSUM_TSOv4)) != 0) { 241 1.100 tron panic("ip6_output: IPv4 checksum offload flags: %d", 242 1.100 tron m->m_pkthdr.csum_flags); 243 1.100 tron } 244 1.100 tron if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) == 245 1.100 tron (M_CSUM_TCPv6|M_CSUM_UDPv6)) { 246 1.100 tron panic("ip6_output: conflicting checksum offload flags: %d", 247 1.100 tron m->m_pkthdr.csum_flags); 248 1.100 tron } 249 1.100 tron #endif 250 1.100 tron 251 1.211 maxv M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data, sizeof(struct ip6_hdr)); 252 1.89 yamt 253 1.22 itojun #define MAKE_EXTHDR(hp, mp) \ 254 1.22 itojun do { \ 255 1.2 itojun if (hp) { \ 256 1.2 itojun struct ip6_ext *eh = (struct ip6_ext *)(hp); \ 257 1.117 christos error = ip6_copyexthdr((mp), (void *)(hp), \ 258 1.49 itojun ((eh)->ip6e_len + 1) << 3); \ 259 1.2 itojun if (error) \ 260 1.2 itojun goto freehdrs; \ 261 1.2 itojun } \ 262 1.60 perry } while (/*CONSTCOND*/ 0) 263 1.51 itojun 264 1.136 cegger memset(&exthdrs, 0, sizeof(exthdrs)); 265 1.2 itojun if (opt) { 266 1.2 itojun /* Hop-by-Hop options header */ 267 1.2 itojun MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh); 268 1.197 maxv /* Destination options header (1st part) */ 269 1.2 itojun MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1); 270 1.2 itojun /* Routing header */ 271 1.2 itojun MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr); 272 1.197 maxv /* Destination options header (2nd part) */ 273 1.2 itojun MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2); 274 1.2 itojun } 275 1.2 itojun 276 1.2 itojun /* 277 1.2 itojun * Calculate the total length of the extension header chain. 278 1.2 itojun * Keep the length of the unfragmentable part for fragmentation. 279 1.2 itojun */ 280 1.9 itojun optlen = 0; 281 1.197 maxv if (exthdrs.ip6e_hbh) 282 1.197 maxv optlen += exthdrs.ip6e_hbh->m_len; 283 1.197 maxv if (exthdrs.ip6e_dest1) 284 1.197 maxv optlen += exthdrs.ip6e_dest1->m_len; 285 1.197 maxv if (exthdrs.ip6e_rthdr) 286 1.197 maxv optlen += exthdrs.ip6e_rthdr->m_len; 287 1.9 itojun unfragpartlen = optlen + sizeof(struct ip6_hdr); 288 1.2 itojun /* NOTE: we don't add AH/ESP length here. do that later. */ 289 1.197 maxv if (exthdrs.ip6e_dest2) 290 1.197 maxv optlen += exthdrs.ip6e_dest2->m_len; 291 1.2 itojun 292 1.153 christos #ifdef IPSEC 293 1.157 christos if (ipsec_used) { 294 1.157 christos /* Check the security policy (SP) for the packet */ 295 1.230 ozaki sp = ipsec6_check_policy(m, inp, flags, &needipsec, &error); 296 1.157 christos if (error != 0) { 297 1.157 christos /* 298 1.157 christos * Hack: -EINVAL is used to signal that a packet 299 1.157 christos * should be silently discarded. This is typically 300 1.157 christos * because we asked key management for an SA and 301 1.157 christos * it was delayed (e.g. kicked up to IKE). 302 1.157 christos */ 303 1.197 maxv if (error == -EINVAL) 304 1.157 christos error = 0; 305 1.224 ozaki IP6_STATINC(IP6_STAT_IPSECDROP_OUT); 306 1.157 christos goto freehdrs; 307 1.157 christos } 308 1.157 christos } 309 1.197 maxv #endif 310 1.114 degroote 311 1.114 degroote if (needipsec && 312 1.114 degroote (m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { 313 1.212 maxv in6_undefer_cksum_tcpudp(m); 314 1.114 degroote m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 315 1.114 degroote } 316 1.114 degroote 317 1.2 itojun /* 318 1.2 itojun * If we need IPsec, or there is at least one extension header, 319 1.2 itojun * separate IP6 header from the payload. 320 1.2 itojun */ 321 1.2 itojun if ((needipsec || optlen) && !hdrsplit) { 322 1.2 itojun if ((error = ip6_splithdr(m, &exthdrs)) != 0) { 323 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 324 1.2 itojun m = NULL; 325 1.2 itojun goto freehdrs; 326 1.2 itojun } 327 1.2 itojun m = exthdrs.ip6e_ip6; 328 1.2 itojun hdrsplit++; 329 1.2 itojun } 330 1.2 itojun 331 1.2 itojun /* adjust pointer */ 332 1.2 itojun ip6 = mtod(m, struct ip6_hdr *); 333 1.2 itojun 334 1.2 itojun /* adjust mbuf packet header length */ 335 1.2 itojun m->m_pkthdr.len += optlen; 336 1.2 itojun plen = m->m_pkthdr.len - sizeof(*ip6); 337 1.2 itojun 338 1.2 itojun /* If this is a jumbo payload, insert a jumbo payload option. */ 339 1.2 itojun if (plen > IPV6_MAXPACKET) { 340 1.2 itojun if (!hdrsplit) { 341 1.2 itojun if ((error = ip6_splithdr(m, &exthdrs)) != 0) { 342 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 343 1.2 itojun m = NULL; 344 1.2 itojun goto freehdrs; 345 1.2 itojun } 346 1.2 itojun m = exthdrs.ip6e_ip6; 347 1.2 itojun hdrsplit++; 348 1.2 itojun } 349 1.2 itojun /* adjust pointer */ 350 1.2 itojun ip6 = mtod(m, struct ip6_hdr *); 351 1.225 ozaki if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0) { 352 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 353 1.2 itojun goto freehdrs; 354 1.225 ozaki } 355 1.89 yamt optlen += 8; /* XXX JUMBOOPTLEN */ 356 1.2 itojun ip6->ip6_plen = 0; 357 1.2 itojun } else 358 1.2 itojun ip6->ip6_plen = htons(plen); 359 1.2 itojun 360 1.2 itojun /* 361 1.2 itojun * Concatenate headers and fill in next header fields. 362 1.2 itojun * Here we have, on "m" 363 1.9 itojun * IPv6 payload 364 1.2 itojun * and we insert headers accordingly. Finally, we should be getting: 365 1.2 itojun * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload] 366 1.9 itojun * 367 1.9 itojun * during the header composing process, "m" points to IPv6 header. 368 1.9 itojun * "mprev" points to an extension header prior to esp. 369 1.2 itojun */ 370 1.2 itojun { 371 1.2 itojun u_char *nexthdrp = &ip6->ip6_nxt; 372 1.2 itojun struct mbuf *mprev = m; 373 1.2 itojun 374 1.2 itojun /* 375 1.2 itojun * we treat dest2 specially. this makes IPsec processing 376 1.78 itojun * much easier. the goal here is to make mprev point the 377 1.78 itojun * mbuf prior to dest2. 378 1.9 itojun * 379 1.9 itojun * result: IPv6 dest2 payload 380 1.9 itojun * m and mprev will point to IPv6 header. 381 1.2 itojun */ 382 1.2 itojun if (exthdrs.ip6e_dest2) { 383 1.2 itojun if (!hdrsplit) 384 1.2 itojun panic("assumption failed: hdr not split"); 385 1.9 itojun exthdrs.ip6e_dest2->m_next = m->m_next; 386 1.9 itojun m->m_next = exthdrs.ip6e_dest2; 387 1.2 itojun *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt; 388 1.2 itojun ip6->ip6_nxt = IPPROTO_DSTOPTS; 389 1.2 itojun } 390 1.2 itojun 391 1.22 itojun #define MAKE_CHAIN(m, mp, p, i)\ 392 1.22 itojun do {\ 393 1.2 itojun if (m) {\ 394 1.2 itojun if (!hdrsplit) \ 395 1.2 itojun panic("assumption failed: hdr not split"); \ 396 1.2 itojun *mtod((m), u_char *) = *(p);\ 397 1.2 itojun *(p) = (i);\ 398 1.2 itojun p = mtod((m), u_char *);\ 399 1.2 itojun (m)->m_next = (mp)->m_next;\ 400 1.2 itojun (mp)->m_next = (m);\ 401 1.2 itojun (mp) = (m);\ 402 1.2 itojun }\ 403 1.60 perry } while (/*CONSTCOND*/ 0) 404 1.9 itojun /* 405 1.9 itojun * result: IPv6 hbh dest1 rthdr dest2 payload 406 1.9 itojun * m will point to IPv6 header. mprev will point to the 407 1.9 itojun * extension header prior to dest2 (rthdr in the above case). 408 1.9 itojun */ 409 1.49 itojun MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS); 410 1.49 itojun MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp, 411 1.49 itojun IPPROTO_DSTOPTS); 412 1.49 itojun MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp, 413 1.49 itojun IPPROTO_ROUTING); 414 1.2 itojun 415 1.211 maxv M_CSUM_DATA_IPv6_SET(m->m_pkthdr.csum_data, 416 1.89 yamt sizeof(struct ip6_hdr) + optlen); 417 1.2 itojun } 418 1.2 itojun 419 1.178 ozaki /* Need to save for pmtu */ 420 1.178 ozaki finaldst = ip6->ip6_dst; 421 1.178 ozaki 422 1.2 itojun /* 423 1.2 itojun * If there is a routing header, replace destination address field 424 1.2 itojun * with the first hop of the routing header. 425 1.2 itojun */ 426 1.2 itojun if (exthdrs.ip6e_rthdr) { 427 1.49 itojun struct ip6_rthdr *rh; 428 1.2 itojun 429 1.197 maxv rh = mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *); 430 1.94 rpaulo 431 1.177 ozaki error = ip6_handle_rthdr(rh, ip6); 432 1.225 ozaki if (error != 0) { 433 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 434 1.177 ozaki goto bad; 435 1.225 ozaki } 436 1.2 itojun } 437 1.2 itojun 438 1.2 itojun /* Source address validation */ 439 1.2 itojun if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && 440 1.54 itojun (flags & IPV6_UNSPECSRC) == 0) { 441 1.2 itojun error = EOPNOTSUPP; 442 1.128 thorpej IP6_STATINC(IP6_STAT_BADSCOPE); 443 1.2 itojun goto bad; 444 1.2 itojun } 445 1.2 itojun if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { 446 1.2 itojun error = EOPNOTSUPP; 447 1.128 thorpej IP6_STATINC(IP6_STAT_BADSCOPE); 448 1.2 itojun goto bad; 449 1.2 itojun } 450 1.2 itojun 451 1.128 thorpej IP6_STATINC(IP6_STAT_LOCALOUT); 452 1.2 itojun 453 1.2 itojun /* 454 1.2 itojun * Route packet. 455 1.2 itojun */ 456 1.78 itojun /* initialize cached route */ 457 1.113 dyoung if (ro == NULL) { 458 1.172 ozaki memset(&ip6route, 0, sizeof(ip6route)); 459 1.2 itojun ro = &ip6route; 460 1.2 itojun } 461 1.2 itojun ro_pmtu = ro; 462 1.2 itojun if (opt && opt->ip6po_rthdr) 463 1.2 itojun ro = &opt->ip6po_route; 464 1.94 rpaulo 465 1.197 maxv /* 466 1.94 rpaulo * if specified, try to fill in the traffic class field. 467 1.94 rpaulo * do not override if a non-zero value is already set. 468 1.94 rpaulo * we check the diffserv field and the ecn field separately. 469 1.94 rpaulo */ 470 1.94 rpaulo if (opt && opt->ip6po_tclass >= 0) { 471 1.94 rpaulo int mask = 0; 472 1.94 rpaulo 473 1.94 rpaulo if ((ip6->ip6_flow & htonl(0xfc << 20)) == 0) 474 1.94 rpaulo mask |= 0xfc; 475 1.94 rpaulo if ((ip6->ip6_flow & htonl(0x03 << 20)) == 0) 476 1.94 rpaulo mask |= 0x03; 477 1.94 rpaulo if (mask != 0) 478 1.94 rpaulo ip6->ip6_flow |= htonl((opt->ip6po_tclass & mask) << 20); 479 1.2 itojun } 480 1.94 rpaulo 481 1.94 rpaulo /* fill in or override the hop limit field, if necessary. */ 482 1.94 rpaulo if (opt && opt->ip6po_hlim != -1) 483 1.94 rpaulo ip6->ip6_hlim = opt->ip6po_hlim & 0xff; 484 1.94 rpaulo else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 485 1.94 rpaulo if (im6o != NULL) 486 1.94 rpaulo ip6->ip6_hlim = im6o->im6o_multicast_hlim; 487 1.94 rpaulo else 488 1.94 rpaulo ip6->ip6_hlim = ip6_defmcasthlim; 489 1.2 itojun } 490 1.94 rpaulo 491 1.153 christos #ifdef IPSEC 492 1.114 degroote if (needipsec) { 493 1.221 knakahar error = ipsec6_process_packet(m, sp->req, flags); 494 1.114 degroote 495 1.114 degroote /* 496 1.114 degroote * Preserve KAME behaviour: ENOENT can be returned 497 1.114 degroote * when an SA acquire is in progress. Don't propagate 498 1.114 degroote * this to user-level; it confuses applications. 499 1.114 degroote * XXX this will go away when the SADB is redone. 500 1.114 degroote */ 501 1.114 degroote if (error == ENOENT) 502 1.114 degroote error = 0; 503 1.197 maxv 504 1.114 degroote goto done; 505 1.118 dyoung } 506 1.197 maxv #endif 507 1.114 degroote 508 1.94 rpaulo /* adjust pointer */ 509 1.94 rpaulo ip6 = mtod(m, struct ip6_hdr *); 510 1.2 itojun 511 1.123 dyoung sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0); 512 1.178 ozaki 513 1.178 ozaki /* We do not need a route for multicast */ 514 1.178 ozaki if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 515 1.178 ozaki struct in6_pktinfo *pi = NULL; 516 1.178 ozaki 517 1.178 ozaki /* 518 1.178 ozaki * If the outgoing interface for the address is specified by 519 1.178 ozaki * the caller, use it. 520 1.178 ozaki */ 521 1.178 ozaki if (opt && (pi = opt->ip6po_pktinfo) != NULL) { 522 1.178 ozaki /* XXX boundary check is assumed to be already done. */ 523 1.178 ozaki ifp = if_get_byindex(pi->ipi6_ifindex, &psref); 524 1.178 ozaki } else if (im6o != NULL) { 525 1.178 ozaki ifp = if_get_byindex(im6o->im6o_multicast_if_index, 526 1.178 ozaki &psref); 527 1.178 ozaki } 528 1.178 ozaki } 529 1.178 ozaki 530 1.178 ozaki if (ifp == NULL) { 531 1.178 ozaki error = in6_selectroute(&dst_sa, opt, &ro, &rt, true); 532 1.178 ozaki if (error != 0) 533 1.178 ozaki goto bad; 534 1.178 ozaki ifp = if_get_byindex(rt->rt_ifp->if_index, &psref); 535 1.94 rpaulo } 536 1.178 ozaki 537 1.94 rpaulo if (rt == NULL) { 538 1.94 rpaulo /* 539 1.94 rpaulo * If in6_selectroute() does not return a route entry, 540 1.94 rpaulo * dst may not have been updated. 541 1.94 rpaulo */ 542 1.145 rmind error = rtcache_setdst(ro, sin6tosa(&dst_sa)); 543 1.145 rmind if (error) { 544 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 545 1.145 rmind goto bad; 546 1.145 rmind } 547 1.94 rpaulo } 548 1.2 itojun 549 1.94 rpaulo /* 550 1.94 rpaulo * then rt (for unicast) and ifp must be non-NULL valid values. 551 1.94 rpaulo */ 552 1.94 rpaulo if ((flags & IPV6_FORWARDING) == 0) { 553 1.94 rpaulo /* XXX: the FORWARDING flag can be set for mrouting. */ 554 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_request); 555 1.94 rpaulo } 556 1.94 rpaulo if (rt != NULL) { 557 1.94 rpaulo ia = (struct in6_ifaddr *)(rt->rt_ifa); 558 1.94 rpaulo rt->rt_use++; 559 1.94 rpaulo } 560 1.9 itojun 561 1.94 rpaulo /* 562 1.94 rpaulo * The outgoing interface must be in the zone of source and 563 1.94 rpaulo * destination addresses. We should use ia_ifp to support the 564 1.94 rpaulo * case of sending packets to an address of our own. 565 1.94 rpaulo */ 566 1.222 ozaki if (ia != NULL) { 567 1.94 rpaulo origifp = ia->ia_ifp; 568 1.225 ozaki if (if_is_deactivated(origifp)) { 569 1.225 ozaki IP6_STATINC(IP6_STAT_ODROPPED); 570 1.173 ozaki goto bad; 571 1.225 ozaki } 572 1.184 ozaki if_acquire(origifp, &psref_ia); 573 1.170 ozaki release_psref_ia = true; 574 1.170 ozaki } else 575 1.94 rpaulo origifp = ifp; 576 1.2 itojun 577 1.94 rpaulo src0 = ip6->ip6_src; 578 1.94 rpaulo if (in6_setscope(&src0, origifp, &zone)) 579 1.94 rpaulo goto badscope; 580 1.123 dyoung sockaddr_in6_init(&src_sa, &ip6->ip6_src, 0, 0, 0); 581 1.94 rpaulo if (sa6_recoverscope(&src_sa) || zone != src_sa.sin6_scope_id) 582 1.94 rpaulo goto badscope; 583 1.94 rpaulo 584 1.94 rpaulo dst0 = ip6->ip6_dst; 585 1.94 rpaulo if (in6_setscope(&dst0, origifp, &zone)) 586 1.94 rpaulo goto badscope; 587 1.94 rpaulo /* re-initialize to be sure */ 588 1.123 dyoung sockaddr_in6_init(&dst_sa, &ip6->ip6_dst, 0, 0, 0); 589 1.94 rpaulo if (sa6_recoverscope(&dst_sa) || zone != dst_sa.sin6_scope_id) 590 1.94 rpaulo goto badscope; 591 1.94 rpaulo 592 1.94 rpaulo /* scope check is done. */ 593 1.94 rpaulo 594 1.175 roy /* Ensure we only send from a valid address. */ 595 1.194 roy if ((ifp->if_flags & IFF_LOOPBACK) == 0 && 596 1.213 ozaki (flags & IPV6_FORWARDING) == 0 && 597 1.194 roy (error = ip6_ifaddrvalid(&src0, &dst0)) != 0) 598 1.194 roy { 599 1.181 ryo char ip6buf[INET6_ADDRSTRLEN]; 600 1.174 roy nd6log(LOG_ERR, 601 1.174 roy "refusing to send from invalid address %s (pid %d)\n", 602 1.182 christos IN6_PRINT(ip6buf, &src0), curproc->p_pid); 603 1.175 roy IP6_STATINC(IP6_STAT_ODROPPED); 604 1.175 roy in6_ifstat_inc(origifp, ifs6_out_discard); 605 1.175 roy if (error == 1) 606 1.175 roy /* 607 1.175 roy * Address exists, but is tentative or detached. 608 1.174 roy * We can't send from it because it's invalid, 609 1.175 roy * so we drop the packet. 610 1.175 roy */ 611 1.174 roy error = 0; 612 1.174 roy else 613 1.174 roy error = EADDRNOTAVAIL; 614 1.174 roy goto bad; 615 1.174 roy } 616 1.174 roy 617 1.178 ozaki if (rt != NULL && (rt->rt_flags & RTF_GATEWAY) && 618 1.178 ozaki !IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) 619 1.178 ozaki dst = satocsin6(rt->rt_gateway); 620 1.164 ozaki else 621 1.118 dyoung dst = satocsin6(rtcache_getdst(ro)); 622 1.2 itojun 623 1.94 rpaulo /* 624 1.94 rpaulo * XXXXXX: original code follows: 625 1.94 rpaulo */ 626 1.94 rpaulo if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) 627 1.94 rpaulo m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */ 628 1.94 rpaulo else { 629 1.187 ozaki bool ingroup; 630 1.2 itojun 631 1.94 rpaulo m->m_flags = (m->m_flags & ~M_BCAST) | M_MCAST; 632 1.9 itojun 633 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_mcast); 634 1.9 itojun 635 1.2 itojun /* 636 1.2 itojun * Confirm that the outgoing interface supports multicast. 637 1.2 itojun */ 638 1.94 rpaulo if (!(ifp->if_flags & IFF_MULTICAST)) { 639 1.128 thorpej IP6_STATINC(IP6_STAT_NOROUTE); 640 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_discard); 641 1.2 itojun error = ENETUNREACH; 642 1.2 itojun goto bad; 643 1.2 itojun } 644 1.94 rpaulo 645 1.187 ozaki ingroup = in6_multi_group(&ip6->ip6_dst, ifp); 646 1.187 ozaki if (ingroup && (im6o == NULL || im6o->im6o_multicast_loop)) { 647 1.2 itojun /* 648 1.2 itojun * If we belong to the destination multicast group 649 1.2 itojun * on the outgoing interface, and the caller did not 650 1.2 itojun * forbid loopback, loop back a copy. 651 1.2 itojun */ 652 1.118 dyoung KASSERT(dst != NULL); 653 1.2 itojun ip6_mloopback(ifp, m, dst); 654 1.2 itojun } else { 655 1.2 itojun /* 656 1.2 itojun * If we are acting as a multicast router, perform 657 1.2 itojun * multicast forwarding as if the packet had just 658 1.2 itojun * arrived on the interface to which we are about 659 1.2 itojun * to send. The multicast forwarding function 660 1.2 itojun * recursively calls this function, using the 661 1.2 itojun * IPV6_FORWARDING flag to prevent infinite recursion. 662 1.2 itojun * 663 1.2 itojun * Multicasts that are looped back by ip6_mloopback(), 664 1.2 itojun * above, will be forwarded by the ip6_input() routine, 665 1.2 itojun * if necessary. 666 1.2 itojun */ 667 1.2 itojun if (ip6_mrouter && (flags & IPV6_FORWARDING) == 0) { 668 1.20 thorpej if (ip6_mforward(ip6, ifp, m) != 0) { 669 1.2 itojun m_freem(m); 670 1.2 itojun goto done; 671 1.2 itojun } 672 1.2 itojun } 673 1.2 itojun } 674 1.2 itojun /* 675 1.2 itojun * Multicasts with a hoplimit of zero may be looped back, 676 1.2 itojun * above, but must not be transmitted on a network. 677 1.2 itojun * Also, multicasts addressed to the loopback interface 678 1.2 itojun * are not sent -- the above call to ip6_mloopback() will 679 1.2 itojun * loop back a copy if this host actually belongs to the 680 1.2 itojun * destination group on the loopback interface. 681 1.2 itojun */ 682 1.94 rpaulo if (ip6->ip6_hlim == 0 || (ifp->if_flags & IFF_LOOPBACK) || 683 1.94 rpaulo IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)) { 684 1.2 itojun m_freem(m); 685 1.2 itojun goto done; 686 1.2 itojun } 687 1.2 itojun } 688 1.2 itojun 689 1.2 itojun /* 690 1.228 andvar * Fill the outgoing interface to tell the upper layer 691 1.9 itojun * to increment per-interface statistics. 692 1.9 itojun */ 693 1.9 itojun if (ifpp) 694 1.9 itojun *ifpp = ifp; 695 1.9 itojun 696 1.45 itojun /* Determine path MTU. */ 697 1.176 ozaki /* 698 1.176 ozaki * ro_pmtu represent final destination while 699 1.176 ozaki * ro might represent immediate destination. 700 1.176 ozaki * Use ro_pmtu destination since MTU might differ. 701 1.176 ozaki */ 702 1.176 ozaki if (ro_pmtu != ro) { 703 1.176 ozaki union { 704 1.176 ozaki struct sockaddr dst; 705 1.176 ozaki struct sockaddr_in6 dst6; 706 1.176 ozaki } u; 707 1.176 ozaki 708 1.176 ozaki /* ro_pmtu may not have a cache */ 709 1.176 ozaki sockaddr_in6_init(&u.dst6, &finaldst, 0, 0, 0); 710 1.176 ozaki rt_pmtu = rtcache_lookup(ro_pmtu, &u.dst); 711 1.176 ozaki } else 712 1.179 ozaki rt_pmtu = rt; 713 1.176 ozaki error = ip6_getpmtu(rt_pmtu, ifp, &mtu, &alwaysfrag); 714 1.179 ozaki if (rt_pmtu != NULL && rt_pmtu != rt) 715 1.179 ozaki rtcache_unref(rt_pmtu, ro_pmtu); 716 1.225 ozaki KASSERT(error == 0); /* ip6_getpmtu never fail if ifp is passed */ 717 1.45 itojun 718 1.9 itojun /* 719 1.45 itojun * The caller of this function may specify to use the minimum MTU 720 1.45 itojun * in some cases. 721 1.97 rpaulo * An advanced API option (IPV6_USE_MIN_MTU) can also override MTU 722 1.97 rpaulo * setting. The logic is a bit complicated; by default, unicast 723 1.97 rpaulo * packets will follow path MTU while multicast packets will be sent at 724 1.97 rpaulo * the minimum MTU. If IP6PO_MINMTU_ALL is specified, all packets 725 1.97 rpaulo * including unicast ones will be sent at the minimum MTU. Multicast 726 1.97 rpaulo * packets will always be sent at the minimum MTU unless 727 1.97 rpaulo * IP6PO_MINMTU_DISABLE is explicitly specified. 728 1.97 rpaulo * See RFC 3542 for more details. 729 1.2 itojun */ 730 1.45 itojun if (mtu > IPV6_MMTU) { 731 1.45 itojun if ((flags & IPV6_MINMTU)) 732 1.45 itojun mtu = IPV6_MMTU; 733 1.97 rpaulo else if (opt && opt->ip6po_minmtu == IP6PO_MINMTU_ALL) 734 1.97 rpaulo mtu = IPV6_MMTU; 735 1.97 rpaulo else if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) && 736 1.97 rpaulo (opt == NULL || 737 1.97 rpaulo opt->ip6po_minmtu != IP6PO_MINMTU_DISABLE)) { 738 1.97 rpaulo mtu = IPV6_MMTU; 739 1.97 rpaulo } 740 1.43 itojun } 741 1.43 itojun 742 1.94 rpaulo /* 743 1.94 rpaulo * clear embedded scope identifiers if necessary. 744 1.94 rpaulo * in6_clearscope will touch the addresses only when necessary. 745 1.94 rpaulo */ 746 1.94 rpaulo in6_clearscope(&ip6->ip6_src); 747 1.94 rpaulo in6_clearscope(&ip6->ip6_dst); 748 1.2 itojun 749 1.2 itojun /* 750 1.2 itojun * If the outgoing packet contains a hop-by-hop options header, 751 1.2 itojun * it must be examined and processed even by the source node. 752 1.2 itojun * (RFC 2460, section 4.) 753 1.200 maxv * 754 1.200 maxv * XXX Is this really necessary? 755 1.2 itojun */ 756 1.200 maxv if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 757 1.235 riastrad u_int32_t dummy1 = 0; /* XXX unused */ 758 1.2 itojun u_int32_t dummy2; /* XXX unused */ 759 1.143 drochner int hoff = sizeof(struct ip6_hdr); 760 1.2 itojun 761 1.143 drochner if (ip6_hopopts_input(&dummy1, &dummy2, &m, &hoff)) { 762 1.2 itojun /* m was already freed at this point */ 763 1.197 maxv error = EINVAL; 764 1.2 itojun goto done; 765 1.2 itojun } 766 1.143 drochner 767 1.143 drochner ip6 = mtod(m, struct ip6_hdr *); 768 1.2 itojun } 769 1.2 itojun 770 1.15 darrenr /* 771 1.15 darrenr * Run through list of hooks for output packets. 772 1.15 darrenr */ 773 1.219 ozaki error = pfil_run_hooks(inet6_pfil_hook, &m, ifp, PFIL_OUT); 774 1.219 ozaki if (error != 0 || m == NULL) { 775 1.219 ozaki IP6_STATINC(IP6_STAT_PFILDROP_OUT); 776 1.27 thorpej goto done; 777 1.219 ozaki } 778 1.27 thorpej ip6 = mtod(m, struct ip6_hdr *); 779 1.154 rmind 780 1.2 itojun /* 781 1.2 itojun * Send the packet to the outgoing interface. 782 1.19 itojun * If necessary, do IPv6 fragmentation before sending. 783 1.78 itojun * 784 1.78 itojun * the logic here is rather complex: 785 1.78 itojun * 1: normal case (dontfrag == 0, alwaysfrag == 0) 786 1.78 itojun * 1-a: send as is if tlen <= path mtu 787 1.78 itojun * 1-b: fragment if tlen > path mtu 788 1.78 itojun * 789 1.78 itojun * 2: if user asks us not to fragment (dontfrag == 1) 790 1.78 itojun * 2-a: send as is if tlen <= interface mtu 791 1.78 itojun * 2-b: error if tlen > interface mtu 792 1.78 itojun * 793 1.78 itojun * 3: if we always need to attach fragment header (alwaysfrag == 1) 794 1.78 itojun * always fragment 795 1.78 itojun * 796 1.78 itojun * 4: if dontfrag == 1 && alwaysfrag == 1 797 1.78 itojun * error, as we cannot handle this conflicting request 798 1.2 itojun */ 799 1.2 itojun tlen = m->m_pkthdr.len; 800 1.105 yamt tso = (m->m_pkthdr.csum_flags & M_CSUM_TSOv6) != 0; 801 1.97 rpaulo if (opt && (opt->ip6po_flags & IP6PO_DONTFRAG)) 802 1.97 rpaulo dontfrag = 1; 803 1.97 rpaulo else 804 1.97 rpaulo dontfrag = 0; 805 1.97 rpaulo 806 1.78 itojun if (dontfrag && alwaysfrag) { /* case 4 */ 807 1.78 itojun /* conflicting request - can't transmit */ 808 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); 809 1.78 itojun error = EMSGSIZE; 810 1.78 itojun goto bad; 811 1.78 itojun } 812 1.223 roy if (dontfrag && (!tso && tlen > ifp->if_mtu)) { /* case 2-b */ 813 1.78 itojun /* 814 1.78 itojun * Even if the DONTFRAG option is specified, we cannot send the 815 1.78 itojun * packet when the data length is larger than the MTU of the 816 1.78 itojun * outgoing interface. 817 1.78 itojun * Notify the error by sending IPV6_PATHMTU ancillary data as 818 1.78 itojun * well as returning an error code (the latter is not described 819 1.78 itojun * in the API spec.) 820 1.78 itojun */ 821 1.78 itojun u_int32_t mtu32; 822 1.78 itojun struct ip6ctlparam ip6cp; 823 1.78 itojun 824 1.78 itojun mtu32 = (u_int32_t)mtu; 825 1.136 cegger memset(&ip6cp, 0, sizeof(ip6cp)); 826 1.78 itojun ip6cp.ip6c_cmdarg = (void *)&mtu32; 827 1.115 dyoung pfctlinput2(PRC_MSGSIZE, 828 1.118 dyoung rtcache_getdst(ro_pmtu), &ip6cp); 829 1.78 itojun 830 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); 831 1.78 itojun error = EMSGSIZE; 832 1.78 itojun goto bad; 833 1.78 itojun } 834 1.97 rpaulo 835 1.78 itojun /* 836 1.78 itojun * transmit packet without fragmentation 837 1.78 itojun */ 838 1.105 yamt if (dontfrag || (!alwaysfrag && (tlen <= mtu || tso))) { 839 1.105 yamt /* case 1-a and 2-a */ 840 1.26 itojun struct in6_ifaddr *ia6; 841 1.89 yamt int sw_csum; 842 1.173 ozaki int s; 843 1.78 itojun 844 1.26 itojun ip6 = mtod(m, struct ip6_hdr *); 845 1.173 ozaki s = pserialize_read_enter(); 846 1.26 itojun ia6 = in6_ifawithifp(ifp, &ip6->ip6_src); 847 1.26 itojun if (ia6) { 848 1.42 itojun /* Record statistics for this interface address. */ 849 1.78 itojun ia6->ia_ifa.ifa_data.ifad_outbytes += m->m_pkthdr.len; 850 1.9 itojun } 851 1.173 ozaki pserialize_read_exit(s); 852 1.89 yamt 853 1.89 yamt sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx; 854 1.89 yamt if ((sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6)) != 0) { 855 1.90 yamt if (IN6_NEED_CHECKSUM(ifp, 856 1.90 yamt sw_csum & (M_CSUM_UDPv6|M_CSUM_TCPv6))) { 857 1.212 maxv in6_undefer_cksum_tcpudp(m); 858 1.90 yamt } 859 1.89 yamt m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 860 1.89 yamt } 861 1.89 yamt 862 1.118 dyoung KASSERT(dst != NULL); 863 1.214 rin if (__predict_false(sw_csum & M_CSUM_TSOv6)) { 864 1.214 rin /* 865 1.214 rin * TSO6 is required by a packet, but disabled for 866 1.214 rin * the interface. 867 1.214 rin */ 868 1.214 rin error = ip6_tso_output(ifp, origifp, m, dst, rt); 869 1.214 rin } else 870 1.183 ozaki error = ip6_if_output(ifp, origifp, m, dst, rt); 871 1.2 itojun goto done; 872 1.78 itojun } 873 1.78 itojun 874 1.105 yamt if (tso) { 875 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); /* XXX */ 876 1.105 yamt error = EINVAL; /* XXX */ 877 1.105 yamt goto bad; 878 1.105 yamt } 879 1.105 yamt 880 1.78 itojun /* 881 1.78 itojun * try to fragment the packet. case 1-b and 3 882 1.78 itojun */ 883 1.78 itojun if (mtu < IPV6_MMTU) { 884 1.78 itojun /* path MTU cannot be less than IPV6_MMTU */ 885 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); 886 1.2 itojun error = EMSGSIZE; 887 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_fragfail); 888 1.2 itojun goto bad; 889 1.78 itojun } else if (ip6->ip6_plen == 0) { 890 1.78 itojun /* jumbo payload cannot be fragmented */ 891 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); 892 1.2 itojun error = EMSGSIZE; 893 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_fragfail); 894 1.2 itojun goto bad; 895 1.2 itojun } else { 896 1.227 christos const uint32_t id = ip6_randomid(); 897 1.2 itojun struct mbuf **mnext, *m_frgpart; 898 1.197 maxv const int hlen = unfragpartlen; 899 1.2 itojun struct ip6_frag *ip6f; 900 1.2 itojun u_char nextproto; 901 1.2 itojun 902 1.2 itojun if (mtu > IPV6_MAXPACKET) 903 1.2 itojun mtu = IPV6_MAXPACKET; 904 1.78 itojun 905 1.197 maxv /* 906 1.197 maxv * Must be able to put at least 8 bytes per fragment. 907 1.197 maxv */ 908 1.2 itojun len = (mtu - hlen - sizeof(struct ip6_frag)) & ~7; 909 1.2 itojun if (len < 8) { 910 1.225 ozaki IP6_STATINC(IP6_STAT_CANTFRAG); 911 1.2 itojun error = EMSGSIZE; 912 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_fragfail); 913 1.2 itojun goto bad; 914 1.2 itojun } 915 1.2 itojun 916 1.2 itojun mnext = &m->m_nextpkt; 917 1.2 itojun 918 1.2 itojun /* 919 1.2 itojun * Change the next header field of the last header in the 920 1.2 itojun * unfragmentable part. 921 1.2 itojun */ 922 1.2 itojun if (exthdrs.ip6e_rthdr) { 923 1.2 itojun nextproto = *mtod(exthdrs.ip6e_rthdr, u_char *); 924 1.2 itojun *mtod(exthdrs.ip6e_rthdr, u_char *) = IPPROTO_FRAGMENT; 925 1.19 itojun } else if (exthdrs.ip6e_dest1) { 926 1.2 itojun nextproto = *mtod(exthdrs.ip6e_dest1, u_char *); 927 1.2 itojun *mtod(exthdrs.ip6e_dest1, u_char *) = IPPROTO_FRAGMENT; 928 1.19 itojun } else if (exthdrs.ip6e_hbh) { 929 1.2 itojun nextproto = *mtod(exthdrs.ip6e_hbh, u_char *); 930 1.2 itojun *mtod(exthdrs.ip6e_hbh, u_char *) = IPPROTO_FRAGMENT; 931 1.19 itojun } else { 932 1.2 itojun nextproto = ip6->ip6_nxt; 933 1.2 itojun ip6->ip6_nxt = IPPROTO_FRAGMENT; 934 1.2 itojun } 935 1.2 itojun 936 1.89 yamt if ((m->m_pkthdr.csum_flags & (M_CSUM_UDPv6|M_CSUM_TCPv6)) 937 1.89 yamt != 0) { 938 1.90 yamt if (IN6_NEED_CHECKSUM(ifp, 939 1.90 yamt m->m_pkthdr.csum_flags & 940 1.90 yamt (M_CSUM_UDPv6|M_CSUM_TCPv6))) { 941 1.212 maxv in6_undefer_cksum_tcpudp(m); 942 1.90 yamt } 943 1.89 yamt m->m_pkthdr.csum_flags &= ~(M_CSUM_UDPv6|M_CSUM_TCPv6); 944 1.89 yamt } 945 1.89 yamt 946 1.2 itojun /* 947 1.2 itojun * Loop through length of segment after first fragment, 948 1.42 itojun * make new header and copy data of each part and link onto 949 1.42 itojun * chain. 950 1.2 itojun */ 951 1.2 itojun m0 = m; 952 1.2 itojun for (off = hlen; off < tlen; off += len) { 953 1.68 itojun struct mbuf *mlast; 954 1.68 itojun 955 1.2 itojun MGETHDR(m, M_DONTWAIT, MT_HEADER); 956 1.2 itojun if (!m) { 957 1.2 itojun error = ENOBUFS; 958 1.128 thorpej IP6_STATINC(IP6_STAT_ODROPPED); 959 1.2 itojun goto sendorfree; 960 1.2 itojun } 961 1.167 ozaki m_reset_rcvif(m); 962 1.2 itojun m->m_flags = m0->m_flags & M_COPYFLAGS; 963 1.2 itojun *mnext = m; 964 1.2 itojun mnext = &m->m_nextpkt; 965 1.2 itojun m->m_data += max_linkhdr; 966 1.2 itojun mhip6 = mtod(m, struct ip6_hdr *); 967 1.2 itojun *mhip6 = *ip6; 968 1.2 itojun m->m_len = sizeof(*mhip6); 969 1.197 maxv 970 1.152 gdt ip6f = NULL; 971 1.42 itojun error = ip6_insertfraghdr(m0, m, hlen, &ip6f); 972 1.42 itojun if (error) { 973 1.128 thorpej IP6_STATINC(IP6_STAT_ODROPPED); 974 1.2 itojun goto sendorfree; 975 1.2 itojun } 976 1.197 maxv 977 1.197 maxv /* Fill in the Frag6 Header */ 978 1.69 itojun ip6f->ip6f_offlg = htons((u_int16_t)((off - hlen) & ~7)); 979 1.2 itojun if (off + len >= tlen) 980 1.2 itojun len = tlen - off; 981 1.2 itojun else 982 1.2 itojun ip6f->ip6f_offlg |= IP6F_MORE_FRAG; 983 1.197 maxv ip6f->ip6f_reserved = 0; 984 1.197 maxv ip6f->ip6f_ident = id; 985 1.197 maxv ip6f->ip6f_nxt = nextproto; 986 1.197 maxv 987 1.69 itojun mhip6->ip6_plen = htons((u_int16_t)(len + hlen + 988 1.49 itojun sizeof(*ip6f) - sizeof(struct ip6_hdr))); 989 1.206 maxv if ((m_frgpart = m_copym(m0, off, len, M_DONTWAIT)) == NULL) { 990 1.2 itojun error = ENOBUFS; 991 1.128 thorpej IP6_STATINC(IP6_STAT_ODROPPED); 992 1.2 itojun goto sendorfree; 993 1.2 itojun } 994 1.68 itojun for (mlast = m; mlast->m_next; mlast = mlast->m_next) 995 1.68 itojun ; 996 1.68 itojun mlast->m_next = m_frgpart; 997 1.197 maxv 998 1.2 itojun m->m_pkthdr.len = len + hlen + sizeof(*ip6f); 999 1.167 ozaki m_reset_rcvif(m); 1000 1.128 thorpej IP6_STATINC(IP6_STAT_OFRAGMENTS); 1001 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_fragcreat); 1002 1.2 itojun } 1003 1.9 itojun 1004 1.9 itojun in6_ifstat_inc(ifp, ifs6_out_fragok); 1005 1.2 itojun } 1006 1.2 itojun 1007 1.2 itojun sendorfree: 1008 1.2 itojun m = m0->m_nextpkt; 1009 1.2 itojun m0->m_nextpkt = 0; 1010 1.2 itojun m_freem(m0); 1011 1.2 itojun for (m0 = m; m; m = m0) { 1012 1.2 itojun m0 = m->m_nextpkt; 1013 1.2 itojun m->m_nextpkt = 0; 1014 1.2 itojun if (error == 0) { 1015 1.26 itojun struct in6_ifaddr *ia6; 1016 1.173 ozaki int s; 1017 1.26 itojun ip6 = mtod(m, struct ip6_hdr *); 1018 1.173 ozaki s = pserialize_read_enter(); 1019 1.26 itojun ia6 = in6_ifawithifp(ifp, &ip6->ip6_src); 1020 1.26 itojun if (ia6) { 1021 1.42 itojun /* 1022 1.42 itojun * Record statistics for this interface 1023 1.42 itojun * address. 1024 1.42 itojun */ 1025 1.26 itojun ia6->ia_ifa.ifa_data.ifad_outbytes += 1026 1.78 itojun m->m_pkthdr.len; 1027 1.9 itojun } 1028 1.173 ozaki pserialize_read_exit(s); 1029 1.118 dyoung KASSERT(dst != NULL); 1030 1.183 ozaki error = ip6_if_output(ifp, origifp, m, dst, rt); 1031 1.19 itojun } else 1032 1.2 itojun m_freem(m); 1033 1.2 itojun } 1034 1.2 itojun 1035 1.2 itojun if (error == 0) 1036 1.128 thorpej IP6_STATINC(IP6_STAT_FRAGMENTED); 1037 1.2 itojun 1038 1.2 itojun done: 1039 1.179 ozaki rtcache_unref(rt, ro); 1040 1.172 ozaki if (ro == &ip6route) 1041 1.172 ozaki rtcache_free(&ip6route); 1042 1.153 christos #ifdef IPSEC 1043 1.114 degroote if (sp != NULL) 1044 1.193 ozaki KEY_SP_UNREF(&sp); 1045 1.197 maxv #endif 1046 1.170 ozaki if_put(ifp, &psref); 1047 1.170 ozaki if (release_psref_ia) 1048 1.170 ozaki if_put(origifp, &psref_ia); 1049 1.170 ozaki curlwp_bindx(bound); 1050 1.2 itojun 1051 1.197 maxv return error; 1052 1.2 itojun 1053 1.2 itojun freehdrs: 1054 1.197 maxv m_freem(exthdrs.ip6e_hbh); 1055 1.2 itojun m_freem(exthdrs.ip6e_dest1); 1056 1.2 itojun m_freem(exthdrs.ip6e_rthdr); 1057 1.2 itojun m_freem(exthdrs.ip6e_dest2); 1058 1.48 itojun /* FALLTHROUGH */ 1059 1.2 itojun bad: 1060 1.2 itojun m_freem(m); 1061 1.2 itojun goto done; 1062 1.197 maxv 1063 1.118 dyoung badscope: 1064 1.128 thorpej IP6_STATINC(IP6_STAT_BADSCOPE); 1065 1.118 dyoung in6_ifstat_inc(origifp, ifs6_out_discard); 1066 1.118 dyoung if (error == 0) 1067 1.118 dyoung error = EHOSTUNREACH; /* XXX */ 1068 1.118 dyoung goto bad; 1069 1.2 itojun } 1070 1.2 itojun 1071 1.2 itojun static int 1072 1.119 christos ip6_copyexthdr(struct mbuf **mp, void *hdr, int hlen) 1073 1.2 itojun { 1074 1.2 itojun struct mbuf *m; 1075 1.2 itojun 1076 1.2 itojun if (hlen > MCLBYTES) 1077 1.197 maxv return ENOBUFS; /* XXX */ 1078 1.2 itojun 1079 1.2 itojun MGET(m, M_DONTWAIT, MT_DATA); 1080 1.2 itojun if (!m) 1081 1.197 maxv return ENOBUFS; 1082 1.2 itojun 1083 1.2 itojun if (hlen > MLEN) { 1084 1.2 itojun MCLGET(m, M_DONTWAIT); 1085 1.2 itojun if ((m->m_flags & M_EXT) == 0) { 1086 1.2 itojun m_free(m); 1087 1.197 maxv return ENOBUFS; 1088 1.2 itojun } 1089 1.2 itojun } 1090 1.2 itojun m->m_len = hlen; 1091 1.2 itojun if (hdr) 1092 1.201 maxv memcpy(mtod(m, void *), hdr, hlen); 1093 1.2 itojun 1094 1.2 itojun *mp = m; 1095 1.197 maxv return 0; 1096 1.2 itojun } 1097 1.2 itojun 1098 1.2 itojun /* 1099 1.19 itojun * Insert jumbo payload option. 1100 1.2 itojun */ 1101 1.2 itojun static int 1102 1.119 christos ip6_insert_jumboopt(struct ip6_exthdrs *exthdrs, u_int32_t plen) 1103 1.2 itojun { 1104 1.2 itojun struct mbuf *mopt; 1105 1.56 itojun u_int8_t *optbuf; 1106 1.25 itojun u_int32_t v; 1107 1.2 itojun 1108 1.2 itojun #define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */ 1109 1.2 itojun 1110 1.2 itojun /* 1111 1.2 itojun * If there is no hop-by-hop options header, allocate new one. 1112 1.2 itojun * If there is one but it doesn't have enough space to store the 1113 1.2 itojun * jumbo payload option, allocate a cluster to store the whole options. 1114 1.2 itojun * Otherwise, use it to store the options. 1115 1.2 itojun */ 1116 1.198 maxv if (exthdrs->ip6e_hbh == NULL) { 1117 1.2 itojun MGET(mopt, M_DONTWAIT, MT_DATA); 1118 1.2 itojun if (mopt == 0) 1119 1.57 itojun return (ENOBUFS); 1120 1.2 itojun mopt->m_len = JUMBOOPTLEN; 1121 1.56 itojun optbuf = mtod(mopt, u_int8_t *); 1122 1.2 itojun optbuf[1] = 0; /* = ((JUMBOOPTLEN) >> 3) - 1 */ 1123 1.2 itojun exthdrs->ip6e_hbh = mopt; 1124 1.19 itojun } else { 1125 1.2 itojun struct ip6_hbh *hbh; 1126 1.2 itojun 1127 1.2 itojun mopt = exthdrs->ip6e_hbh; 1128 1.2 itojun if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) { 1129 1.198 maxv const int oldoptlen = mopt->m_len; 1130 1.198 maxv struct mbuf *n; 1131 1.198 maxv 1132 1.25 itojun /* 1133 1.198 maxv * Assumptions: 1134 1.25 itojun * - exthdrs->ip6e_hbh is not referenced from places 1135 1.25 itojun * other than exthdrs. 1136 1.25 itojun * - exthdrs->ip6e_hbh is not an mbuf chain. 1137 1.25 itojun */ 1138 1.198 maxv KASSERT(mopt->m_next == NULL); 1139 1.2 itojun 1140 1.25 itojun /* 1141 1.198 maxv * Give up if the whole (new) hbh header does not fit 1142 1.198 maxv * even in an mbuf cluster. 1143 1.25 itojun */ 1144 1.25 itojun if (oldoptlen + JUMBOOPTLEN > MCLBYTES) 1145 1.198 maxv return ENOBUFS; 1146 1.2 itojun 1147 1.25 itojun /* 1148 1.198 maxv * At this point, we must always prepare a cluster. 1149 1.25 itojun */ 1150 1.25 itojun MGET(n, M_DONTWAIT, MT_DATA); 1151 1.25 itojun if (n) { 1152 1.25 itojun MCLGET(n, M_DONTWAIT); 1153 1.25 itojun if ((n->m_flags & M_EXT) == 0) { 1154 1.25 itojun m_freem(n); 1155 1.25 itojun n = NULL; 1156 1.25 itojun } 1157 1.25 itojun } 1158 1.25 itojun if (!n) 1159 1.198 maxv return ENOBUFS; 1160 1.198 maxv 1161 1.25 itojun n->m_len = oldoptlen + JUMBOOPTLEN; 1162 1.117 christos bcopy(mtod(mopt, void *), mtod(n, void *), 1163 1.78 itojun oldoptlen); 1164 1.56 itojun optbuf = mtod(n, u_int8_t *) + oldoptlen; 1165 1.25 itojun m_freem(mopt); 1166 1.33 itojun mopt = exthdrs->ip6e_hbh = n; 1167 1.19 itojun } else { 1168 1.56 itojun optbuf = mtod(mopt, u_int8_t *) + mopt->m_len; 1169 1.2 itojun mopt->m_len += JUMBOOPTLEN; 1170 1.2 itojun } 1171 1.2 itojun optbuf[0] = IP6OPT_PADN; 1172 1.58 itojun optbuf[1] = 0; 1173 1.2 itojun 1174 1.2 itojun /* 1175 1.2 itojun * Adjust the header length according to the pad and 1176 1.2 itojun * the jumbo payload option. 1177 1.2 itojun */ 1178 1.2 itojun hbh = mtod(mopt, struct ip6_hbh *); 1179 1.2 itojun hbh->ip6h_len += (JUMBOOPTLEN >> 3); 1180 1.2 itojun } 1181 1.2 itojun 1182 1.2 itojun /* fill in the option. */ 1183 1.2 itojun optbuf[2] = IP6OPT_JUMBO; 1184 1.2 itojun optbuf[3] = 4; 1185 1.25 itojun v = (u_int32_t)htonl(plen + JUMBOOPTLEN); 1186 1.201 maxv memcpy(&optbuf[4], &v, sizeof(u_int32_t)); 1187 1.2 itojun 1188 1.2 itojun /* finally, adjust the packet header length */ 1189 1.2 itojun exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN; 1190 1.2 itojun 1191 1.198 maxv return 0; 1192 1.2 itojun #undef JUMBOOPTLEN 1193 1.2 itojun } 1194 1.2 itojun 1195 1.2 itojun /* 1196 1.2 itojun * Insert fragment header and copy unfragmentable header portions. 1197 1.197 maxv * 1198 1.150 gdt * *frghdrp will not be read, and it is guaranteed that either an 1199 1.150 gdt * error is returned or that *frghdrp will point to space allocated 1200 1.150 gdt * for the fragment header. 1201 1.197 maxv * 1202 1.197 maxv * On entry, m contains: 1203 1.197 maxv * IPv6 Header 1204 1.197 maxv * On exit, it contains: 1205 1.197 maxv * IPv6 Header -> Unfragmentable Part -> Frag6 Header 1206 1.2 itojun */ 1207 1.2 itojun static int 1208 1.197 maxv ip6_insertfraghdr(struct mbuf *m0, struct mbuf *m, int hlen, 1209 1.119 christos struct ip6_frag **frghdrp) 1210 1.2 itojun { 1211 1.2 itojun struct mbuf *n, *mlast; 1212 1.2 itojun 1213 1.2 itojun if (hlen > sizeof(struct ip6_hdr)) { 1214 1.2 itojun n = m_copym(m0, sizeof(struct ip6_hdr), 1215 1.49 itojun hlen - sizeof(struct ip6_hdr), M_DONTWAIT); 1216 1.197 maxv if (n == NULL) 1217 1.197 maxv return ENOBUFS; 1218 1.2 itojun m->m_next = n; 1219 1.19 itojun } else 1220 1.2 itojun n = m; 1221 1.2 itojun 1222 1.2 itojun /* Search for the last mbuf of unfragmentable part. */ 1223 1.2 itojun for (mlast = n; mlast->m_next; mlast = mlast->m_next) 1224 1.2 itojun ; 1225 1.2 itojun 1226 1.2 itojun if ((mlast->m_flags & M_EXT) == 0 && 1227 1.22 itojun M_TRAILINGSPACE(mlast) >= sizeof(struct ip6_frag)) { 1228 1.2 itojun /* use the trailing space of the last mbuf for the fragment hdr */ 1229 1.117 christos *frghdrp = (struct ip6_frag *)(mtod(mlast, char *) + 1230 1.49 itojun mlast->m_len); 1231 1.2 itojun mlast->m_len += sizeof(struct ip6_frag); 1232 1.19 itojun } else { 1233 1.2 itojun /* allocate a new mbuf for the fragment header */ 1234 1.2 itojun struct mbuf *mfrg; 1235 1.2 itojun 1236 1.2 itojun MGET(mfrg, M_DONTWAIT, MT_DATA); 1237 1.197 maxv if (mfrg == NULL) 1238 1.197 maxv return ENOBUFS; 1239 1.2 itojun mfrg->m_len = sizeof(struct ip6_frag); 1240 1.2 itojun *frghdrp = mtod(mfrg, struct ip6_frag *); 1241 1.2 itojun mlast->m_next = mfrg; 1242 1.2 itojun } 1243 1.2 itojun 1244 1.197 maxv return 0; 1245 1.45 itojun } 1246 1.45 itojun 1247 1.88 itojun static int 1248 1.176 ozaki ip6_getpmtu(struct rtentry *rt, struct ifnet *ifp, u_long *mtup, 1249 1.176 ozaki int *alwaysfragp) 1250 1.45 itojun { 1251 1.45 itojun u_int32_t mtu = 0; 1252 1.78 itojun int alwaysfrag = 0; 1253 1.45 itojun int error = 0; 1254 1.45 itojun 1255 1.126 dyoung if (rt != NULL) { 1256 1.45 itojun if (ifp == NULL) 1257 1.124 dyoung ifp = rt->rt_ifp; 1258 1.124 dyoung mtu = rt->rt_rmx.rmx_mtu; 1259 1.46 itojun if (mtu == 0) 1260 1.223 roy mtu = ifp->if_mtu; 1261 1.78 itojun else if (mtu < IPV6_MMTU) { 1262 1.78 itojun /* 1263 1.78 itojun * RFC2460 section 5, last paragraph: 1264 1.78 itojun * if we record ICMPv6 too big message with 1265 1.78 itojun * mtu < IPV6_MMTU, transmit packets sized IPV6_MMTU 1266 1.78 itojun * or smaller, with fragment header attached. 1267 1.78 itojun * (fragment header is needed regardless from the 1268 1.78 itojun * packet size, for translators to identify packets) 1269 1.78 itojun */ 1270 1.78 itojun alwaysfrag = 1; 1271 1.78 itojun mtu = IPV6_MMTU; 1272 1.223 roy } else if (mtu > ifp->if_mtu) { 1273 1.45 itojun /* 1274 1.45 itojun * The MTU on the route is larger than the MTU on 1275 1.45 itojun * the interface! This shouldn't happen, unless the 1276 1.45 itojun * MTU of the interface has been changed after the 1277 1.45 itojun * interface was brought up. Change the MTU in the 1278 1.45 itojun * route to match the interface MTU (as long as the 1279 1.45 itojun * field isn't locked). 1280 1.45 itojun */ 1281 1.223 roy mtu = ifp->if_mtu; 1282 1.124 dyoung if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) 1283 1.124 dyoung rt->rt_rmx.rmx_mtu = mtu; 1284 1.45 itojun } 1285 1.45 itojun } else if (ifp) { 1286 1.223 roy mtu = ifp->if_mtu; 1287 1.45 itojun } else 1288 1.45 itojun error = EHOSTUNREACH; /* XXX */ 1289 1.45 itojun 1290 1.45 itojun *mtup = mtu; 1291 1.78 itojun if (alwaysfragp) 1292 1.78 itojun *alwaysfragp = alwaysfrag; 1293 1.57 itojun return (error); 1294 1.2 itojun } 1295 1.2 itojun 1296 1.2 itojun /* 1297 1.2 itojun * IP6 socket option processing. 1298 1.2 itojun */ 1299 1.2 itojun int 1300 1.130 plunky ip6_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1301 1.2 itojun { 1302 1.138 elad int optdatalen, uproto; 1303 1.97 rpaulo void *optdata; 1304 1.230 ozaki struct inpcb *inp = sotoinpcb(so); 1305 1.159 christos struct ip_moptions **mopts; 1306 1.97 rpaulo int error, optval; 1307 1.130 plunky int level, optname; 1308 1.130 plunky 1309 1.185 ozaki KASSERT(solocked(so)); 1310 1.130 plunky KASSERT(sopt != NULL); 1311 1.130 plunky 1312 1.130 plunky level = sopt->sopt_level; 1313 1.130 plunky optname = sopt->sopt_name; 1314 1.2 itojun 1315 1.97 rpaulo error = optval = 0; 1316 1.97 rpaulo uproto = (int)so->so_proto->pr_protocol; 1317 1.97 rpaulo 1318 1.159 christos switch (level) { 1319 1.159 christos case IPPROTO_IP: 1320 1.159 christos switch (optname) { 1321 1.159 christos case IP_ADD_MEMBERSHIP: 1322 1.159 christos case IP_DROP_MEMBERSHIP: 1323 1.159 christos case IP_MULTICAST_IF: 1324 1.159 christos case IP_MULTICAST_LOOP: 1325 1.159 christos case IP_MULTICAST_TTL: 1326 1.230 ozaki mopts = &inp->inp_moptions; 1327 1.159 christos switch (op) { 1328 1.159 christos case PRCO_GETOPT: 1329 1.159 christos return ip_getmoptions(*mopts, sopt); 1330 1.159 christos case PRCO_SETOPT: 1331 1.159 christos return ip_setmoptions(mopts, sopt); 1332 1.159 christos default: 1333 1.159 christos return EINVAL; 1334 1.159 christos } 1335 1.159 christos default: 1336 1.159 christos return ENOPROTOOPT; 1337 1.159 christos } 1338 1.159 christos case IPPROTO_IPV6: 1339 1.159 christos break; 1340 1.159 christos default: 1341 1.121 dyoung return ENOPROTOOPT; 1342 1.121 dyoung } 1343 1.121 dyoung switch (op) { 1344 1.121 dyoung case PRCO_SETOPT: 1345 1.121 dyoung switch (optname) { 1346 1.97 rpaulo #ifdef RFC2292 1347 1.121 dyoung case IPV6_2292PKTOPTIONS: 1348 1.231 ozaki error = ip6_pcbopts(&in6p_outputopts(inp), so, sopt); 1349 1.121 dyoung break; 1350 1.121 dyoung #endif 1351 1.121 dyoung 1352 1.121 dyoung /* 1353 1.121 dyoung * Use of some Hop-by-Hop options or some 1354 1.121 dyoung * Destination options, might require special 1355 1.121 dyoung * privilege. That is, normal applications 1356 1.121 dyoung * (without special privilege) might be forbidden 1357 1.121 dyoung * from setting certain options in outgoing packets, 1358 1.121 dyoung * and might never see certain options in received 1359 1.121 dyoung * packets. [RFC 2292 Section 6] 1360 1.121 dyoung * KAME specific note: 1361 1.121 dyoung * KAME prevents non-privileged users from sending or 1362 1.121 dyoung * receiving ANY hbh/dst options in order to avoid 1363 1.121 dyoung * overhead of parsing options in the kernel. 1364 1.121 dyoung */ 1365 1.121 dyoung case IPV6_RECVHOPOPTS: 1366 1.121 dyoung case IPV6_RECVDSTOPTS: 1367 1.121 dyoung case IPV6_RECVRTHDRDSTOPTS: 1368 1.229 christos error = kauth_authorize_network( 1369 1.229 christos kauth_cred_get(), 1370 1.146 elad KAUTH_NETWORK_IPV6, KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, 1371 1.146 elad NULL, NULL, NULL); 1372 1.138 elad if (error) 1373 1.121 dyoung break; 1374 1.121 dyoung /* FALLTHROUGH */ 1375 1.121 dyoung case IPV6_UNICAST_HOPS: 1376 1.121 dyoung case IPV6_HOPLIMIT: 1377 1.121 dyoung case IPV6_FAITH: 1378 1.121 dyoung 1379 1.121 dyoung case IPV6_RECVPKTINFO: 1380 1.121 dyoung case IPV6_RECVHOPLIMIT: 1381 1.121 dyoung case IPV6_RECVRTHDR: 1382 1.121 dyoung case IPV6_RECVPATHMTU: 1383 1.121 dyoung case IPV6_RECVTCLASS: 1384 1.121 dyoung case IPV6_V6ONLY: 1385 1.226 christos case IPV6_BINDANY: 1386 1.130 plunky error = sockopt_getint(sopt, &optval); 1387 1.130 plunky if (error) 1388 1.97 rpaulo break; 1389 1.121 dyoung switch (optname) { 1390 1.2 itojun case IPV6_UNICAST_HOPS: 1391 1.121 dyoung if (optval < -1 || optval >= 256) 1392 1.2 itojun error = EINVAL; 1393 1.121 dyoung else { 1394 1.121 dyoung /* -1 = kernel default */ 1395 1.231 ozaki in6p_hops6(inp) = optval; 1396 1.37 itojun } 1397 1.121 dyoung break; 1398 1.2 itojun #define OPTSET(bit) \ 1399 1.49 itojun do { \ 1400 1.121 dyoung if (optval) \ 1401 1.230 ozaki inp->inp_flags |= (bit); \ 1402 1.121 dyoung else \ 1403 1.230 ozaki inp->inp_flags &= ~(bit); \ 1404 1.60 perry } while (/*CONSTCOND*/ 0) 1405 1.2 itojun 1406 1.97 rpaulo #ifdef RFC2292 1407 1.97 rpaulo #define OPTSET2292(bit) \ 1408 1.97 rpaulo do { \ 1409 1.230 ozaki inp->inp_flags |= IN6P_RFC2292; \ 1410 1.121 dyoung if (optval) \ 1411 1.230 ozaki inp->inp_flags |= (bit); \ 1412 1.121 dyoung else \ 1413 1.230 ozaki inp->inp_flags &= ~(bit); \ 1414 1.97 rpaulo } while (/*CONSTCOND*/ 0) 1415 1.97 rpaulo #endif 1416 1.97 rpaulo 1417 1.230 ozaki #define OPTBIT(bit) (inp->inp_flags & (bit) ? 1 : 0) 1418 1.2 itojun 1419 1.121 dyoung case IPV6_RECVPKTINFO: 1420 1.97 rpaulo #ifdef RFC2292 1421 1.121 dyoung /* cannot mix with RFC2292 */ 1422 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1423 1.121 dyoung error = EINVAL; 1424 1.121 dyoung break; 1425 1.121 dyoung } 1426 1.97 rpaulo #endif 1427 1.121 dyoung OPTSET(IN6P_PKTINFO); 1428 1.121 dyoung break; 1429 1.121 dyoung 1430 1.121 dyoung case IPV6_HOPLIMIT: 1431 1.121 dyoung { 1432 1.121 dyoung struct ip6_pktopts **optp; 1433 1.2 itojun 1434 1.121 dyoung #ifdef RFC2292 1435 1.121 dyoung /* cannot mix with RFC2292 */ 1436 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1437 1.121 dyoung error = EINVAL; 1438 1.37 itojun break; 1439 1.97 rpaulo } 1440 1.121 dyoung #endif 1441 1.231 ozaki optp = &in6p_outputopts(inp); 1442 1.121 dyoung error = ip6_pcbopt(IPV6_HOPLIMIT, 1443 1.121 dyoung (u_char *)&optval, 1444 1.121 dyoung sizeof(optval), 1445 1.121 dyoung optp, 1446 1.138 elad kauth_cred_get(), uproto); 1447 1.121 dyoung break; 1448 1.121 dyoung } 1449 1.2 itojun 1450 1.121 dyoung case IPV6_RECVHOPLIMIT: 1451 1.97 rpaulo #ifdef RFC2292 1452 1.121 dyoung /* cannot mix with RFC2292 */ 1453 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1454 1.121 dyoung error = EINVAL; 1455 1.121 dyoung break; 1456 1.121 dyoung } 1457 1.97 rpaulo #endif 1458 1.121 dyoung OPTSET(IN6P_HOPLIMIT); 1459 1.121 dyoung break; 1460 1.2 itojun 1461 1.121 dyoung case IPV6_RECVHOPOPTS: 1462 1.97 rpaulo #ifdef RFC2292 1463 1.121 dyoung /* cannot mix with RFC2292 */ 1464 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1465 1.121 dyoung error = EINVAL; 1466 1.121 dyoung break; 1467 1.121 dyoung } 1468 1.97 rpaulo #endif 1469 1.121 dyoung OPTSET(IN6P_HOPOPTS); 1470 1.121 dyoung break; 1471 1.2 itojun 1472 1.121 dyoung case IPV6_RECVDSTOPTS: 1473 1.97 rpaulo #ifdef RFC2292 1474 1.121 dyoung /* cannot mix with RFC2292 */ 1475 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1476 1.121 dyoung error = EINVAL; 1477 1.121 dyoung break; 1478 1.121 dyoung } 1479 1.97 rpaulo #endif 1480 1.121 dyoung OPTSET(IN6P_DSTOPTS); 1481 1.121 dyoung break; 1482 1.2 itojun 1483 1.121 dyoung case IPV6_RECVRTHDRDSTOPTS: 1484 1.97 rpaulo #ifdef RFC2292 1485 1.121 dyoung /* cannot mix with RFC2292 */ 1486 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1487 1.121 dyoung error = EINVAL; 1488 1.121 dyoung break; 1489 1.121 dyoung } 1490 1.97 rpaulo #endif 1491 1.121 dyoung OPTSET(IN6P_RTHDRDSTOPTS); 1492 1.121 dyoung break; 1493 1.97 rpaulo 1494 1.121 dyoung case IPV6_RECVRTHDR: 1495 1.97 rpaulo #ifdef RFC2292 1496 1.121 dyoung /* cannot mix with RFC2292 */ 1497 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1498 1.121 dyoung error = EINVAL; 1499 1.121 dyoung break; 1500 1.121 dyoung } 1501 1.97 rpaulo #endif 1502 1.121 dyoung OPTSET(IN6P_RTHDR); 1503 1.121 dyoung break; 1504 1.121 dyoung 1505 1.121 dyoung case IPV6_FAITH: 1506 1.121 dyoung OPTSET(IN6P_FAITH); 1507 1.121 dyoung break; 1508 1.2 itojun 1509 1.121 dyoung case IPV6_RECVPATHMTU: 1510 1.121 dyoung /* 1511 1.121 dyoung * We ignore this option for TCP 1512 1.121 dyoung * sockets. 1513 1.121 dyoung * (RFC3542 leaves this case 1514 1.121 dyoung * unspecified.) 1515 1.121 dyoung */ 1516 1.121 dyoung if (uproto != IPPROTO_TCP) 1517 1.121 dyoung OPTSET(IN6P_MTU); 1518 1.121 dyoung break; 1519 1.10 itojun 1520 1.121 dyoung case IPV6_V6ONLY: 1521 1.121 dyoung /* 1522 1.121 dyoung * make setsockopt(IPV6_V6ONLY) 1523 1.121 dyoung * available only prior to bind(2). 1524 1.121 dyoung * see ipng mailing list, Jun 22 2001. 1525 1.121 dyoung */ 1526 1.230 ozaki if (inp->inp_lport || 1527 1.231 ozaki !IN6_IS_ADDR_UNSPECIFIED(&in6p_laddr(inp))) { 1528 1.121 dyoung error = EINVAL; 1529 1.83 itojun break; 1530 1.121 dyoung } 1531 1.37 itojun #ifdef INET6_BINDV6ONLY 1532 1.121 dyoung if (!optval) 1533 1.121 dyoung error = EINVAL; 1534 1.37 itojun #else 1535 1.121 dyoung OPTSET(IN6P_IPV6_V6ONLY); 1536 1.10 itojun #endif 1537 1.121 dyoung break; 1538 1.226 christos 1539 1.121 dyoung case IPV6_RECVTCLASS: 1540 1.121 dyoung #ifdef RFC2292 1541 1.121 dyoung /* cannot mix with RFC2292 XXX */ 1542 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1543 1.121 dyoung error = EINVAL; 1544 1.37 itojun break; 1545 1.121 dyoung } 1546 1.97 rpaulo #endif 1547 1.121 dyoung OPTSET(IN6P_TCLASS); 1548 1.121 dyoung break; 1549 1.121 dyoung 1550 1.226 christos case IPV6_BINDANY: 1551 1.226 christos error = kauth_authorize_network( 1552 1.226 christos kauth_cred_get(), KAUTH_NETWORK_BIND, 1553 1.226 christos KAUTH_REQ_NETWORK_BIND_ANYADDR, so, NULL, 1554 1.226 christos NULL); 1555 1.226 christos if (error) 1556 1.226 christos break; 1557 1.226 christos OPTSET(IN6P_BINDANY); 1558 1.226 christos break; 1559 1.121 dyoung } 1560 1.121 dyoung break; 1561 1.121 dyoung 1562 1.121 dyoung case IPV6_OTCLASS: 1563 1.121 dyoung { 1564 1.121 dyoung struct ip6_pktopts **optp; 1565 1.121 dyoung u_int8_t tclass; 1566 1.97 rpaulo 1567 1.130 plunky error = sockopt_get(sopt, &tclass, sizeof(tclass)); 1568 1.130 plunky if (error) 1569 1.97 rpaulo break; 1570 1.231 ozaki optp = &in6p_outputopts(inp); 1571 1.121 dyoung error = ip6_pcbopt(optname, 1572 1.121 dyoung (u_char *)&tclass, 1573 1.121 dyoung sizeof(tclass), 1574 1.121 dyoung optp, 1575 1.138 elad kauth_cred_get(), uproto); 1576 1.121 dyoung break; 1577 1.121 dyoung } 1578 1.97 rpaulo 1579 1.121 dyoung case IPV6_TCLASS: 1580 1.121 dyoung case IPV6_DONTFRAG: 1581 1.121 dyoung case IPV6_USE_MIN_MTU: 1582 1.161 roy case IPV6_PREFER_TEMPADDR: 1583 1.130 plunky error = sockopt_getint(sopt, &optval); 1584 1.130 plunky if (error) 1585 1.121 dyoung break; 1586 1.97 rpaulo { 1587 1.97 rpaulo struct ip6_pktopts **optp; 1588 1.231 ozaki optp = &in6p_outputopts(inp); 1589 1.97 rpaulo error = ip6_pcbopt(optname, 1590 1.121 dyoung (u_char *)&optval, 1591 1.121 dyoung sizeof(optval), 1592 1.97 rpaulo optp, 1593 1.138 elad kauth_cred_get(), uproto); 1594 1.97 rpaulo break; 1595 1.97 rpaulo } 1596 1.97 rpaulo 1597 1.97 rpaulo #ifdef RFC2292 1598 1.121 dyoung case IPV6_2292PKTINFO: 1599 1.121 dyoung case IPV6_2292HOPLIMIT: 1600 1.121 dyoung case IPV6_2292HOPOPTS: 1601 1.121 dyoung case IPV6_2292DSTOPTS: 1602 1.121 dyoung case IPV6_2292RTHDR: 1603 1.121 dyoung /* RFC 2292 */ 1604 1.130 plunky error = sockopt_getint(sopt, &optval); 1605 1.130 plunky if (error) 1606 1.121 dyoung break; 1607 1.130 plunky 1608 1.121 dyoung switch (optname) { 1609 1.97 rpaulo case IPV6_2292PKTINFO: 1610 1.121 dyoung OPTSET2292(IN6P_PKTINFO); 1611 1.121 dyoung break; 1612 1.97 rpaulo case IPV6_2292HOPLIMIT: 1613 1.121 dyoung OPTSET2292(IN6P_HOPLIMIT); 1614 1.121 dyoung break; 1615 1.97 rpaulo case IPV6_2292HOPOPTS: 1616 1.121 dyoung /* 1617 1.121 dyoung * Check super-user privilege. 1618 1.121 dyoung * See comments for IPV6_RECVHOPOPTS. 1619 1.121 dyoung */ 1620 1.229 christos error = kauth_authorize_network( 1621 1.229 christos kauth_cred_get(), 1622 1.146 elad KAUTH_NETWORK_IPV6, 1623 1.146 elad KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, 1624 1.146 elad NULL, NULL); 1625 1.138 elad if (error) 1626 1.138 elad return (error); 1627 1.121 dyoung OPTSET2292(IN6P_HOPOPTS); 1628 1.121 dyoung break; 1629 1.97 rpaulo case IPV6_2292DSTOPTS: 1630 1.229 christos error = kauth_authorize_network( 1631 1.229 christos kauth_cred_get(), 1632 1.146 elad KAUTH_NETWORK_IPV6, 1633 1.146 elad KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, 1634 1.146 elad NULL, NULL); 1635 1.138 elad if (error) 1636 1.138 elad return (error); 1637 1.121 dyoung OPTSET2292(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); /* XXX */ 1638 1.121 dyoung break; 1639 1.97 rpaulo case IPV6_2292RTHDR: 1640 1.121 dyoung OPTSET2292(IN6P_RTHDR); 1641 1.97 rpaulo break; 1642 1.121 dyoung } 1643 1.121 dyoung break; 1644 1.97 rpaulo #endif 1645 1.121 dyoung case IPV6_PKTINFO: 1646 1.121 dyoung case IPV6_HOPOPTS: 1647 1.121 dyoung case IPV6_RTHDR: 1648 1.121 dyoung case IPV6_DSTOPTS: 1649 1.121 dyoung case IPV6_RTHDRDSTOPTS: 1650 1.130 plunky case IPV6_NEXTHOP: { 1651 1.121 dyoung /* new advanced API (RFC3542) */ 1652 1.130 plunky void *optbuf; 1653 1.121 dyoung int optbuflen; 1654 1.121 dyoung struct ip6_pktopts **optp; 1655 1.97 rpaulo 1656 1.97 rpaulo #ifdef RFC2292 1657 1.121 dyoung /* cannot mix with RFC2292 */ 1658 1.121 dyoung if (OPTBIT(IN6P_RFC2292)) { 1659 1.121 dyoung error = EINVAL; 1660 1.121 dyoung break; 1661 1.121 dyoung } 1662 1.97 rpaulo #endif 1663 1.97 rpaulo 1664 1.131 plunky optbuflen = sopt->sopt_size; 1665 1.131 plunky optbuf = malloc(optbuflen, M_IP6OPT, M_NOWAIT); 1666 1.131 plunky if (optbuf == NULL) { 1667 1.131 plunky error = ENOBUFS; 1668 1.131 plunky break; 1669 1.131 plunky } 1670 1.131 plunky 1671 1.155 christos error = sockopt_get(sopt, optbuf, optbuflen); 1672 1.155 christos if (error) { 1673 1.155 christos free(optbuf, M_IP6OPT); 1674 1.155 christos break; 1675 1.155 christos } 1676 1.231 ozaki optp = &in6p_outputopts(inp); 1677 1.121 dyoung error = ip6_pcbopt(optname, optbuf, optbuflen, 1678 1.138 elad optp, kauth_cred_get(), uproto); 1679 1.158 maxv 1680 1.158 maxv free(optbuf, M_IP6OPT); 1681 1.121 dyoung break; 1682 1.130 plunky } 1683 1.2 itojun #undef OPTSET 1684 1.2 itojun 1685 1.121 dyoung case IPV6_MULTICAST_IF: 1686 1.121 dyoung case IPV6_MULTICAST_HOPS: 1687 1.121 dyoung case IPV6_MULTICAST_LOOP: 1688 1.121 dyoung case IPV6_JOIN_GROUP: 1689 1.132 plunky case IPV6_LEAVE_GROUP: 1690 1.230 ozaki error = ip6_setmoptions(sopt, inp); 1691 1.121 dyoung break; 1692 1.121 dyoung 1693 1.121 dyoung case IPV6_PORTRANGE: 1694 1.130 plunky error = sockopt_getint(sopt, &optval); 1695 1.130 plunky if (error) 1696 1.2 itojun break; 1697 1.2 itojun 1698 1.121 dyoung switch (optval) { 1699 1.121 dyoung case IPV6_PORTRANGE_DEFAULT: 1700 1.230 ozaki inp->inp_flags &= ~(IN6P_LOWPORT); 1701 1.230 ozaki inp->inp_flags &= ~(IN6P_HIGHPORT); 1702 1.121 dyoung break; 1703 1.12 itojun 1704 1.121 dyoung case IPV6_PORTRANGE_HIGH: 1705 1.230 ozaki inp->inp_flags &= ~(IN6P_LOWPORT); 1706 1.230 ozaki inp->inp_flags |= IN6P_HIGHPORT; 1707 1.121 dyoung break; 1708 1.12 itojun 1709 1.121 dyoung case IPV6_PORTRANGE_LOW: 1710 1.230 ozaki inp->inp_flags &= ~(IN6P_HIGHPORT); 1711 1.230 ozaki inp->inp_flags |= IN6P_LOWPORT; 1712 1.121 dyoung break; 1713 1.12 itojun 1714 1.121 dyoung default: 1715 1.121 dyoung error = EINVAL; 1716 1.12 itojun break; 1717 1.121 dyoung } 1718 1.121 dyoung break; 1719 1.12 itojun 1720 1.148 christos case IPV6_PORTALGO: 1721 1.148 christos error = sockopt_getint(sopt, &optval); 1722 1.148 christos if (error) 1723 1.148 christos break; 1724 1.148 christos 1725 1.230 ozaki error = portalgo_algo_index_select(inp, optval); 1726 1.148 christos break; 1727 1.114 degroote 1728 1.153 christos #if defined(IPSEC) 1729 1.121 dyoung case IPV6_IPSEC_POLICY: 1730 1.157 christos if (ipsec_enabled) { 1731 1.230 ozaki error = ipsec_set_policy(inp, 1732 1.157 christos sopt->sopt_data, sopt->sopt_size, 1733 1.157 christos kauth_cred_get()); 1734 1.217 mrg } else 1735 1.217 mrg error = ENOPROTOOPT; 1736 1.217 mrg break; 1737 1.2 itojun #endif /* IPSEC */ 1738 1.2 itojun 1739 1.121 dyoung default: 1740 1.121 dyoung error = ENOPROTOOPT; 1741 1.2 itojun break; 1742 1.121 dyoung } 1743 1.121 dyoung break; 1744 1.2 itojun 1745 1.121 dyoung case PRCO_GETOPT: 1746 1.121 dyoung switch (optname) { 1747 1.97 rpaulo #ifdef RFC2292 1748 1.121 dyoung case IPV6_2292PKTOPTIONS: 1749 1.121 dyoung /* 1750 1.121 dyoung * RFC3542 (effectively) deprecated the 1751 1.121 dyoung * semantics of the 2292-style pktoptions. 1752 1.121 dyoung * Since it was not reliable in nature (i.e., 1753 1.121 dyoung * applications had to expect the lack of some 1754 1.121 dyoung * information after all), it would make sense 1755 1.121 dyoung * to simplify this part by always returning 1756 1.121 dyoung * empty data. 1757 1.121 dyoung */ 1758 1.121 dyoung break; 1759 1.97 rpaulo #endif 1760 1.2 itojun 1761 1.121 dyoung case IPV6_RECVHOPOPTS: 1762 1.121 dyoung case IPV6_RECVDSTOPTS: 1763 1.121 dyoung case IPV6_RECVRTHDRDSTOPTS: 1764 1.121 dyoung case IPV6_UNICAST_HOPS: 1765 1.121 dyoung case IPV6_RECVPKTINFO: 1766 1.121 dyoung case IPV6_RECVHOPLIMIT: 1767 1.121 dyoung case IPV6_RECVRTHDR: 1768 1.121 dyoung case IPV6_RECVPATHMTU: 1769 1.121 dyoung 1770 1.121 dyoung case IPV6_FAITH: 1771 1.121 dyoung case IPV6_V6ONLY: 1772 1.121 dyoung case IPV6_PORTRANGE: 1773 1.121 dyoung case IPV6_RECVTCLASS: 1774 1.226 christos case IPV6_BINDANY: 1775 1.121 dyoung switch (optname) { 1776 1.121 dyoung 1777 1.97 rpaulo case IPV6_RECVHOPOPTS: 1778 1.121 dyoung optval = OPTBIT(IN6P_HOPOPTS); 1779 1.121 dyoung break; 1780 1.121 dyoung 1781 1.97 rpaulo case IPV6_RECVDSTOPTS: 1782 1.121 dyoung optval = OPTBIT(IN6P_DSTOPTS); 1783 1.121 dyoung break; 1784 1.121 dyoung 1785 1.97 rpaulo case IPV6_RECVRTHDRDSTOPTS: 1786 1.121 dyoung optval = OPTBIT(IN6P_RTHDRDSTOPTS); 1787 1.121 dyoung break; 1788 1.121 dyoung 1789 1.97 rpaulo case IPV6_UNICAST_HOPS: 1790 1.231 ozaki optval = in6p_hops6(inp); 1791 1.121 dyoung break; 1792 1.121 dyoung 1793 1.97 rpaulo case IPV6_RECVPKTINFO: 1794 1.121 dyoung optval = OPTBIT(IN6P_PKTINFO); 1795 1.121 dyoung break; 1796 1.121 dyoung 1797 1.97 rpaulo case IPV6_RECVHOPLIMIT: 1798 1.121 dyoung optval = OPTBIT(IN6P_HOPLIMIT); 1799 1.121 dyoung break; 1800 1.121 dyoung 1801 1.97 rpaulo case IPV6_RECVRTHDR: 1802 1.121 dyoung optval = OPTBIT(IN6P_RTHDR); 1803 1.121 dyoung break; 1804 1.121 dyoung 1805 1.97 rpaulo case IPV6_RECVPATHMTU: 1806 1.121 dyoung optval = OPTBIT(IN6P_MTU); 1807 1.121 dyoung break; 1808 1.2 itojun 1809 1.2 itojun case IPV6_FAITH: 1810 1.121 dyoung optval = OPTBIT(IN6P_FAITH); 1811 1.121 dyoung break; 1812 1.121 dyoung 1813 1.37 itojun case IPV6_V6ONLY: 1814 1.121 dyoung optval = OPTBIT(IN6P_IPV6_V6ONLY); 1815 1.121 dyoung break; 1816 1.121 dyoung 1817 1.97 rpaulo case IPV6_PORTRANGE: 1818 1.121 dyoung { 1819 1.121 dyoung int flags; 1820 1.230 ozaki flags = inp->inp_flags; 1821 1.121 dyoung if (flags & IN6P_HIGHPORT) 1822 1.121 dyoung optval = IPV6_PORTRANGE_HIGH; 1823 1.121 dyoung else if (flags & IN6P_LOWPORT) 1824 1.121 dyoung optval = IPV6_PORTRANGE_LOW; 1825 1.121 dyoung else 1826 1.121 dyoung optval = 0; 1827 1.121 dyoung break; 1828 1.121 dyoung } 1829 1.97 rpaulo case IPV6_RECVTCLASS: 1830 1.121 dyoung optval = OPTBIT(IN6P_TCLASS); 1831 1.121 dyoung break; 1832 1.2 itojun 1833 1.226 christos case IPV6_BINDANY: 1834 1.226 christos optval = OPTBIT(IN6P_BINDANY); 1835 1.226 christos break; 1836 1.121 dyoung } 1837 1.226 christos 1838 1.121 dyoung if (error) 1839 1.97 rpaulo break; 1840 1.130 plunky error = sockopt_setint(sopt, optval); 1841 1.121 dyoung break; 1842 1.97 rpaulo 1843 1.121 dyoung case IPV6_PATHMTU: 1844 1.121 dyoung { 1845 1.121 dyoung u_long pmtu = 0; 1846 1.121 dyoung struct ip6_mtuinfo mtuinfo; 1847 1.230 ozaki struct route *ro = &inp->inp_route; 1848 1.176 ozaki struct rtentry *rt; 1849 1.176 ozaki union { 1850 1.176 ozaki struct sockaddr dst; 1851 1.176 ozaki struct sockaddr_in6 dst6; 1852 1.176 ozaki } u; 1853 1.2 itojun 1854 1.121 dyoung if (!(so->so_state & SS_ISCONNECTED)) 1855 1.121 dyoung return (ENOTCONN); 1856 1.121 dyoung /* 1857 1.121 dyoung * XXX: we dot not consider the case of source 1858 1.121 dyoung * routing, or optional information to specify 1859 1.121 dyoung * the outgoing interface. 1860 1.121 dyoung */ 1861 1.231 ozaki sockaddr_in6_init(&u.dst6, &in6p_faddr(inp), 0, 0, 0); 1862 1.176 ozaki rt = rtcache_lookup(ro, &u.dst); 1863 1.176 ozaki error = ip6_getpmtu(rt, NULL, &pmtu, NULL); 1864 1.179 ozaki rtcache_unref(rt, ro); 1865 1.121 dyoung if (error) 1866 1.121 dyoung break; 1867 1.121 dyoung if (pmtu > IPV6_MAXPACKET) 1868 1.121 dyoung pmtu = IPV6_MAXPACKET; 1869 1.121 dyoung 1870 1.121 dyoung memset(&mtuinfo, 0, sizeof(mtuinfo)); 1871 1.121 dyoung mtuinfo.ip6m_mtu = (u_int32_t)pmtu; 1872 1.121 dyoung optdata = (void *)&mtuinfo; 1873 1.121 dyoung optdatalen = sizeof(mtuinfo); 1874 1.121 dyoung if (optdatalen > MCLBYTES) 1875 1.121 dyoung return (EMSGSIZE); /* XXX */ 1876 1.130 plunky error = sockopt_set(sopt, optdata, optdatalen); 1877 1.121 dyoung break; 1878 1.121 dyoung } 1879 1.97 rpaulo 1880 1.97 rpaulo #ifdef RFC2292 1881 1.121 dyoung case IPV6_2292PKTINFO: 1882 1.121 dyoung case IPV6_2292HOPLIMIT: 1883 1.121 dyoung case IPV6_2292HOPOPTS: 1884 1.121 dyoung case IPV6_2292RTHDR: 1885 1.121 dyoung case IPV6_2292DSTOPTS: 1886 1.121 dyoung switch (optname) { 1887 1.97 rpaulo case IPV6_2292PKTINFO: 1888 1.121 dyoung optval = OPTBIT(IN6P_PKTINFO); 1889 1.121 dyoung break; 1890 1.97 rpaulo case IPV6_2292HOPLIMIT: 1891 1.121 dyoung optval = OPTBIT(IN6P_HOPLIMIT); 1892 1.121 dyoung break; 1893 1.97 rpaulo case IPV6_2292HOPOPTS: 1894 1.121 dyoung optval = OPTBIT(IN6P_HOPOPTS); 1895 1.121 dyoung break; 1896 1.97 rpaulo case IPV6_2292RTHDR: 1897 1.121 dyoung optval = OPTBIT(IN6P_RTHDR); 1898 1.121 dyoung break; 1899 1.97 rpaulo case IPV6_2292DSTOPTS: 1900 1.121 dyoung optval = OPTBIT(IN6P_DSTOPTS|IN6P_RTHDRDSTOPTS); 1901 1.2 itojun break; 1902 1.121 dyoung } 1903 1.130 plunky error = sockopt_setint(sopt, optval); 1904 1.121 dyoung break; 1905 1.121 dyoung #endif 1906 1.121 dyoung case IPV6_PKTINFO: 1907 1.121 dyoung case IPV6_HOPOPTS: 1908 1.121 dyoung case IPV6_RTHDR: 1909 1.121 dyoung case IPV6_DSTOPTS: 1910 1.121 dyoung case IPV6_RTHDRDSTOPTS: 1911 1.121 dyoung case IPV6_NEXTHOP: 1912 1.121 dyoung case IPV6_OTCLASS: 1913 1.121 dyoung case IPV6_TCLASS: 1914 1.121 dyoung case IPV6_DONTFRAG: 1915 1.121 dyoung case IPV6_USE_MIN_MTU: 1916 1.161 roy case IPV6_PREFER_TEMPADDR: 1917 1.231 ozaki error = ip6_getpcbopt(in6p_outputopts(inp), 1918 1.130 plunky optname, sopt); 1919 1.121 dyoung break; 1920 1.121 dyoung 1921 1.121 dyoung case IPV6_MULTICAST_IF: 1922 1.121 dyoung case IPV6_MULTICAST_HOPS: 1923 1.121 dyoung case IPV6_MULTICAST_LOOP: 1924 1.121 dyoung case IPV6_JOIN_GROUP: 1925 1.132 plunky case IPV6_LEAVE_GROUP: 1926 1.230 ozaki error = ip6_getmoptions(sopt, inp); 1927 1.121 dyoung break; 1928 1.2 itojun 1929 1.148 christos case IPV6_PORTALGO: 1930 1.230 ozaki optval = inp->inp_portalgo; 1931 1.148 christos error = sockopt_setint(sopt, optval); 1932 1.148 christos break; 1933 1.148 christos 1934 1.153 christos #if defined(IPSEC) 1935 1.121 dyoung case IPV6_IPSEC_POLICY: 1936 1.157 christos if (ipsec_used) { 1937 1.157 christos struct mbuf *m = NULL; 1938 1.130 plunky 1939 1.157 christos /* 1940 1.157 christos * XXX: this will return EINVAL as sopt is 1941 1.157 christos * empty 1942 1.157 christos */ 1943 1.230 ozaki error = ipsec_get_policy(inp, sopt->sopt_data, 1944 1.157 christos sopt->sopt_size, &m); 1945 1.157 christos if (!error) 1946 1.157 christos error = sockopt_setmbuf(sopt, m); 1947 1.217 mrg } else 1948 1.217 mrg error = ENOPROTOOPT; 1949 1.217 mrg break; 1950 1.2 itojun #endif /* IPSEC */ 1951 1.2 itojun 1952 1.121 dyoung default: 1953 1.121 dyoung error = ENOPROTOOPT; 1954 1.2 itojun break; 1955 1.2 itojun } 1956 1.121 dyoung break; 1957 1.2 itojun } 1958 1.57 itojun return (error); 1959 1.53 itojun } 1960 1.53 itojun 1961 1.53 itojun int 1962 1.130 plunky ip6_raw_ctloutput(int op, struct socket *so, struct sockopt *sopt) 1963 1.53 itojun { 1964 1.130 plunky int error = 0, optval; 1965 1.53 itojun const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum); 1966 1.230 ozaki struct inpcb *inp = sotoinpcb(so); 1967 1.130 plunky int level, optname; 1968 1.53 itojun 1969 1.130 plunky KASSERT(sopt != NULL); 1970 1.130 plunky 1971 1.130 plunky level = sopt->sopt_level; 1972 1.130 plunky optname = sopt->sopt_name; 1973 1.53 itojun 1974 1.53 itojun if (level != IPPROTO_IPV6) { 1975 1.121 dyoung return ENOPROTOOPT; 1976 1.53 itojun } 1977 1.55 itojun 1978 1.53 itojun switch (optname) { 1979 1.53 itojun case IPV6_CHECKSUM: 1980 1.53 itojun /* 1981 1.53 itojun * For ICMPv6 sockets, no modification allowed for checksum 1982 1.53 itojun * offset, permit "no change" values to help existing apps. 1983 1.53 itojun * 1984 1.97 rpaulo * XXX RFC3542 says: "An attempt to set IPV6_CHECKSUM 1985 1.97 rpaulo * for an ICMPv6 socket will fail." The current 1986 1.97 rpaulo * behavior does not meet RFC3542. 1987 1.53 itojun */ 1988 1.53 itojun switch (op) { 1989 1.53 itojun case PRCO_SETOPT: 1990 1.130 plunky error = sockopt_getint(sopt, &optval); 1991 1.130 plunky if (error) 1992 1.53 itojun break; 1993 1.233 ozaki if (optval < -1 || 1994 1.233 ozaki (optval > 0 && (optval % 2) != 0)) { 1995 1.233 ozaki /* 1996 1.233 ozaki * The API assumes non-negative even offset 1997 1.233 ozaki * values or -1 as a special value. 1998 1.233 ozaki */ 1999 1.53 itojun error = EINVAL; 2000 1.53 itojun } else if (so->so_proto->pr_protocol == 2001 1.53 itojun IPPROTO_ICMPV6) { 2002 1.53 itojun if (optval != icmp6off) 2003 1.53 itojun error = EINVAL; 2004 1.53 itojun } else 2005 1.231 ozaki in6p_cksum(inp) = optval; 2006 1.53 itojun break; 2007 1.53 itojun 2008 1.53 itojun case PRCO_GETOPT: 2009 1.53 itojun if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) 2010 1.53 itojun optval = icmp6off; 2011 1.53 itojun else 2012 1.231 ozaki optval = in6p_cksum(inp); 2013 1.53 itojun 2014 1.130 plunky error = sockopt_setint(sopt, optval); 2015 1.53 itojun break; 2016 1.53 itojun 2017 1.53 itojun default: 2018 1.53 itojun error = EINVAL; 2019 1.53 itojun break; 2020 1.53 itojun } 2021 1.53 itojun break; 2022 1.53 itojun 2023 1.53 itojun default: 2024 1.53 itojun error = ENOPROTOOPT; 2025 1.53 itojun break; 2026 1.53 itojun } 2027 1.53 itojun 2028 1.57 itojun return (error); 2029 1.2 itojun } 2030 1.2 itojun 2031 1.97 rpaulo #ifdef RFC2292 2032 1.2 itojun /* 2033 1.97 rpaulo * Set up IP6 options in pcb for insertion in output packets or 2034 1.97 rpaulo * specifying behavior of outgoing packets. 2035 1.2 itojun */ 2036 1.2 itojun static int 2037 1.130 plunky ip6_pcbopts(struct ip6_pktopts **pktopt, struct socket *so, 2038 1.130 plunky struct sockopt *sopt) 2039 1.2 itojun { 2040 1.31 itojun struct ip6_pktopts *opt = *pktopt; 2041 1.130 plunky struct mbuf *m; 2042 1.2 itojun int error = 0; 2043 1.2 itojun 2044 1.185 ozaki KASSERT(solocked(so)); 2045 1.185 ozaki 2046 1.2 itojun /* turn off any old options. */ 2047 1.2 itojun if (opt) { 2048 1.97 rpaulo #ifdef DIAGNOSTIC 2049 1.97 rpaulo if (opt->ip6po_pktinfo || opt->ip6po_nexthop || 2050 1.97 rpaulo opt->ip6po_hbh || opt->ip6po_dest1 || opt->ip6po_dest2 || 2051 1.97 rpaulo opt->ip6po_rhinfo.ip6po_rhi_rthdr) 2052 1.97 rpaulo printf("ip6_pcbopts: all specified options are cleared.\n"); 2053 1.97 rpaulo #endif 2054 1.97 rpaulo ip6_clearpktopts(opt, -1); 2055 1.134 plunky } else { 2056 1.134 plunky opt = malloc(sizeof(*opt), M_IP6OPT, M_NOWAIT); 2057 1.134 plunky if (opt == NULL) 2058 1.134 plunky return (ENOBUFS); 2059 1.134 plunky } 2060 1.97 rpaulo *pktopt = NULL; 2061 1.2 itojun 2062 1.130 plunky if (sopt == NULL || sopt->sopt_size == 0) { 2063 1.2 itojun /* 2064 1.97 rpaulo * Only turning off any previous options, regardless of 2065 1.97 rpaulo * whether the opt is just created or given. 2066 1.2 itojun */ 2067 1.59 itojun free(opt, M_IP6OPT); 2068 1.57 itojun return (0); 2069 1.2 itojun } 2070 1.2 itojun 2071 1.2 itojun /* set options specified by user. */ 2072 1.130 plunky m = sockopt_getmbuf(sopt); 2073 1.135 plunky if (m == NULL) { 2074 1.135 plunky free(opt, M_IP6OPT); 2075 1.135 plunky return (ENOBUFS); 2076 1.135 plunky } 2077 1.135 plunky 2078 1.138 elad error = ip6_setpktopts(m, opt, NULL, kauth_cred_get(), 2079 1.138 elad so->so_proto->pr_protocol); 2080 1.130 plunky m_freem(m); 2081 1.130 plunky if (error != 0) { 2082 1.97 rpaulo ip6_clearpktopts(opt, -1); /* XXX: discard all options */ 2083 1.59 itojun free(opt, M_IP6OPT); 2084 1.57 itojun return (error); 2085 1.2 itojun } 2086 1.2 itojun *pktopt = opt; 2087 1.57 itojun return (0); 2088 1.2 itojun } 2089 1.97 rpaulo #endif 2090 1.97 rpaulo 2091 1.97 rpaulo /* 2092 1.97 rpaulo * initialize ip6_pktopts. beware that there are non-zero default values in 2093 1.97 rpaulo * the struct. 2094 1.97 rpaulo */ 2095 1.97 rpaulo void 2096 1.97 rpaulo ip6_initpktopts(struct ip6_pktopts *opt) 2097 1.97 rpaulo { 2098 1.97 rpaulo 2099 1.97 rpaulo memset(opt, 0, sizeof(*opt)); 2100 1.97 rpaulo opt->ip6po_hlim = -1; /* -1 means default hop limit */ 2101 1.97 rpaulo opt->ip6po_tclass = -1; /* -1 means default traffic class */ 2102 1.97 rpaulo opt->ip6po_minmtu = IP6PO_MINMTU_MCASTONLY; 2103 1.161 roy opt->ip6po_prefer_tempaddr = IP6PO_TEMPADDR_SYSTEM; 2104 1.97 rpaulo } 2105 1.97 rpaulo 2106 1.97 rpaulo #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) /* XXX */ 2107 1.97 rpaulo static int 2108 1.97 rpaulo ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt, 2109 1.138 elad kauth_cred_t cred, int uproto) 2110 1.97 rpaulo { 2111 1.97 rpaulo struct ip6_pktopts *opt; 2112 1.97 rpaulo 2113 1.97 rpaulo if (*pktopt == NULL) { 2114 1.97 rpaulo *pktopt = malloc(sizeof(struct ip6_pktopts), M_IP6OPT, 2115 1.133 plunky M_NOWAIT); 2116 1.133 plunky if (*pktopt == NULL) 2117 1.133 plunky return (ENOBUFS); 2118 1.133 plunky 2119 1.97 rpaulo ip6_initpktopts(*pktopt); 2120 1.97 rpaulo } 2121 1.97 rpaulo opt = *pktopt; 2122 1.97 rpaulo 2123 1.138 elad return (ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto)); 2124 1.97 rpaulo } 2125 1.97 rpaulo 2126 1.97 rpaulo static int 2127 1.130 plunky ip6_getpcbopt(struct ip6_pktopts *pktopt, int optname, struct sockopt *sopt) 2128 1.97 rpaulo { 2129 1.97 rpaulo void *optdata = NULL; 2130 1.97 rpaulo int optdatalen = 0; 2131 1.97 rpaulo struct ip6_ext *ip6e; 2132 1.97 rpaulo int error = 0; 2133 1.97 rpaulo struct in6_pktinfo null_pktinfo; 2134 1.97 rpaulo int deftclass = 0, on; 2135 1.97 rpaulo int defminmtu = IP6PO_MINMTU_MCASTONLY; 2136 1.161 roy int defpreftemp = IP6PO_TEMPADDR_SYSTEM; 2137 1.97 rpaulo 2138 1.97 rpaulo switch (optname) { 2139 1.97 rpaulo case IPV6_PKTINFO: 2140 1.97 rpaulo if (pktopt && pktopt->ip6po_pktinfo) 2141 1.97 rpaulo optdata = (void *)pktopt->ip6po_pktinfo; 2142 1.97 rpaulo else { 2143 1.97 rpaulo /* XXX: we don't have to do this every time... */ 2144 1.97 rpaulo memset(&null_pktinfo, 0, sizeof(null_pktinfo)); 2145 1.97 rpaulo optdata = (void *)&null_pktinfo; 2146 1.97 rpaulo } 2147 1.97 rpaulo optdatalen = sizeof(struct in6_pktinfo); 2148 1.97 rpaulo break; 2149 1.97 rpaulo case IPV6_OTCLASS: 2150 1.97 rpaulo /* XXX */ 2151 1.97 rpaulo return (EINVAL); 2152 1.97 rpaulo case IPV6_TCLASS: 2153 1.97 rpaulo if (pktopt && pktopt->ip6po_tclass >= 0) 2154 1.97 rpaulo optdata = (void *)&pktopt->ip6po_tclass; 2155 1.97 rpaulo else 2156 1.97 rpaulo optdata = (void *)&deftclass; 2157 1.97 rpaulo optdatalen = sizeof(int); 2158 1.97 rpaulo break; 2159 1.97 rpaulo case IPV6_HOPOPTS: 2160 1.97 rpaulo if (pktopt && pktopt->ip6po_hbh) { 2161 1.97 rpaulo optdata = (void *)pktopt->ip6po_hbh; 2162 1.97 rpaulo ip6e = (struct ip6_ext *)pktopt->ip6po_hbh; 2163 1.97 rpaulo optdatalen = (ip6e->ip6e_len + 1) << 3; 2164 1.97 rpaulo } 2165 1.97 rpaulo break; 2166 1.97 rpaulo case IPV6_RTHDR: 2167 1.97 rpaulo if (pktopt && pktopt->ip6po_rthdr) { 2168 1.97 rpaulo optdata = (void *)pktopt->ip6po_rthdr; 2169 1.97 rpaulo ip6e = (struct ip6_ext *)pktopt->ip6po_rthdr; 2170 1.97 rpaulo optdatalen = (ip6e->ip6e_len + 1) << 3; 2171 1.97 rpaulo } 2172 1.97 rpaulo break; 2173 1.97 rpaulo case IPV6_RTHDRDSTOPTS: 2174 1.97 rpaulo if (pktopt && pktopt->ip6po_dest1) { 2175 1.97 rpaulo optdata = (void *)pktopt->ip6po_dest1; 2176 1.97 rpaulo ip6e = (struct ip6_ext *)pktopt->ip6po_dest1; 2177 1.97 rpaulo optdatalen = (ip6e->ip6e_len + 1) << 3; 2178 1.97 rpaulo } 2179 1.97 rpaulo break; 2180 1.97 rpaulo case IPV6_DSTOPTS: 2181 1.97 rpaulo if (pktopt && pktopt->ip6po_dest2) { 2182 1.97 rpaulo optdata = (void *)pktopt->ip6po_dest2; 2183 1.97 rpaulo ip6e = (struct ip6_ext *)pktopt->ip6po_dest2; 2184 1.97 rpaulo optdatalen = (ip6e->ip6e_len + 1) << 3; 2185 1.97 rpaulo } 2186 1.97 rpaulo break; 2187 1.97 rpaulo case IPV6_NEXTHOP: 2188 1.97 rpaulo if (pktopt && pktopt->ip6po_nexthop) { 2189 1.97 rpaulo optdata = (void *)pktopt->ip6po_nexthop; 2190 1.97 rpaulo optdatalen = pktopt->ip6po_nexthop->sa_len; 2191 1.97 rpaulo } 2192 1.97 rpaulo break; 2193 1.97 rpaulo case IPV6_USE_MIN_MTU: 2194 1.97 rpaulo if (pktopt) 2195 1.97 rpaulo optdata = (void *)&pktopt->ip6po_minmtu; 2196 1.97 rpaulo else 2197 1.97 rpaulo optdata = (void *)&defminmtu; 2198 1.97 rpaulo optdatalen = sizeof(int); 2199 1.97 rpaulo break; 2200 1.97 rpaulo case IPV6_DONTFRAG: 2201 1.97 rpaulo if (pktopt && ((pktopt->ip6po_flags) & IP6PO_DONTFRAG)) 2202 1.97 rpaulo on = 1; 2203 1.97 rpaulo else 2204 1.97 rpaulo on = 0; 2205 1.97 rpaulo optdata = (void *)&on; 2206 1.97 rpaulo optdatalen = sizeof(on); 2207 1.97 rpaulo break; 2208 1.161 roy case IPV6_PREFER_TEMPADDR: 2209 1.161 roy if (pktopt) 2210 1.161 roy optdata = (void *)&pktopt->ip6po_prefer_tempaddr; 2211 1.161 roy else 2212 1.161 roy optdata = (void *)&defpreftemp; 2213 1.161 roy optdatalen = sizeof(int); 2214 1.163 christos break; 2215 1.97 rpaulo default: /* should not happen */ 2216 1.97 rpaulo #ifdef DIAGNOSTIC 2217 1.97 rpaulo panic("ip6_getpcbopt: unexpected option\n"); 2218 1.97 rpaulo #endif 2219 1.97 rpaulo return (ENOPROTOOPT); 2220 1.97 rpaulo } 2221 1.97 rpaulo 2222 1.130 plunky error = sockopt_set(sopt, optdata, optdatalen); 2223 1.97 rpaulo 2224 1.97 rpaulo return (error); 2225 1.97 rpaulo } 2226 1.97 rpaulo 2227 1.97 rpaulo void 2228 1.97 rpaulo ip6_clearpktopts(struct ip6_pktopts *pktopt, int optname) 2229 1.97 rpaulo { 2230 1.97 rpaulo if (optname == -1 || optname == IPV6_PKTINFO) { 2231 1.97 rpaulo if (pktopt->ip6po_pktinfo) 2232 1.97 rpaulo free(pktopt->ip6po_pktinfo, M_IP6OPT); 2233 1.97 rpaulo pktopt->ip6po_pktinfo = NULL; 2234 1.97 rpaulo } 2235 1.97 rpaulo if (optname == -1 || optname == IPV6_HOPLIMIT) 2236 1.97 rpaulo pktopt->ip6po_hlim = -1; 2237 1.97 rpaulo if (optname == -1 || optname == IPV6_TCLASS) 2238 1.97 rpaulo pktopt->ip6po_tclass = -1; 2239 1.97 rpaulo if (optname == -1 || optname == IPV6_NEXTHOP) { 2240 1.118 dyoung rtcache_free(&pktopt->ip6po_nextroute); 2241 1.97 rpaulo if (pktopt->ip6po_nexthop) 2242 1.97 rpaulo free(pktopt->ip6po_nexthop, M_IP6OPT); 2243 1.97 rpaulo pktopt->ip6po_nexthop = NULL; 2244 1.97 rpaulo } 2245 1.97 rpaulo if (optname == -1 || optname == IPV6_HOPOPTS) { 2246 1.97 rpaulo if (pktopt->ip6po_hbh) 2247 1.97 rpaulo free(pktopt->ip6po_hbh, M_IP6OPT); 2248 1.97 rpaulo pktopt->ip6po_hbh = NULL; 2249 1.97 rpaulo } 2250 1.97 rpaulo if (optname == -1 || optname == IPV6_RTHDRDSTOPTS) { 2251 1.97 rpaulo if (pktopt->ip6po_dest1) 2252 1.97 rpaulo free(pktopt->ip6po_dest1, M_IP6OPT); 2253 1.97 rpaulo pktopt->ip6po_dest1 = NULL; 2254 1.97 rpaulo } 2255 1.97 rpaulo if (optname == -1 || optname == IPV6_RTHDR) { 2256 1.97 rpaulo if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr) 2257 1.97 rpaulo free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT); 2258 1.97 rpaulo pktopt->ip6po_rhinfo.ip6po_rhi_rthdr = NULL; 2259 1.118 dyoung rtcache_free(&pktopt->ip6po_route); 2260 1.97 rpaulo } 2261 1.97 rpaulo if (optname == -1 || optname == IPV6_DSTOPTS) { 2262 1.97 rpaulo if (pktopt->ip6po_dest2) 2263 1.97 rpaulo free(pktopt->ip6po_dest2, M_IP6OPT); 2264 1.97 rpaulo pktopt->ip6po_dest2 = NULL; 2265 1.97 rpaulo } 2266 1.97 rpaulo } 2267 1.97 rpaulo 2268 1.97 rpaulo #define PKTOPT_EXTHDRCPY(type) \ 2269 1.97 rpaulo do { \ 2270 1.97 rpaulo if (src->type) { \ 2271 1.97 rpaulo int hlen = (((struct ip6_ext *)src->type)->ip6e_len + 1) << 3;\ 2272 1.97 rpaulo dst->type = malloc(hlen, M_IP6OPT, canwait); \ 2273 1.144 drochner if (dst->type == NULL) \ 2274 1.97 rpaulo goto bad; \ 2275 1.97 rpaulo memcpy(dst->type, src->type, hlen); \ 2276 1.97 rpaulo } \ 2277 1.97 rpaulo } while (/*CONSTCOND*/ 0) 2278 1.97 rpaulo 2279 1.97 rpaulo static int 2280 1.97 rpaulo copypktopts(struct ip6_pktopts *dst, struct ip6_pktopts *src, int canwait) 2281 1.97 rpaulo { 2282 1.97 rpaulo dst->ip6po_hlim = src->ip6po_hlim; 2283 1.97 rpaulo dst->ip6po_tclass = src->ip6po_tclass; 2284 1.97 rpaulo dst->ip6po_flags = src->ip6po_flags; 2285 1.162 roy dst->ip6po_minmtu = src->ip6po_minmtu; 2286 1.161 roy dst->ip6po_prefer_tempaddr = src->ip6po_prefer_tempaddr; 2287 1.97 rpaulo if (src->ip6po_pktinfo) { 2288 1.97 rpaulo dst->ip6po_pktinfo = malloc(sizeof(*dst->ip6po_pktinfo), 2289 1.97 rpaulo M_IP6OPT, canwait); 2290 1.144 drochner if (dst->ip6po_pktinfo == NULL) 2291 1.97 rpaulo goto bad; 2292 1.97 rpaulo *dst->ip6po_pktinfo = *src->ip6po_pktinfo; 2293 1.97 rpaulo } 2294 1.97 rpaulo if (src->ip6po_nexthop) { 2295 1.97 rpaulo dst->ip6po_nexthop = malloc(src->ip6po_nexthop->sa_len, 2296 1.97 rpaulo M_IP6OPT, canwait); 2297 1.144 drochner if (dst->ip6po_nexthop == NULL) 2298 1.97 rpaulo goto bad; 2299 1.97 rpaulo memcpy(dst->ip6po_nexthop, src->ip6po_nexthop, 2300 1.97 rpaulo src->ip6po_nexthop->sa_len); 2301 1.97 rpaulo } 2302 1.97 rpaulo PKTOPT_EXTHDRCPY(ip6po_hbh); 2303 1.97 rpaulo PKTOPT_EXTHDRCPY(ip6po_dest1); 2304 1.97 rpaulo PKTOPT_EXTHDRCPY(ip6po_dest2); 2305 1.97 rpaulo PKTOPT_EXTHDRCPY(ip6po_rthdr); /* not copy the cached route */ 2306 1.97 rpaulo return (0); 2307 1.97 rpaulo 2308 1.97 rpaulo bad: 2309 1.97 rpaulo if (dst->ip6po_pktinfo) free(dst->ip6po_pktinfo, M_IP6OPT); 2310 1.97 rpaulo if (dst->ip6po_nexthop) free(dst->ip6po_nexthop, M_IP6OPT); 2311 1.97 rpaulo if (dst->ip6po_hbh) free(dst->ip6po_hbh, M_IP6OPT); 2312 1.97 rpaulo if (dst->ip6po_dest1) free(dst->ip6po_dest1, M_IP6OPT); 2313 1.97 rpaulo if (dst->ip6po_dest2) free(dst->ip6po_dest2, M_IP6OPT); 2314 1.97 rpaulo if (dst->ip6po_rthdr) free(dst->ip6po_rthdr, M_IP6OPT); 2315 1.97 rpaulo 2316 1.97 rpaulo return (ENOBUFS); 2317 1.97 rpaulo } 2318 1.97 rpaulo #undef PKTOPT_EXTHDRCPY 2319 1.97 rpaulo 2320 1.97 rpaulo struct ip6_pktopts * 2321 1.97 rpaulo ip6_copypktopts(struct ip6_pktopts *src, int canwait) 2322 1.97 rpaulo { 2323 1.97 rpaulo int error; 2324 1.97 rpaulo struct ip6_pktopts *dst; 2325 1.97 rpaulo 2326 1.97 rpaulo dst = malloc(sizeof(*dst), M_IP6OPT, canwait); 2327 1.144 drochner if (dst == NULL) 2328 1.97 rpaulo return (NULL); 2329 1.97 rpaulo ip6_initpktopts(dst); 2330 1.97 rpaulo 2331 1.97 rpaulo if ((error = copypktopts(dst, src, canwait)) != 0) { 2332 1.97 rpaulo free(dst, M_IP6OPT); 2333 1.97 rpaulo return (NULL); 2334 1.97 rpaulo } 2335 1.97 rpaulo 2336 1.97 rpaulo return (dst); 2337 1.97 rpaulo } 2338 1.97 rpaulo 2339 1.97 rpaulo void 2340 1.97 rpaulo ip6_freepcbopts(struct ip6_pktopts *pktopt) 2341 1.97 rpaulo { 2342 1.97 rpaulo if (pktopt == NULL) 2343 1.97 rpaulo return; 2344 1.97 rpaulo 2345 1.97 rpaulo ip6_clearpktopts(pktopt, -1); 2346 1.97 rpaulo 2347 1.97 rpaulo free(pktopt, M_IP6OPT); 2348 1.97 rpaulo } 2349 1.2 itojun 2350 1.160 christos int 2351 1.189 ozaki ip6_get_membership(const struct sockopt *sopt, struct ifnet **ifp, 2352 1.189 ozaki struct psref *psref, void *v, size_t l) 2353 1.160 christos { 2354 1.160 christos struct ipv6_mreq mreq; 2355 1.160 christos int error; 2356 1.160 christos struct in6_addr *ia = &mreq.ipv6mr_multiaddr; 2357 1.160 christos struct in_addr *ia4 = (void *)&ia->s6_addr32[3]; 2358 1.189 ozaki 2359 1.160 christos error = sockopt_get(sopt, &mreq, sizeof(mreq)); 2360 1.160 christos if (error != 0) 2361 1.160 christos return error; 2362 1.160 christos 2363 1.160 christos if (IN6_IS_ADDR_UNSPECIFIED(ia)) { 2364 1.160 christos /* 2365 1.160 christos * We use the unspecified address to specify to accept 2366 1.160 christos * all multicast addresses. Only super user is allowed 2367 1.160 christos * to do this. 2368 1.160 christos */ 2369 1.229 christos if (kauth_authorize_network(kauth_cred_get(), 2370 1.229 christos KAUTH_NETWORK_IPV6, 2371 1.160 christos KAUTH_REQ_NETWORK_IPV6_JOIN_MULTICAST, NULL, NULL, NULL)) 2372 1.160 christos return EACCES; 2373 1.160 christos } else if (IN6_IS_ADDR_V4MAPPED(ia)) { 2374 1.160 christos // Don't bother if we are not going to use ifp. 2375 1.160 christos if (l == sizeof(*ia)) { 2376 1.160 christos memcpy(v, ia, l); 2377 1.160 christos return 0; 2378 1.160 christos } 2379 1.160 christos } else if (!IN6_IS_ADDR_MULTICAST(ia)) { 2380 1.160 christos return EINVAL; 2381 1.160 christos } 2382 1.160 christos 2383 1.160 christos /* 2384 1.160 christos * If no interface was explicitly specified, choose an 2385 1.160 christos * appropriate one according to the given multicast address. 2386 1.160 christos */ 2387 1.160 christos if (mreq.ipv6mr_interface == 0) { 2388 1.160 christos struct rtentry *rt; 2389 1.160 christos union { 2390 1.160 christos struct sockaddr dst; 2391 1.160 christos struct sockaddr_in dst4; 2392 1.160 christos struct sockaddr_in6 dst6; 2393 1.160 christos } u; 2394 1.160 christos struct route ro; 2395 1.160 christos 2396 1.160 christos /* 2397 1.160 christos * Look up the routing table for the 2398 1.160 christos * address, and choose the outgoing interface. 2399 1.160 christos * XXX: is it a good approach? 2400 1.160 christos */ 2401 1.160 christos memset(&ro, 0, sizeof(ro)); 2402 1.160 christos if (IN6_IS_ADDR_V4MAPPED(ia)) 2403 1.160 christos sockaddr_in_init(&u.dst4, ia4, 0); 2404 1.160 christos else 2405 1.160 christos sockaddr_in6_init(&u.dst6, ia, 0, 0, 0); 2406 1.165 ozaki error = rtcache_setdst(&ro, &u.dst); 2407 1.165 ozaki if (error != 0) 2408 1.165 ozaki return error; 2409 1.179 ozaki rt = rtcache_init(&ro); 2410 1.189 ozaki *ifp = rt != NULL ? 2411 1.189 ozaki if_get_byindex(rt->rt_ifp->if_index, psref) : NULL; 2412 1.179 ozaki rtcache_unref(rt, &ro); 2413 1.160 christos rtcache_free(&ro); 2414 1.160 christos } else { 2415 1.160 christos /* 2416 1.160 christos * If the interface is specified, validate it. 2417 1.160 christos */ 2418 1.189 ozaki *ifp = if_get_byindex(mreq.ipv6mr_interface, psref); 2419 1.189 ozaki if (*ifp == NULL) 2420 1.160 christos return ENXIO; /* XXX EINVAL? */ 2421 1.160 christos } 2422 1.160 christos if (sizeof(*ia) == l) 2423 1.160 christos memcpy(v, ia, l); 2424 1.160 christos else 2425 1.160 christos memcpy(v, ia4, l); 2426 1.160 christos return 0; 2427 1.160 christos } 2428 1.160 christos 2429 1.2 itojun /* 2430 1.2 itojun * Set the IP6 multicast options in response to user setsockopt(). 2431 1.2 itojun */ 2432 1.2 itojun static int 2433 1.230 ozaki ip6_setmoptions(const struct sockopt *sopt, struct inpcb *inp) 2434 1.2 itojun { 2435 1.2 itojun int error = 0; 2436 1.2 itojun u_int loop, ifindex; 2437 1.132 plunky struct ipv6_mreq mreq; 2438 1.160 christos struct in6_addr ia; 2439 1.2 itojun struct ifnet *ifp; 2440 1.231 ozaki struct ip6_moptions *im6o = in6p_moptions(inp); 2441 1.2 itojun struct in6_multi_mship *imm; 2442 1.2 itojun 2443 1.230 ozaki KASSERT(inp_locked(inp)); 2444 1.185 ozaki 2445 1.2 itojun if (im6o == NULL) { 2446 1.2 itojun /* 2447 1.2 itojun * No multicast option buffer attached to the pcb; 2448 1.2 itojun * allocate one and initialize to default values. 2449 1.2 itojun */ 2450 1.132 plunky im6o = malloc(sizeof(*im6o), M_IPMOPTS, M_NOWAIT); 2451 1.2 itojun if (im6o == NULL) 2452 1.57 itojun return (ENOBUFS); 2453 1.231 ozaki in6p_moptions(inp) = im6o; 2454 1.168 ozaki im6o->im6o_multicast_if_index = 0; 2455 1.2 itojun im6o->im6o_multicast_hlim = ip6_defmcasthlim; 2456 1.2 itojun im6o->im6o_multicast_loop = IPV6_DEFAULT_MULTICAST_LOOP; 2457 1.2 itojun LIST_INIT(&im6o->im6o_memberships); 2458 1.2 itojun } 2459 1.2 itojun 2460 1.132 plunky switch (sopt->sopt_name) { 2461 1.2 itojun 2462 1.189 ozaki case IPV6_MULTICAST_IF: { 2463 1.189 ozaki int s; 2464 1.2 itojun /* 2465 1.2 itojun * Select the interface for outgoing multicast packets. 2466 1.2 itojun */ 2467 1.132 plunky error = sockopt_get(sopt, &ifindex, sizeof(ifindex)); 2468 1.132 plunky if (error != 0) 2469 1.2 itojun break; 2470 1.132 plunky 2471 1.189 ozaki s = pserialize_read_enter(); 2472 1.87 drochner if (ifindex != 0) { 2473 1.156 rmind if ((ifp = if_byindex(ifindex)) == NULL) { 2474 1.189 ozaki pserialize_read_exit(s); 2475 1.87 drochner error = ENXIO; /* XXX EINVAL? */ 2476 1.87 drochner break; 2477 1.87 drochner } 2478 1.87 drochner if ((ifp->if_flags & IFF_MULTICAST) == 0) { 2479 1.189 ozaki pserialize_read_exit(s); 2480 1.87 drochner error = EADDRNOTAVAIL; 2481 1.87 drochner break; 2482 1.87 drochner } 2483 1.87 drochner } else 2484 1.87 drochner ifp = NULL; 2485 1.168 ozaki im6o->im6o_multicast_if_index = if_get_index(ifp); 2486 1.189 ozaki pserialize_read_exit(s); 2487 1.2 itojun break; 2488 1.189 ozaki } 2489 1.2 itojun 2490 1.2 itojun case IPV6_MULTICAST_HOPS: 2491 1.2 itojun { 2492 1.2 itojun /* 2493 1.2 itojun * Set the IP6 hoplimit for outgoing multicast packets. 2494 1.2 itojun */ 2495 1.2 itojun int optval; 2496 1.132 plunky 2497 1.132 plunky error = sockopt_getint(sopt, &optval); 2498 1.132 plunky if (error != 0) 2499 1.2 itojun break; 2500 1.132 plunky 2501 1.2 itojun if (optval < -1 || optval >= 256) 2502 1.2 itojun error = EINVAL; 2503 1.2 itojun else if (optval == -1) 2504 1.2 itojun im6o->im6o_multicast_hlim = ip6_defmcasthlim; 2505 1.2 itojun else 2506 1.2 itojun im6o->im6o_multicast_hlim = optval; 2507 1.2 itojun break; 2508 1.2 itojun } 2509 1.2 itojun 2510 1.2 itojun case IPV6_MULTICAST_LOOP: 2511 1.2 itojun /* 2512 1.2 itojun * Set the loopback flag for outgoing multicast packets. 2513 1.2 itojun * Must be zero or one. 2514 1.2 itojun */ 2515 1.132 plunky error = sockopt_get(sopt, &loop, sizeof(loop)); 2516 1.132 plunky if (error != 0) 2517 1.25 itojun break; 2518 1.25 itojun if (loop > 1) { 2519 1.2 itojun error = EINVAL; 2520 1.2 itojun break; 2521 1.2 itojun } 2522 1.2 itojun im6o->im6o_multicast_loop = loop; 2523 1.2 itojun break; 2524 1.2 itojun 2525 1.189 ozaki case IPV6_JOIN_GROUP: { 2526 1.189 ozaki int bound; 2527 1.189 ozaki struct psref psref; 2528 1.2 itojun /* 2529 1.2 itojun * Add a multicast group membership. 2530 1.2 itojun * Group must be a valid IP6 multicast address. 2531 1.2 itojun */ 2532 1.189 ozaki bound = curlwp_bind(); 2533 1.192 ozaki ifp = NULL; 2534 1.189 ozaki error = ip6_get_membership(sopt, &ifp, &psref, &ia, sizeof(ia)); 2535 1.189 ozaki if (error != 0) { 2536 1.192 ozaki KASSERT(ifp == NULL); 2537 1.189 ozaki curlwp_bindx(bound); 2538 1.160 christos return error; 2539 1.189 ozaki } 2540 1.132 plunky 2541 1.160 christos if (IN6_IS_ADDR_V4MAPPED(&ia)) { 2542 1.230 ozaki error = ip_setmoptions(&inp->inp_moptions, sopt); 2543 1.189 ozaki goto put_break; 2544 1.2 itojun } 2545 1.2 itojun /* 2546 1.2 itojun * See if we found an interface, and confirm that it 2547 1.2 itojun * supports multicast 2548 1.2 itojun */ 2549 1.2 itojun if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 2550 1.2 itojun error = EADDRNOTAVAIL; 2551 1.189 ozaki goto put_break; 2552 1.2 itojun } 2553 1.94 rpaulo 2554 1.160 christos if (in6_setscope(&ia, ifp, NULL)) { 2555 1.94 rpaulo error = EADDRNOTAVAIL; /* XXX: should not happen */ 2556 1.189 ozaki goto put_break; 2557 1.2 itojun } 2558 1.94 rpaulo 2559 1.2 itojun /* 2560 1.2 itojun * See if the membership already exists. 2561 1.2 itojun */ 2562 1.188 ozaki LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain) { 2563 1.2 itojun if (imm->i6mm_maddr->in6m_ifp == ifp && 2564 1.2 itojun IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, 2565 1.160 christos &ia)) 2566 1.189 ozaki goto put_break; 2567 1.188 ozaki } 2568 1.2 itojun if (imm != NULL) { 2569 1.2 itojun error = EADDRINUSE; 2570 1.189 ozaki goto put_break; 2571 1.2 itojun } 2572 1.2 itojun /* 2573 1.2 itojun * Everything looks good; add a new record to the multicast 2574 1.2 itojun * address list for the given interface. 2575 1.2 itojun */ 2576 1.160 christos imm = in6_joingroup(ifp, &ia, &error, 0); 2577 1.95 rpaulo if (imm == NULL) 2578 1.189 ozaki goto put_break; 2579 1.2 itojun LIST_INSERT_HEAD(&im6o->im6o_memberships, imm, i6mm_chain); 2580 1.189 ozaki put_break: 2581 1.189 ozaki if_put(ifp, &psref); 2582 1.189 ozaki curlwp_bindx(bound); 2583 1.2 itojun break; 2584 1.189 ozaki } 2585 1.2 itojun 2586 1.196 ozaki case IPV6_LEAVE_GROUP: { 2587 1.2 itojun /* 2588 1.2 itojun * Drop a multicast group membership. 2589 1.2 itojun * Group must be a valid IP6 multicast address. 2590 1.2 itojun */ 2591 1.132 plunky error = sockopt_get(sopt, &mreq, sizeof(mreq)); 2592 1.132 plunky if (error != 0) 2593 1.2 itojun break; 2594 1.94 rpaulo 2595 1.160 christos if (IN6_IS_ADDR_V4MAPPED(&mreq.ipv6mr_multiaddr)) { 2596 1.230 ozaki error = ip_setmoptions(&inp->inp_moptions, sopt); 2597 1.160 christos break; 2598 1.160 christos } 2599 1.2 itojun /* 2600 1.2 itojun * If an interface address was specified, get a pointer 2601 1.2 itojun * to its ifnet structure. 2602 1.2 itojun */ 2603 1.132 plunky if (mreq.ipv6mr_interface != 0) { 2604 1.156 rmind if ((ifp = if_byindex(mreq.ipv6mr_interface)) == NULL) { 2605 1.87 drochner error = ENXIO; /* XXX EINVAL? */ 2606 1.87 drochner break; 2607 1.87 drochner } 2608 1.87 drochner } else 2609 1.87 drochner ifp = NULL; 2610 1.94 rpaulo 2611 1.94 rpaulo /* Fill in the scope zone ID */ 2612 1.94 rpaulo if (ifp) { 2613 1.132 plunky if (in6_setscope(&mreq.ipv6mr_multiaddr, ifp, NULL)) { 2614 1.94 rpaulo /* XXX: should not happen */ 2615 1.94 rpaulo error = EADDRNOTAVAIL; 2616 1.94 rpaulo break; 2617 1.94 rpaulo } 2618 1.132 plunky } else if (mreq.ipv6mr_interface != 0) { 2619 1.94 rpaulo /* 2620 1.94 rpaulo * XXX: This case would happens when the (positive) 2621 1.94 rpaulo * index is in the valid range, but the corresponding 2622 1.94 rpaulo * interface has been detached dynamically. The above 2623 1.94 rpaulo * check probably avoids such case to happen here, but 2624 1.94 rpaulo * we check it explicitly for safety. 2625 1.94 rpaulo */ 2626 1.94 rpaulo error = EADDRNOTAVAIL; 2627 1.197 maxv break; 2628 1.94 rpaulo } else { /* ipv6mr_interface == 0 */ 2629 1.94 rpaulo struct sockaddr_in6 sa6_mc; 2630 1.94 rpaulo 2631 1.94 rpaulo /* 2632 1.94 rpaulo * The API spec says as follows: 2633 1.94 rpaulo * If the interface index is specified as 0, the 2634 1.94 rpaulo * system may choose a multicast group membership to 2635 1.94 rpaulo * drop by matching the multicast address only. 2636 1.94 rpaulo * On the other hand, we cannot disambiguate the scope 2637 1.94 rpaulo * zone unless an interface is provided. Thus, we 2638 1.94 rpaulo * check if there's ambiguity with the default scope 2639 1.94 rpaulo * zone as the last resort. 2640 1.94 rpaulo */ 2641 1.132 plunky sockaddr_in6_init(&sa6_mc, &mreq.ipv6mr_multiaddr, 2642 1.123 dyoung 0, 0, 0); 2643 1.94 rpaulo error = sa6_embedscope(&sa6_mc, ip6_use_defzone); 2644 1.94 rpaulo if (error != 0) 2645 1.94 rpaulo break; 2646 1.132 plunky mreq.ipv6mr_multiaddr = sa6_mc.sin6_addr; 2647 1.2 itojun } 2648 1.94 rpaulo 2649 1.2 itojun /* 2650 1.2 itojun * Find the membership in the membership list. 2651 1.2 itojun */ 2652 1.188 ozaki LIST_FOREACH(imm, &im6o->im6o_memberships, i6mm_chain) { 2653 1.49 itojun if ((ifp == NULL || imm->i6mm_maddr->in6m_ifp == ifp) && 2654 1.2 itojun IN6_ARE_ADDR_EQUAL(&imm->i6mm_maddr->in6m_addr, 2655 1.132 plunky &mreq.ipv6mr_multiaddr)) 2656 1.2 itojun break; 2657 1.2 itojun } 2658 1.2 itojun if (imm == NULL) { 2659 1.2 itojun /* Unable to resolve interface */ 2660 1.2 itojun error = EADDRNOTAVAIL; 2661 1.2 itojun break; 2662 1.2 itojun } 2663 1.2 itojun /* 2664 1.2 itojun * Give up the multicast address record to which the 2665 1.2 itojun * membership points. 2666 1.2 itojun */ 2667 1.2 itojun LIST_REMOVE(imm, i6mm_chain); 2668 1.43 itojun in6_leavegroup(imm); 2669 1.230 ozaki /* in6m_ifp should not leave thanks to inp_lock */ 2670 1.2 itojun break; 2671 1.196 ozaki } 2672 1.2 itojun 2673 1.2 itojun default: 2674 1.2 itojun error = EOPNOTSUPP; 2675 1.2 itojun break; 2676 1.2 itojun } 2677 1.2 itojun 2678 1.2 itojun /* 2679 1.2 itojun * If all options have default values, no need to keep the mbuf. 2680 1.2 itojun */ 2681 1.168 ozaki if (im6o->im6o_multicast_if_index == 0 && 2682 1.2 itojun im6o->im6o_multicast_hlim == ip6_defmcasthlim && 2683 1.2 itojun im6o->im6o_multicast_loop == IPV6_DEFAULT_MULTICAST_LOOP && 2684 1.188 ozaki LIST_EMPTY(&im6o->im6o_memberships)) { 2685 1.231 ozaki free(in6p_moptions(inp), M_IPMOPTS); 2686 1.231 ozaki in6p_moptions(inp) = NULL; 2687 1.2 itojun } 2688 1.2 itojun 2689 1.57 itojun return (error); 2690 1.2 itojun } 2691 1.2 itojun 2692 1.2 itojun /* 2693 1.2 itojun * Return the IP6 multicast options in response to user getsockopt(). 2694 1.2 itojun */ 2695 1.2 itojun static int 2696 1.230 ozaki ip6_getmoptions(struct sockopt *sopt, struct inpcb *inp) 2697 1.2 itojun { 2698 1.132 plunky u_int optval; 2699 1.132 plunky int error; 2700 1.231 ozaki struct ip6_moptions *im6o = in6p_moptions(inp); 2701 1.2 itojun 2702 1.132 plunky switch (sopt->sopt_name) { 2703 1.2 itojun case IPV6_MULTICAST_IF: 2704 1.168 ozaki if (im6o == NULL || im6o->im6o_multicast_if_index == 0) 2705 1.132 plunky optval = 0; 2706 1.2 itojun else 2707 1.168 ozaki optval = im6o->im6o_multicast_if_index; 2708 1.132 plunky 2709 1.132 plunky error = sockopt_set(sopt, &optval, sizeof(optval)); 2710 1.132 plunky break; 2711 1.2 itojun 2712 1.2 itojun case IPV6_MULTICAST_HOPS: 2713 1.2 itojun if (im6o == NULL) 2714 1.132 plunky optval = ip6_defmcasthlim; 2715 1.2 itojun else 2716 1.132 plunky optval = im6o->im6o_multicast_hlim; 2717 1.132 plunky 2718 1.132 plunky error = sockopt_set(sopt, &optval, sizeof(optval)); 2719 1.132 plunky break; 2720 1.2 itojun 2721 1.2 itojun case IPV6_MULTICAST_LOOP: 2722 1.2 itojun if (im6o == NULL) 2723 1.151 kefren optval = IPV6_DEFAULT_MULTICAST_LOOP; 2724 1.2 itojun else 2725 1.132 plunky optval = im6o->im6o_multicast_loop; 2726 1.132 plunky 2727 1.132 plunky error = sockopt_set(sopt, &optval, sizeof(optval)); 2728 1.132 plunky break; 2729 1.2 itojun 2730 1.2 itojun default: 2731 1.132 plunky error = EOPNOTSUPP; 2732 1.2 itojun } 2733 1.132 plunky 2734 1.132 plunky return (error); 2735 1.2 itojun } 2736 1.2 itojun 2737 1.2 itojun /* 2738 1.2 itojun * Discard the IP6 multicast options. 2739 1.2 itojun */ 2740 1.2 itojun void 2741 1.119 christos ip6_freemoptions(struct ip6_moptions *im6o) 2742 1.2 itojun { 2743 1.188 ozaki struct in6_multi_mship *imm, *nimm; 2744 1.2 itojun 2745 1.2 itojun if (im6o == NULL) 2746 1.2 itojun return; 2747 1.2 itojun 2748 1.230 ozaki /* The owner of im6o (inp) should be protected by solock */ 2749 1.188 ozaki LIST_FOREACH_SAFE(imm, &im6o->im6o_memberships, i6mm_chain, nimm) { 2750 1.2 itojun LIST_REMOVE(imm, i6mm_chain); 2751 1.43 itojun in6_leavegroup(imm); 2752 1.2 itojun } 2753 1.2 itojun free(im6o, M_IPMOPTS); 2754 1.2 itojun } 2755 1.2 itojun 2756 1.2 itojun /* 2757 1.2 itojun * Set IPv6 outgoing packet options based on advanced API. 2758 1.2 itojun */ 2759 1.2 itojun int 2760 1.197 maxv ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt, 2761 1.138 elad struct ip6_pktopts *stickyopt, kauth_cred_t cred, int uproto) 2762 1.2 itojun { 2763 1.31 itojun struct cmsghdr *cm = 0; 2764 1.2 itojun 2765 1.97 rpaulo if (control == NULL || opt == NULL) 2766 1.57 itojun return (EINVAL); 2767 1.2 itojun 2768 1.97 rpaulo ip6_initpktopts(opt); 2769 1.97 rpaulo if (stickyopt) { 2770 1.97 rpaulo int error; 2771 1.97 rpaulo 2772 1.97 rpaulo /* 2773 1.97 rpaulo * If stickyopt is provided, make a local copy of the options 2774 1.97 rpaulo * for this particular packet, then override them by ancillary 2775 1.97 rpaulo * objects. 2776 1.97 rpaulo * XXX: copypktopts() does not copy the cached route to a next 2777 1.97 rpaulo * hop (if any). This is not very good in terms of efficiency, 2778 1.97 rpaulo * but we can allow this since this option should be rarely 2779 1.97 rpaulo * used. 2780 1.97 rpaulo */ 2781 1.97 rpaulo if ((error = copypktopts(opt, stickyopt, M_NOWAIT)) != 0) 2782 1.97 rpaulo return (error); 2783 1.97 rpaulo } 2784 1.2 itojun 2785 1.2 itojun /* 2786 1.2 itojun * XXX: Currently, we assume all the optional information is stored 2787 1.2 itojun * in a single mbuf. 2788 1.2 itojun */ 2789 1.2 itojun if (control->m_next) 2790 1.57 itojun return (EINVAL); 2791 1.2 itojun 2792 1.137 drochner /* XXX if cm->cmsg_len is not aligned, control->m_len can become <0 */ 2793 1.137 drochner for (; control->m_len > 0; control->m_data += CMSG_ALIGN(cm->cmsg_len), 2794 1.49 itojun control->m_len -= CMSG_ALIGN(cm->cmsg_len)) { 2795 1.97 rpaulo int error; 2796 1.97 rpaulo 2797 1.97 rpaulo if (control->m_len < CMSG_LEN(0)) 2798 1.97 rpaulo return (EINVAL); 2799 1.97 rpaulo 2800 1.2 itojun cm = mtod(control, struct cmsghdr *); 2801 1.218 maxv if (cm->cmsg_len < CMSG_LEN(0) || cm->cmsg_len > control->m_len) 2802 1.57 itojun return (EINVAL); 2803 1.2 itojun if (cm->cmsg_level != IPPROTO_IPV6) 2804 1.2 itojun continue; 2805 1.2 itojun 2806 1.97 rpaulo error = ip6_setpktopt(cm->cmsg_type, CMSG_DATA(cm), 2807 1.138 elad cm->cmsg_len - CMSG_LEN(0), opt, cred, 0, 1, uproto); 2808 1.97 rpaulo if (error) 2809 1.97 rpaulo return (error); 2810 1.97 rpaulo } 2811 1.97 rpaulo 2812 1.97 rpaulo return (0); 2813 1.97 rpaulo } 2814 1.97 rpaulo 2815 1.97 rpaulo /* 2816 1.97 rpaulo * Set a particular packet option, as a sticky option or an ancillary data 2817 1.97 rpaulo * item. "len" can be 0 only when it's a sticky option. 2818 1.97 rpaulo * We have 4 cases of combination of "sticky" and "cmsg": 2819 1.97 rpaulo * "sticky=0, cmsg=0": impossible 2820 1.97 rpaulo * "sticky=0, cmsg=1": RFC2292 or RFC3542 ancillary data 2821 1.97 rpaulo * "sticky=1, cmsg=0": RFC3542 socket option 2822 1.97 rpaulo * "sticky=1, cmsg=1": RFC2292 socket option 2823 1.97 rpaulo */ 2824 1.97 rpaulo static int 2825 1.97 rpaulo ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, 2826 1.138 elad kauth_cred_t cred, int sticky, int cmsg, int uproto) 2827 1.97 rpaulo { 2828 1.97 rpaulo int minmtupolicy; 2829 1.139 elad int error; 2830 1.97 rpaulo 2831 1.97 rpaulo if (!sticky && !cmsg) { 2832 1.97 rpaulo #ifdef DIAGNOSTIC 2833 1.97 rpaulo printf("ip6_setpktopt: impossible case\n"); 2834 1.97 rpaulo #endif 2835 1.97 rpaulo return (EINVAL); 2836 1.97 rpaulo } 2837 1.97 rpaulo 2838 1.97 rpaulo /* 2839 1.97 rpaulo * IPV6_2292xxx is for backward compatibility to RFC2292, and should 2840 1.97 rpaulo * not be specified in the context of RFC3542. Conversely, 2841 1.97 rpaulo * RFC3542 types should not be specified in the context of RFC2292. 2842 1.97 rpaulo */ 2843 1.97 rpaulo if (!cmsg) { 2844 1.97 rpaulo switch (optname) { 2845 1.97 rpaulo case IPV6_2292PKTINFO: 2846 1.97 rpaulo case IPV6_2292HOPLIMIT: 2847 1.97 rpaulo case IPV6_2292NEXTHOP: 2848 1.97 rpaulo case IPV6_2292HOPOPTS: 2849 1.97 rpaulo case IPV6_2292DSTOPTS: 2850 1.97 rpaulo case IPV6_2292RTHDR: 2851 1.97 rpaulo case IPV6_2292PKTOPTIONS: 2852 1.97 rpaulo return (ENOPROTOOPT); 2853 1.97 rpaulo } 2854 1.97 rpaulo } 2855 1.97 rpaulo if (sticky && cmsg) { 2856 1.97 rpaulo switch (optname) { 2857 1.2 itojun case IPV6_PKTINFO: 2858 1.97 rpaulo case IPV6_HOPLIMIT: 2859 1.97 rpaulo case IPV6_NEXTHOP: 2860 1.97 rpaulo case IPV6_HOPOPTS: 2861 1.97 rpaulo case IPV6_DSTOPTS: 2862 1.97 rpaulo case IPV6_RTHDRDSTOPTS: 2863 1.97 rpaulo case IPV6_RTHDR: 2864 1.97 rpaulo case IPV6_USE_MIN_MTU: 2865 1.97 rpaulo case IPV6_DONTFRAG: 2866 1.97 rpaulo case IPV6_OTCLASS: 2867 1.97 rpaulo case IPV6_TCLASS: 2868 1.161 roy case IPV6_PREFER_TEMPADDR: /* XXX not an RFC3542 option */ 2869 1.97 rpaulo return (ENOPROTOOPT); 2870 1.97 rpaulo } 2871 1.97 rpaulo } 2872 1.97 rpaulo 2873 1.97 rpaulo switch (optname) { 2874 1.97 rpaulo #ifdef RFC2292 2875 1.97 rpaulo case IPV6_2292PKTINFO: 2876 1.97 rpaulo #endif 2877 1.97 rpaulo case IPV6_PKTINFO: 2878 1.97 rpaulo { 2879 1.97 rpaulo struct in6_pktinfo *pktinfo; 2880 1.97 rpaulo 2881 1.97 rpaulo if (len != sizeof(struct in6_pktinfo)) 2882 1.97 rpaulo return (EINVAL); 2883 1.97 rpaulo 2884 1.97 rpaulo pktinfo = (struct in6_pktinfo *)buf; 2885 1.97 rpaulo 2886 1.97 rpaulo /* 2887 1.97 rpaulo * An application can clear any sticky IPV6_PKTINFO option by 2888 1.97 rpaulo * doing a "regular" setsockopt with ipi6_addr being 2889 1.97 rpaulo * in6addr_any and ipi6_ifindex being zero. 2890 1.97 rpaulo * [RFC 3542, Section 6] 2891 1.97 rpaulo */ 2892 1.97 rpaulo if (optname == IPV6_PKTINFO && opt->ip6po_pktinfo && 2893 1.97 rpaulo pktinfo->ipi6_ifindex == 0 && 2894 1.97 rpaulo IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { 2895 1.97 rpaulo ip6_clearpktopts(opt, optname); 2896 1.97 rpaulo break; 2897 1.97 rpaulo } 2898 1.97 rpaulo 2899 1.97 rpaulo if (uproto == IPPROTO_TCP && optname == IPV6_PKTINFO && 2900 1.97 rpaulo sticky && !IN6_IS_ADDR_UNSPECIFIED(&pktinfo->ipi6_addr)) { 2901 1.97 rpaulo return (EINVAL); 2902 1.97 rpaulo } 2903 1.97 rpaulo 2904 1.156 rmind /* Validate the interface index if specified. */ 2905 1.97 rpaulo if (pktinfo->ipi6_ifindex) { 2906 1.169 ozaki struct ifnet *ifp; 2907 1.169 ozaki int s = pserialize_read_enter(); 2908 1.156 rmind ifp = if_byindex(pktinfo->ipi6_ifindex); 2909 1.169 ozaki if (ifp == NULL) { 2910 1.169 ozaki pserialize_read_exit(s); 2911 1.169 ozaki return ENXIO; 2912 1.169 ozaki } 2913 1.169 ozaki pserialize_read_exit(s); 2914 1.97 rpaulo } 2915 1.97 rpaulo 2916 1.97 rpaulo /* 2917 1.97 rpaulo * We store the address anyway, and let in6_selectsrc() 2918 1.97 rpaulo * validate the specified address. This is because ipi6_addr 2919 1.97 rpaulo * may not have enough information about its scope zone, and 2920 1.97 rpaulo * we may need additional information (such as outgoing 2921 1.97 rpaulo * interface or the scope zone of a destination address) to 2922 1.97 rpaulo * disambiguate the scope. 2923 1.97 rpaulo * XXX: the delay of the validation may confuse the 2924 1.97 rpaulo * application when it is used as a sticky option. 2925 1.97 rpaulo */ 2926 1.97 rpaulo if (opt->ip6po_pktinfo == NULL) { 2927 1.97 rpaulo opt->ip6po_pktinfo = malloc(sizeof(*pktinfo), 2928 1.97 rpaulo M_IP6OPT, M_NOWAIT); 2929 1.97 rpaulo if (opt->ip6po_pktinfo == NULL) 2930 1.97 rpaulo return (ENOBUFS); 2931 1.97 rpaulo } 2932 1.97 rpaulo memcpy(opt->ip6po_pktinfo, pktinfo, sizeof(*pktinfo)); 2933 1.97 rpaulo break; 2934 1.97 rpaulo } 2935 1.97 rpaulo 2936 1.97 rpaulo #ifdef RFC2292 2937 1.97 rpaulo case IPV6_2292HOPLIMIT: 2938 1.97 rpaulo #endif 2939 1.97 rpaulo case IPV6_HOPLIMIT: 2940 1.97 rpaulo { 2941 1.97 rpaulo int *hlimp; 2942 1.97 rpaulo 2943 1.97 rpaulo /* 2944 1.97 rpaulo * RFC 3542 deprecated the usage of sticky IPV6_HOPLIMIT 2945 1.97 rpaulo * to simplify the ordering among hoplimit options. 2946 1.97 rpaulo */ 2947 1.97 rpaulo if (optname == IPV6_HOPLIMIT && sticky) 2948 1.97 rpaulo return (ENOPROTOOPT); 2949 1.97 rpaulo 2950 1.97 rpaulo if (len != sizeof(int)) 2951 1.97 rpaulo return (EINVAL); 2952 1.97 rpaulo hlimp = (int *)buf; 2953 1.97 rpaulo if (*hlimp < -1 || *hlimp > 255) 2954 1.97 rpaulo return (EINVAL); 2955 1.97 rpaulo 2956 1.97 rpaulo opt->ip6po_hlim = *hlimp; 2957 1.97 rpaulo break; 2958 1.97 rpaulo } 2959 1.97 rpaulo 2960 1.97 rpaulo case IPV6_OTCLASS: 2961 1.97 rpaulo if (len != sizeof(u_int8_t)) 2962 1.97 rpaulo return (EINVAL); 2963 1.97 rpaulo 2964 1.97 rpaulo opt->ip6po_tclass = *(u_int8_t *)buf; 2965 1.97 rpaulo break; 2966 1.97 rpaulo 2967 1.97 rpaulo case IPV6_TCLASS: 2968 1.97 rpaulo { 2969 1.97 rpaulo int tclass; 2970 1.97 rpaulo 2971 1.97 rpaulo if (len != sizeof(int)) 2972 1.97 rpaulo return (EINVAL); 2973 1.97 rpaulo tclass = *(int *)buf; 2974 1.97 rpaulo if (tclass < -1 || tclass > 255) 2975 1.97 rpaulo return (EINVAL); 2976 1.2 itojun 2977 1.97 rpaulo opt->ip6po_tclass = tclass; 2978 1.97 rpaulo break; 2979 1.97 rpaulo } 2980 1.94 rpaulo 2981 1.97 rpaulo #ifdef RFC2292 2982 1.97 rpaulo case IPV6_2292NEXTHOP: 2983 1.97 rpaulo #endif 2984 1.97 rpaulo case IPV6_NEXTHOP: 2985 1.229 christos error = kauth_authorize_network(cred, 2986 1.229 christos KAUTH_NETWORK_IPV6, 2987 1.146 elad KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, NULL, NULL); 2988 1.139 elad if (error) 2989 1.139 elad return (error); 2990 1.35 itojun 2991 1.97 rpaulo if (len == 0) { /* just remove the option */ 2992 1.97 rpaulo ip6_clearpktopts(opt, IPV6_NEXTHOP); 2993 1.2 itojun break; 2994 1.97 rpaulo } 2995 1.97 rpaulo 2996 1.97 rpaulo /* check if cmsg_len is large enough for sa_len */ 2997 1.97 rpaulo if (len < sizeof(struct sockaddr) || len < *buf) 2998 1.97 rpaulo return (EINVAL); 2999 1.97 rpaulo 3000 1.97 rpaulo switch (((struct sockaddr *)buf)->sa_family) { 3001 1.97 rpaulo case AF_INET6: 3002 1.97 rpaulo { 3003 1.97 rpaulo struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)buf; 3004 1.2 itojun 3005 1.97 rpaulo if (sa6->sin6_len != sizeof(struct sockaddr_in6)) 3006 1.57 itojun return (EINVAL); 3007 1.2 itojun 3008 1.97 rpaulo if (IN6_IS_ADDR_UNSPECIFIED(&sa6->sin6_addr) || 3009 1.97 rpaulo IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) { 3010 1.97 rpaulo return (EINVAL); 3011 1.97 rpaulo } 3012 1.97 rpaulo if ((error = sa6_embedscope(sa6, ip6_use_defzone)) 3013 1.97 rpaulo != 0) { 3014 1.97 rpaulo return (error); 3015 1.67 itojun } 3016 1.2 itojun break; 3017 1.97 rpaulo } 3018 1.97 rpaulo case AF_LINK: /* eventually be supported? */ 3019 1.97 rpaulo default: 3020 1.97 rpaulo return (EAFNOSUPPORT); 3021 1.97 rpaulo } 3022 1.2 itojun 3023 1.97 rpaulo /* turn off the previous option, then set the new option. */ 3024 1.97 rpaulo ip6_clearpktopts(opt, IPV6_NEXTHOP); 3025 1.97 rpaulo opt->ip6po_nexthop = malloc(*buf, M_IP6OPT, M_NOWAIT); 3026 1.97 rpaulo if (opt->ip6po_nexthop == NULL) 3027 1.97 rpaulo return (ENOBUFS); 3028 1.97 rpaulo memcpy(opt->ip6po_nexthop, buf, *buf); 3029 1.97 rpaulo break; 3030 1.97 rpaulo 3031 1.97 rpaulo #ifdef RFC2292 3032 1.97 rpaulo case IPV6_2292HOPOPTS: 3033 1.97 rpaulo #endif 3034 1.97 rpaulo case IPV6_HOPOPTS: 3035 1.97 rpaulo { 3036 1.97 rpaulo struct ip6_hbh *hbh; 3037 1.97 rpaulo int hbhlen; 3038 1.97 rpaulo 3039 1.97 rpaulo /* 3040 1.97 rpaulo * XXX: We don't allow a non-privileged user to set ANY HbH 3041 1.97 rpaulo * options, since per-option restriction has too much 3042 1.97 rpaulo * overhead. 3043 1.97 rpaulo */ 3044 1.229 christos error = kauth_authorize_network(cred, 3045 1.229 christos KAUTH_NETWORK_IPV6, 3046 1.146 elad KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, NULL, NULL); 3047 1.139 elad if (error) 3048 1.139 elad return (error); 3049 1.97 rpaulo 3050 1.97 rpaulo if (len == 0) { 3051 1.97 rpaulo ip6_clearpktopts(opt, IPV6_HOPOPTS); 3052 1.97 rpaulo break; /* just remove the option */ 3053 1.97 rpaulo } 3054 1.31 itojun 3055 1.97 rpaulo /* message length validation */ 3056 1.97 rpaulo if (len < sizeof(struct ip6_hbh)) 3057 1.97 rpaulo return (EINVAL); 3058 1.97 rpaulo hbh = (struct ip6_hbh *)buf; 3059 1.97 rpaulo hbhlen = (hbh->ip6h_len + 1) << 3; 3060 1.97 rpaulo if (len != hbhlen) 3061 1.97 rpaulo return (EINVAL); 3062 1.2 itojun 3063 1.97 rpaulo /* turn off the previous option, then set the new option. */ 3064 1.97 rpaulo ip6_clearpktopts(opt, IPV6_HOPOPTS); 3065 1.97 rpaulo opt->ip6po_hbh = malloc(hbhlen, M_IP6OPT, M_NOWAIT); 3066 1.97 rpaulo if (opt->ip6po_hbh == NULL) 3067 1.97 rpaulo return (ENOBUFS); 3068 1.97 rpaulo memcpy(opt->ip6po_hbh, hbh, hbhlen); 3069 1.2 itojun 3070 1.97 rpaulo break; 3071 1.97 rpaulo } 3072 1.2 itojun 3073 1.97 rpaulo #ifdef RFC2292 3074 1.97 rpaulo case IPV6_2292DSTOPTS: 3075 1.97 rpaulo #endif 3076 1.97 rpaulo case IPV6_DSTOPTS: 3077 1.97 rpaulo case IPV6_RTHDRDSTOPTS: 3078 1.97 rpaulo { 3079 1.97 rpaulo struct ip6_dest *dest, **newdest = NULL; 3080 1.97 rpaulo int destlen; 3081 1.67 itojun 3082 1.139 elad /* XXX: see the comment for IPV6_HOPOPTS */ 3083 1.229 christos error = kauth_authorize_network(cred, 3084 1.229 christos KAUTH_NETWORK_IPV6, 3085 1.146 elad KAUTH_REQ_NETWORK_IPV6_HOPBYHOP, NULL, NULL, NULL); 3086 1.139 elad if (error) 3087 1.139 elad return (error); 3088 1.2 itojun 3089 1.97 rpaulo if (len == 0) { 3090 1.97 rpaulo ip6_clearpktopts(opt, optname); 3091 1.97 rpaulo break; /* just remove the option */ 3092 1.97 rpaulo } 3093 1.2 itojun 3094 1.97 rpaulo /* message length validation */ 3095 1.97 rpaulo if (len < sizeof(struct ip6_dest)) 3096 1.97 rpaulo return (EINVAL); 3097 1.97 rpaulo dest = (struct ip6_dest *)buf; 3098 1.97 rpaulo destlen = (dest->ip6d_len + 1) << 3; 3099 1.97 rpaulo if (len != destlen) 3100 1.97 rpaulo return (EINVAL); 3101 1.97 rpaulo /* 3102 1.97 rpaulo * Determine the position that the destination options header 3103 1.97 rpaulo * should be inserted; before or after the routing header. 3104 1.97 rpaulo */ 3105 1.97 rpaulo switch (optname) { 3106 1.97 rpaulo case IPV6_2292DSTOPTS: 3107 1.2 itojun /* 3108 1.97 rpaulo * The old advanced API is ambiguous on this point. 3109 1.97 rpaulo * Our approach is to determine the position based 3110 1.97 rpaulo * according to the existence of a routing header. 3111 1.97 rpaulo * Note, however, that this depends on the order of the 3112 1.97 rpaulo * extension headers in the ancillary data; the 1st 3113 1.97 rpaulo * part of the destination options header must appear 3114 1.97 rpaulo * before the routing header in the ancillary data, 3115 1.97 rpaulo * too. 3116 1.97 rpaulo * RFC3542 solved the ambiguity by introducing 3117 1.97 rpaulo * separate ancillary data or option types. 3118 1.2 itojun */ 3119 1.97 rpaulo if (opt->ip6po_rthdr == NULL) 3120 1.97 rpaulo newdest = &opt->ip6po_dest1; 3121 1.97 rpaulo else 3122 1.97 rpaulo newdest = &opt->ip6po_dest2; 3123 1.97 rpaulo break; 3124 1.97 rpaulo case IPV6_RTHDRDSTOPTS: 3125 1.97 rpaulo newdest = &opt->ip6po_dest1; 3126 1.97 rpaulo break; 3127 1.97 rpaulo case IPV6_DSTOPTS: 3128 1.97 rpaulo newdest = &opt->ip6po_dest2; 3129 1.97 rpaulo break; 3130 1.97 rpaulo } 3131 1.97 rpaulo 3132 1.97 rpaulo /* turn off the previous option, then set the new option. */ 3133 1.97 rpaulo ip6_clearpktopts(opt, optname); 3134 1.97 rpaulo *newdest = malloc(destlen, M_IP6OPT, M_NOWAIT); 3135 1.97 rpaulo if (*newdest == NULL) 3136 1.97 rpaulo return (ENOBUFS); 3137 1.97 rpaulo memcpy(*newdest, dest, destlen); 3138 1.67 itojun 3139 1.97 rpaulo break; 3140 1.97 rpaulo } 3141 1.97 rpaulo 3142 1.97 rpaulo #ifdef RFC2292 3143 1.97 rpaulo case IPV6_2292RTHDR: 3144 1.97 rpaulo #endif 3145 1.97 rpaulo case IPV6_RTHDR: 3146 1.97 rpaulo { 3147 1.97 rpaulo struct ip6_rthdr *rth; 3148 1.97 rpaulo int rthlen; 3149 1.97 rpaulo 3150 1.97 rpaulo if (len == 0) { 3151 1.97 rpaulo ip6_clearpktopts(opt, IPV6_RTHDR); 3152 1.97 rpaulo break; /* just remove the option */ 3153 1.97 rpaulo } 3154 1.2 itojun 3155 1.97 rpaulo /* message length validation */ 3156 1.97 rpaulo if (len < sizeof(struct ip6_rthdr)) 3157 1.97 rpaulo return (EINVAL); 3158 1.97 rpaulo rth = (struct ip6_rthdr *)buf; 3159 1.97 rpaulo rthlen = (rth->ip6r_len + 1) << 3; 3160 1.97 rpaulo if (len != rthlen) 3161 1.97 rpaulo return (EINVAL); 3162 1.97 rpaulo switch (rth->ip6r_type) { 3163 1.97 rpaulo case IPV6_RTHDR_TYPE_0: 3164 1.205 maxv /* Dropped, RFC5095. */ 3165 1.2 itojun default: 3166 1.97 rpaulo return (EINVAL); /* not supported */ 3167 1.2 itojun } 3168 1.97 rpaulo /* turn off the previous option */ 3169 1.97 rpaulo ip6_clearpktopts(opt, IPV6_RTHDR); 3170 1.97 rpaulo opt->ip6po_rthdr = malloc(rthlen, M_IP6OPT, M_NOWAIT); 3171 1.97 rpaulo if (opt->ip6po_rthdr == NULL) 3172 1.97 rpaulo return (ENOBUFS); 3173 1.97 rpaulo memcpy(opt->ip6po_rthdr, rth, rthlen); 3174 1.97 rpaulo break; 3175 1.2 itojun } 3176 1.2 itojun 3177 1.97 rpaulo case IPV6_USE_MIN_MTU: 3178 1.97 rpaulo if (len != sizeof(int)) 3179 1.97 rpaulo return (EINVAL); 3180 1.97 rpaulo minmtupolicy = *(int *)buf; 3181 1.97 rpaulo if (minmtupolicy != IP6PO_MINMTU_MCASTONLY && 3182 1.97 rpaulo minmtupolicy != IP6PO_MINMTU_DISABLE && 3183 1.97 rpaulo minmtupolicy != IP6PO_MINMTU_ALL) { 3184 1.97 rpaulo return (EINVAL); 3185 1.97 rpaulo } 3186 1.97 rpaulo opt->ip6po_minmtu = minmtupolicy; 3187 1.97 rpaulo break; 3188 1.97 rpaulo 3189 1.97 rpaulo case IPV6_DONTFRAG: 3190 1.97 rpaulo if (len != sizeof(int)) 3191 1.97 rpaulo return (EINVAL); 3192 1.97 rpaulo 3193 1.97 rpaulo if (uproto == IPPROTO_TCP || *(int *)buf == 0) { 3194 1.97 rpaulo /* 3195 1.97 rpaulo * we ignore this option for TCP sockets. 3196 1.97 rpaulo * (RFC3542 leaves this case unspecified.) 3197 1.97 rpaulo */ 3198 1.97 rpaulo opt->ip6po_flags &= ~IP6PO_DONTFRAG; 3199 1.97 rpaulo } else 3200 1.97 rpaulo opt->ip6po_flags |= IP6PO_DONTFRAG; 3201 1.97 rpaulo break; 3202 1.97 rpaulo 3203 1.161 roy case IPV6_PREFER_TEMPADDR: 3204 1.161 roy { 3205 1.161 roy int preftemp; 3206 1.161 roy 3207 1.161 roy if (len != sizeof(int)) 3208 1.161 roy return (EINVAL); 3209 1.161 roy preftemp = *(int *)buf; 3210 1.161 roy switch (preftemp) { 3211 1.161 roy case IP6PO_TEMPADDR_SYSTEM: 3212 1.161 roy case IP6PO_TEMPADDR_NOTPREFER: 3213 1.161 roy case IP6PO_TEMPADDR_PREFER: 3214 1.161 roy break; 3215 1.161 roy default: 3216 1.161 roy return (EINVAL); 3217 1.161 roy } 3218 1.161 roy opt->ip6po_prefer_tempaddr = preftemp; 3219 1.161 roy break; 3220 1.161 roy } 3221 1.161 roy 3222 1.97 rpaulo default: 3223 1.97 rpaulo return (ENOPROTOOPT); 3224 1.97 rpaulo } /* end of switch */ 3225 1.97 rpaulo 3226 1.57 itojun return (0); 3227 1.2 itojun } 3228 1.2 itojun 3229 1.2 itojun /* 3230 1.2 itojun * Routine called from ip6_output() to loop back a copy of an IP6 multicast 3231 1.2 itojun * packet to the input queue of a specified interface. Note that this 3232 1.2 itojun * calls the output routine of the loopback "driver", but with an interface 3233 1.86 peter * pointer that might NOT be lo0ifp -- easier than replicating that code here. 3234 1.2 itojun */ 3235 1.2 itojun void 3236 1.197 maxv ip6_mloopback(struct ifnet *ifp, struct mbuf *m, 3237 1.119 christos const struct sockaddr_in6 *dst) 3238 1.2 itojun { 3239 1.22 itojun struct mbuf *copym; 3240 1.22 itojun struct ip6_hdr *ip6; 3241 1.2 itojun 3242 1.209 maxv copym = m_copypacket(m, M_DONTWAIT); 3243 1.22 itojun if (copym == NULL) 3244 1.22 itojun return; 3245 1.22 itojun 3246 1.22 itojun /* 3247 1.22 itojun * Make sure to deep-copy IPv6 header portion in case the data 3248 1.22 itojun * is in an mbuf cluster, so that we can safely override the IPv6 3249 1.22 itojun * header portion later. 3250 1.22 itojun */ 3251 1.22 itojun if ((copym->m_flags & M_EXT) != 0 || 3252 1.22 itojun copym->m_len < sizeof(struct ip6_hdr)) { 3253 1.22 itojun copym = m_pullup(copym, sizeof(struct ip6_hdr)); 3254 1.22 itojun if (copym == NULL) 3255 1.22 itojun return; 3256 1.22 itojun } 3257 1.22 itojun 3258 1.22 itojun #ifdef DIAGNOSTIC 3259 1.22 itojun if (copym->m_len < sizeof(*ip6)) { 3260 1.22 itojun m_freem(copym); 3261 1.22 itojun return; 3262 1.22 itojun } 3263 1.22 itojun #endif 3264 1.22 itojun 3265 1.34 itojun ip6 = mtod(copym, struct ip6_hdr *); 3266 1.94 rpaulo /* 3267 1.94 rpaulo * clear embedded scope identifiers if necessary. 3268 1.94 rpaulo * in6_clearscope will touch the addresses only when necessary. 3269 1.94 rpaulo */ 3270 1.94 rpaulo in6_clearscope(&ip6->ip6_src); 3271 1.94 rpaulo in6_clearscope(&ip6->ip6_dst); 3272 1.22 itojun 3273 1.115 dyoung (void)looutput(ifp, copym, (const struct sockaddr *)dst, NULL); 3274 1.2 itojun } 3275 1.2 itojun 3276 1.2 itojun /* 3277 1.2 itojun * Chop IPv6 header off from the payload. 3278 1.2 itojun */ 3279 1.2 itojun static int 3280 1.201 maxv ip6_splithdr(struct mbuf *m, struct ip6_exthdrs *exthdrs) 3281 1.2 itojun { 3282 1.2 itojun struct mbuf *mh; 3283 1.2 itojun struct ip6_hdr *ip6; 3284 1.2 itojun 3285 1.2 itojun ip6 = mtod(m, struct ip6_hdr *); 3286 1.2 itojun if (m->m_len > sizeof(*ip6)) { 3287 1.2 itojun MGETHDR(mh, M_DONTWAIT, MT_HEADER); 3288 1.201 maxv if (mh == NULL) { 3289 1.2 itojun m_freem(m); 3290 1.2 itojun return ENOBUFS; 3291 1.2 itojun } 3292 1.215 maxv m_move_pkthdr(mh, m); 3293 1.216 maxv m_align(mh, sizeof(*ip6)); 3294 1.2 itojun m->m_len -= sizeof(*ip6); 3295 1.2 itojun m->m_data += sizeof(*ip6); 3296 1.2 itojun mh->m_next = m; 3297 1.201 maxv mh->m_len = sizeof(*ip6); 3298 1.201 maxv memcpy(mtod(mh, void *), (void *)ip6, sizeof(*ip6)); 3299 1.2 itojun m = mh; 3300 1.2 itojun } 3301 1.2 itojun exthdrs->ip6e_ip6 = m; 3302 1.2 itojun return 0; 3303 1.2 itojun } 3304 1.2 itojun 3305 1.2 itojun /* 3306 1.2 itojun * Compute IPv6 extension header length. 3307 1.2 itojun */ 3308 1.2 itojun int 3309 1.230 ozaki ip6_optlen(struct inpcb *inp) 3310 1.2 itojun { 3311 1.2 itojun int len; 3312 1.2 itojun 3313 1.231 ozaki if (!in6p_outputopts(inp)) 3314 1.2 itojun return 0; 3315 1.2 itojun 3316 1.2 itojun len = 0; 3317 1.2 itojun #define elen(x) \ 3318 1.2 itojun (((struct ip6_ext *)(x)) ? (((struct ip6_ext *)(x))->ip6e_len + 1) << 3 : 0) 3319 1.2 itojun 3320 1.231 ozaki len += elen(in6p_outputopts(inp)->ip6po_hbh); 3321 1.231 ozaki len += elen(in6p_outputopts(inp)->ip6po_dest1); 3322 1.231 ozaki len += elen(in6p_outputopts(inp)->ip6po_rthdr); 3323 1.231 ozaki len += elen(in6p_outputopts(inp)->ip6po_dest2); 3324 1.2 itojun return len; 3325 1.2 itojun #undef elen 3326 1.2 itojun } 3327 1.174 roy 3328 1.174 roy /* 3329 1.174 roy * Ensure sending address is valid. 3330 1.174 roy * Returns 0 on success, -1 if an error should be sent back or 1 3331 1.174 roy * if the packet could be dropped without error (protocol dependent). 3332 1.174 roy */ 3333 1.174 roy static int 3334 1.194 roy ip6_ifaddrvalid(const struct in6_addr *src, const struct in6_addr *dst) 3335 1.174 roy { 3336 1.174 roy struct sockaddr_in6 sin6; 3337 1.174 roy int s, error; 3338 1.174 roy struct ifaddr *ifa; 3339 1.174 roy struct in6_ifaddr *ia6; 3340 1.174 roy 3341 1.194 roy if (IN6_IS_ADDR_UNSPECIFIED(src)) 3342 1.174 roy return 0; 3343 1.174 roy 3344 1.174 roy memset(&sin6, 0, sizeof(sin6)); 3345 1.174 roy sin6.sin6_family = AF_INET6; 3346 1.174 roy sin6.sin6_len = sizeof(sin6); 3347 1.194 roy sin6.sin6_addr = *src; 3348 1.174 roy 3349 1.174 roy s = pserialize_read_enter(); 3350 1.174 roy ifa = ifa_ifwithaddr(sin6tosa(&sin6)); 3351 1.174 roy if ((ia6 = ifatoia6(ifa)) == NULL || 3352 1.174 roy ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED)) 3353 1.174 roy error = -1; 3354 1.194 roy else if (ia6->ia6_flags & IN6_IFF_TENTATIVE) 3355 1.194 roy error = 1; 3356 1.194 roy else if (ia6->ia6_flags & IN6_IFF_DETACHED && 3357 1.195 kre (sin6.sin6_addr = *dst, ifa_ifwithaddr(sin6tosa(&sin6)) == NULL)) 3358 1.194 roy /* Allow internal traffic to DETACHED addresses */ 3359 1.174 roy error = 1; 3360 1.174 roy else 3361 1.174 roy error = 0; 3362 1.174 roy pserialize_read_exit(s); 3363 1.174 roy 3364 1.174 roy return error; 3365 1.174 roy } 3366