1 1.185 rin /* $NetBSD: raw_ip6.c,v 1.185 2024/07/05 04:31:54 rin Exp $ */ 2 1.34 itojun /* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei 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.24 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.24 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, 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.55 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 * @(#)raw_ip.c 8.2 (Berkeley) 1/4/94 62 1.2 itojun */ 63 1.39 lukem 64 1.39 lukem #include <sys/cdefs.h> 65 1.185 rin __KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.185 2024/07/05 04:31:54 rin Exp $"); 66 1.6 thorpej 67 1.141 pooka #ifdef _KERNEL_OPT 68 1.6 thorpej #include "opt_ipsec.h" 69 1.153 knakahar #include "opt_net_mpsafe.h" 70 1.141 pooka #endif 71 1.2 itojun 72 1.2 itojun #include <sys/param.h> 73 1.69 atatat #include <sys/sysctl.h> 74 1.2 itojun #include <sys/mbuf.h> 75 1.2 itojun #include <sys/socket.h> 76 1.2 itojun #include <sys/protosw.h> 77 1.2 itojun #include <sys/socketvar.h> 78 1.2 itojun #include <sys/systm.h> 79 1.2 itojun #include <sys/proc.h> 80 1.77 elad #include <sys/kauth.h> 81 1.116 rmind #include <sys/kmem.h> 82 1.2 itojun 83 1.2 itojun #include <net/if.h> 84 1.2 itojun #include <net/if_types.h> 85 1.97 thorpej #include <net/net_stats.h> 86 1.2 itojun 87 1.2 itojun #include <netinet/in.h> 88 1.2 itojun #include <netinet/in_var.h> 89 1.19 itojun #include <netinet/ip6.h> 90 1.2 itojun #include <netinet6/ip6_var.h> 91 1.94 thorpej #include <netinet6/ip6_private.h> 92 1.2 itojun #include <netinet6/ip6_mroute.h> 93 1.19 itojun #include <netinet/icmp6.h> 94 1.94 thorpej #include <netinet6/icmp6_private.h> 95 1.2 itojun #include <netinet6/in6_pcb.h> 96 1.20 itojun #include <netinet6/ip6protosw.h> 97 1.24 itojun #include <netinet6/scope6_var.h> 98 1.37 itojun #include <netinet6/raw_ip6.h> 99 1.2 itojun 100 1.111 christos #ifdef IPSEC 101 1.81 degroote #include <netipsec/ipsec.h> 102 1.81 degroote #include <netipsec/ipsec6.h> 103 1.81 degroote #endif 104 1.81 degroote 105 1.2 itojun #include "faith.h" 106 1.32 itojun #if defined(NFAITH) && 0 < NFAITH 107 1.32 itojun #include <net/if_faith.h> 108 1.32 itojun #endif 109 1.2 itojun 110 1.59 itojun extern struct inpcbtable rawcbtable; 111 1.59 itojun struct inpcbtable raw6cbtable; 112 1.2 itojun #define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) 113 1.2 itojun 114 1.2 itojun /* 115 1.2 itojun * Raw interface to IP6 protocol. 116 1.2 itojun */ 117 1.2 itojun 118 1.95 thorpej static percpu_t *rip6stat_percpu; 119 1.95 thorpej 120 1.97 thorpej #define RIP6_STATINC(x) _NET_STATINC(rip6stat_percpu, x) 121 1.37 itojun 122 1.105 pooka static void sysctl_net_inet6_raw6_setup(struct sysctllog **); 123 1.105 pooka 124 1.2 itojun /* 125 1.2 itojun * Initialize raw connection block queue. 126 1.2 itojun */ 127 1.2 itojun void 128 1.103 cegger rip6_init(void) 129 1.2 itojun { 130 1.47 itojun 131 1.105 pooka sysctl_net_inet6_raw6_setup(NULL); 132 1.182 ozaki in6pcb_init(&raw6cbtable, 1, 1); 133 1.95 thorpej 134 1.95 thorpej rip6stat_percpu = percpu_alloc(sizeof(uint64_t) * RIP6_NSTATS); 135 1.2 itojun } 136 1.2 itojun 137 1.172 maxv static void 138 1.179 ozaki rip6_sbappendaddr(struct inpcb *last, struct ip6_hdr *ip6, 139 1.172 maxv const struct sockaddr *sa, int hlen, struct mbuf *n) 140 1.172 maxv { 141 1.172 maxv struct mbuf *opts = NULL; 142 1.172 maxv 143 1.184 mlelstv if (last->inp_flags & IN6P_CONTROLOPTS || 144 1.184 mlelstv SOOPT_TIMESTAMP(last->inp_socket->so_options)) 145 1.172 maxv ip6_savecontrol(last, &opts, ip6, n); 146 1.172 maxv 147 1.172 maxv m_adj(n, hlen); 148 1.172 maxv 149 1.179 ozaki if (sbappendaddr(&last->inp_socket->so_rcv, sa, n, opts) == 0) { 150 1.179 ozaki soroverflow(last->inp_socket); 151 1.172 maxv m_freem(n); 152 1.185 rin m_freem(opts); 153 1.172 maxv RIP6_STATINC(RIP6_STAT_FULLSOCK); 154 1.172 maxv } else { 155 1.179 ozaki sorwakeup(last->inp_socket); 156 1.172 maxv } 157 1.172 maxv } 158 1.172 maxv 159 1.2 itojun /* 160 1.2 itojun * Setup generic address and protocol structures 161 1.2 itojun * for raw_input routine, then pass them along with 162 1.2 itojun * mbuf chain. 163 1.2 itojun */ 164 1.2 itojun int 165 1.85 christos rip6_input(struct mbuf **mp, int *offp, int proto) 166 1.2 itojun { 167 1.2 itojun struct mbuf *m = *mp; 168 1.27 itojun struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 169 1.179 ozaki struct inpcb *inp; 170 1.179 ozaki struct inpcb *last = NULL; 171 1.2 itojun struct sockaddr_in6 rip6src; 172 1.172 maxv struct mbuf *n; 173 1.2 itojun 174 1.95 thorpej RIP6_STATINC(RIP6_STAT_IPACKETS); 175 1.37 itojun 176 1.2 itojun #if defined(NFAITH) && 0 < NFAITH 177 1.32 itojun if (faithprefix(&ip6->ip6_dst)) { 178 1.32 itojun /* send icmp6 host unreach? */ 179 1.32 itojun m_freem(m); 180 1.32 itojun return IPPROTO_DONE; 181 1.2 itojun } 182 1.2 itojun #endif 183 1.14 itojun 184 1.89 dyoung sockaddr_in6_init(&rip6src, &ip6->ip6_src, 0, 0, 0); 185 1.75 rpaulo if (sa6_recoverscope(&rip6src) != 0) { 186 1.75 rpaulo /* XXX: should be impossible. */ 187 1.75 rpaulo m_freem(m); 188 1.75 rpaulo return IPPROTO_DONE; 189 1.75 rpaulo } 190 1.2 itojun 191 1.179 ozaki TAILQ_FOREACH(inp, &raw6cbtable.inpt_queue, inp_queue) { 192 1.179 ozaki if (inp->inp_af != AF_INET6) 193 1.59 itojun continue; 194 1.180 ozaki if (in6p_ip6(inp).ip6_nxt && 195 1.180 ozaki in6p_ip6(inp).ip6_nxt != proto) 196 1.2 itojun continue; 197 1.180 ozaki if (!IN6_IS_ADDR_UNSPECIFIED(&in6p_laddr(inp)) && 198 1.180 ozaki !IN6_ARE_ADDR_EQUAL(&in6p_laddr(inp), &ip6->ip6_dst)) 199 1.2 itojun continue; 200 1.180 ozaki if (!IN6_IS_ADDR_UNSPECIFIED(&in6p_faddr(inp)) && 201 1.180 ozaki !IN6_ARE_ADDR_EQUAL(&in6p_faddr(inp), &ip6->ip6_src)) 202 1.2 itojun continue; 203 1.180 ozaki if (in6p_cksum(inp) != -1) { 204 1.95 thorpej RIP6_STATINC(RIP6_STAT_ISUM); 205 1.183 ozaki /* 206 1.183 ozaki * Although in6_cksum() does not need the position of 207 1.183 ozaki * the checksum field for verification, enforce that it 208 1.183 ozaki * is located within the packet. Userland has given 209 1.183 ozaki * a checksum offset, a packet too short for that is 210 1.183 ozaki * invalid. Avoid overflow with user supplied offset. 211 1.183 ozaki */ 212 1.183 ozaki if (m->m_pkthdr.len < *offp + 2 || 213 1.183 ozaki m->m_pkthdr.len - *offp - 2 < in6p_cksum(inp) || 214 1.183 ozaki in6_cksum(m, proto, *offp, 215 1.37 itojun m->m_pkthdr.len - *offp)) { 216 1.95 thorpej RIP6_STATINC(RIP6_STAT_BADSUM); 217 1.37 itojun continue; 218 1.37 itojun } 219 1.2 itojun } 220 1.30 itojun 221 1.168 maxv if (last == NULL) { 222 1.168 maxv ; 223 1.168 maxv } 224 1.111 christos #ifdef IPSEC 225 1.168 maxv else if (ipsec_used && ipsec_in_reject(m, last)) { 226 1.168 maxv /* do not inject data into pcb */ 227 1.168 maxv } 228 1.159 maxv #endif 229 1.171 maxv else if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) { 230 1.172 maxv rip6_sbappendaddr(last, ip6, sin6tosa(&rip6src), 231 1.172 maxv *offp, n); 232 1.2 itojun } 233 1.168 maxv 234 1.179 ozaki last = inp; 235 1.2 itojun } 236 1.159 maxv 237 1.111 christos #ifdef IPSEC 238 1.163 maxv if (ipsec_used && last && ipsec_in_reject(m, last)) { 239 1.81 degroote m_freem(m); 240 1.159 maxv IP6_STATDEC(IP6_STAT_DELIVERED); 241 1.159 maxv /* do not inject data into pcb */ 242 1.159 maxv } else 243 1.159 maxv #endif 244 1.172 maxv if (last != NULL) { 245 1.172 maxv rip6_sbappendaddr(last, ip6, sin6tosa(&rip6src), *offp, m); 246 1.2 itojun } else { 247 1.95 thorpej RIP6_STATINC(RIP6_STAT_NOSOCK); 248 1.37 itojun if (m->m_flags & M_MCAST) 249 1.95 thorpej RIP6_STATINC(RIP6_STAT_NOSOCKMCAST); 250 1.2 itojun if (proto == IPPROTO_NONE) 251 1.2 itojun m_freem(m); 252 1.2 itojun else { 253 1.144 ozaki int s; 254 1.144 ozaki struct ifnet *rcvif = m_get_rcvif(m, &s); 255 1.160 maxv const int prvnxt = ip6_get_prevhdr(m, *offp); 256 1.144 ozaki in6_ifstat_inc(rcvif, ifs6_in_protounknown); 257 1.144 ozaki m_put_rcvif(rcvif, &s); 258 1.2 itojun icmp6_error(m, ICMP6_PARAM_PROB, 259 1.43 itojun ICMP6_PARAMPROB_NEXTHEADER, 260 1.160 maxv prvnxt); 261 1.2 itojun } 262 1.94 thorpej IP6_STATDEC(IP6_STAT_DELIVERED); 263 1.2 itojun } 264 1.2 itojun return IPPROTO_DONE; 265 1.2 itojun } 266 1.2 itojun 267 1.98 ad void * 268 1.82 dyoung rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d) 269 1.20 itojun { 270 1.27 itojun struct ip6_hdr *ip6; 271 1.29 itojun struct ip6ctlparam *ip6cp = NULL; 272 1.29 itojun const struct sockaddr_in6 *sa6_src = NULL; 273 1.29 itojun void *cmdarg; 274 1.182 ozaki void (*notify)(struct inpcb *, int) = in6pcb_rtchange; 275 1.29 itojun int nxt; 276 1.20 itojun 277 1.20 itojun if (sa->sa_family != AF_INET6 || 278 1.20 itojun sa->sa_len != sizeof(struct sockaddr_in6)) 279 1.102 yamt return NULL; 280 1.20 itojun 281 1.21 itojun if ((unsigned)cmd >= PRC_NCMDS) 282 1.102 yamt return NULL; 283 1.21 itojun if (PRC_IS_REDIRECT(cmd)) 284 1.182 ozaki notify = in6pcb_rtchange, d = NULL; 285 1.21 itojun else if (cmd == PRC_HOSTDEAD) 286 1.21 itojun d = NULL; 287 1.29 itojun else if (cmd == PRC_MSGSIZE) 288 1.29 itojun ; /* special code is present, see below */ 289 1.21 itojun else if (inet6ctlerrmap[cmd] == 0) 290 1.102 yamt return NULL; 291 1.20 itojun 292 1.20 itojun /* if the parameter is from icmp6, decode it. */ 293 1.20 itojun if (d != NULL) { 294 1.29 itojun ip6cp = (struct ip6ctlparam *)d; 295 1.20 itojun ip6 = ip6cp->ip6c_ip6; 296 1.29 itojun cmdarg = ip6cp->ip6c_cmdarg; 297 1.29 itojun sa6_src = ip6cp->ip6c_src; 298 1.29 itojun nxt = ip6cp->ip6c_nxt; 299 1.20 itojun } else { 300 1.20 itojun ip6 = NULL; 301 1.29 itojun cmdarg = NULL; 302 1.29 itojun sa6_src = &sa6_any; 303 1.29 itojun nxt = -1; 304 1.20 itojun } 305 1.20 itojun 306 1.29 itojun if (ip6 && cmd == PRC_MSGSIZE) { 307 1.82 dyoung const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *)sa; 308 1.29 itojun int valid = 0; 309 1.179 ozaki struct inpcb *inp; 310 1.20 itojun 311 1.20 itojun /* 312 1.29 itojun * Check to see if we have a valid raw IPv6 socket 313 1.29 itojun * corresponding to the address in the ICMPv6 message 314 1.29 itojun * payload, and the protocol (ip6_nxt) meets the socket. 315 1.29 itojun * XXX chase extension headers, or pass final nxt value 316 1.29 itojun * from icmp6_notify_error() 317 1.20 itojun */ 318 1.179 ozaki inp = NULL; 319 1.182 ozaki inp = in6pcb_lookup(&raw6cbtable, &sa6->sin6_addr, 0, 320 1.108 dyoung (const struct in6_addr *)&sa6_src->sin6_addr, 0, 0, 0); 321 1.29 itojun #if 0 322 1.179 ozaki if (!inp) { 323 1.29 itojun /* 324 1.29 itojun * As the use of sendto(2) is fairly popular, 325 1.29 itojun * we may want to allow non-connected pcb too. 326 1.29 itojun * But it could be too weak against attacks... 327 1.29 itojun * We should at least check if the local 328 1.29 itojun * address (= s) is really ours. 329 1.29 itojun */ 330 1.182 ozaki inp = in6pcb_lookup_bound(&raw6cbtable, 331 1.75 rpaulo &sa6->sin6_addr, 0, 0); 332 1.29 itojun } 333 1.29 itojun #endif 334 1.29 itojun 335 1.180 ozaki if (inp && in6p_ip6(inp).ip6_nxt && 336 1.180 ozaki in6p_ip6(inp).ip6_nxt == nxt) 337 1.29 itojun valid++; 338 1.20 itojun 339 1.29 itojun /* 340 1.29 itojun * Depending on the value of "valid" and routing table 341 1.29 itojun * size (mtudisc_{hi,lo}wat), we will: 342 1.44 itojun * - recalculate the new MTU and create the 343 1.29 itojun * corresponding routing entry, or 344 1.29 itojun * - ignore the MTU change notification. 345 1.29 itojun */ 346 1.29 itojun icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); 347 1.20 itojun 348 1.29 itojun /* 349 1.29 itojun * regardless of if we called icmp6_mtudisc_update(), 350 1.182 ozaki * we need to call in6pcb_notify(), to notify path MTU 351 1.76 rpaulo * change to the userland (RFC3542), because some 352 1.76 rpaulo * unconnected sockets may share the same destination 353 1.76 rpaulo * and want to know the path MTU. 354 1.29 itojun */ 355 1.20 itojun } 356 1.29 itojun 357 1.182 ozaki (void) in6pcb_notify(&raw6cbtable, sa, 0, 358 1.148 ozaki sin6tocsa(sa6_src), 0, cmd, cmdarg, notify); 359 1.98 ad return NULL; 360 1.20 itojun } 361 1.20 itojun 362 1.2 itojun /* 363 1.2 itojun * Generate IPv6 header and pass packet to ip6_output. 364 1.2 itojun * Tack on options user may have setup with control call. 365 1.2 itojun */ 366 1.2 itojun int 367 1.106 dyoung rip6_output(struct mbuf *m, struct socket * const so, 368 1.106 dyoung struct sockaddr_in6 * const dstsock, struct mbuf * const control) 369 1.2 itojun { 370 1.2 itojun struct in6_addr *dst; 371 1.2 itojun struct ip6_hdr *ip6; 372 1.179 ozaki struct inpcb *inp; 373 1.2 itojun u_int plen = m->m_pkthdr.len; 374 1.2 itojun int error = 0; 375 1.75 rpaulo struct ip6_pktopts opt, *optp = NULL; 376 1.2 itojun struct ifnet *oifp = NULL; 377 1.12 itojun int type, code; /* for ICMPv6 output statistics only */ 378 1.75 rpaulo int scope_ambiguous = 0; 379 1.145 ozaki int bound = curlwp_bind(); 380 1.146 ozaki struct psref psref; 381 1.2 itojun 382 1.179 ozaki inp = sotoinpcb(so); 383 1.2 itojun 384 1.2 itojun dst = &dstsock->sin6_addr; 385 1.2 itojun if (control) { 386 1.76 rpaulo if ((error = ip6_setpktopts(control, &opt, 387 1.180 ozaki in6p_outputopts(inp), 388 1.104 elad kauth_cred_get(), so->so_proto->pr_protocol)) != 0) { 389 1.2 itojun goto bad; 390 1.76 rpaulo } 391 1.2 itojun optp = &opt; 392 1.2 itojun } else 393 1.180 ozaki optp = in6p_outputopts(inp); 394 1.2 itojun 395 1.12 itojun /* 396 1.75 rpaulo * Check and convert scope zone ID into internal form. 397 1.75 rpaulo * XXX: we may still need to determine the zone later. 398 1.75 rpaulo */ 399 1.75 rpaulo if (!(so->so_state & SS_ISCONNECTED)) { 400 1.75 rpaulo if (dstsock->sin6_scope_id == 0 && !ip6_use_defzone) 401 1.75 rpaulo scope_ambiguous = 1; 402 1.75 rpaulo if ((error = sa6_embedscope(dstsock, ip6_use_defzone)) != 0) 403 1.75 rpaulo goto bad; 404 1.75 rpaulo } 405 1.75 rpaulo 406 1.75 rpaulo /* 407 1.12 itojun * For an ICMPv6 packet, we should know its type and code 408 1.12 itojun * to update statistics. 409 1.12 itojun */ 410 1.12 itojun if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { 411 1.12 itojun struct icmp6_hdr *icmp6; 412 1.12 itojun if (m->m_len < sizeof(struct icmp6_hdr) && 413 1.12 itojun (m = m_pullup(m, sizeof(struct icmp6_hdr))) == NULL) { 414 1.12 itojun error = ENOBUFS; 415 1.12 itojun goto bad; 416 1.12 itojun } 417 1.12 itojun icmp6 = mtod(m, struct icmp6_hdr *); 418 1.12 itojun type = icmp6->icmp6_type; 419 1.12 itojun code = icmp6->icmp6_code; 420 1.62 christos } else { 421 1.62 christos type = 0; 422 1.62 christos code = 0; 423 1.12 itojun } 424 1.12 itojun 425 1.52 itojun M_PREPEND(m, sizeof(*ip6), M_DONTWAIT); 426 1.52 itojun if (!m) { 427 1.52 itojun error = ENOBUFS; 428 1.52 itojun goto bad; 429 1.52 itojun } 430 1.2 itojun ip6 = mtod(m, struct ip6_hdr *); 431 1.2 itojun 432 1.2 itojun /* 433 1.2 itojun * Next header might not be ICMP6 but use its pseudo header anyway. 434 1.2 itojun */ 435 1.2 itojun ip6->ip6_dst = *dst; 436 1.2 itojun 437 1.12 itojun /* 438 1.12 itojun * Source address selection. 439 1.12 itojun */ 440 1.180 ozaki error = in6_selectsrc(dstsock, optp, in6p_moptions(inp), 441 1.180 ozaki &inp->inp_route, &in6p_laddr(inp), &oifp, &psref, &ip6->ip6_src); 442 1.152 ozaki if (error != 0) 443 1.75 rpaulo goto bad; 444 1.2 itojun 445 1.75 rpaulo if (oifp && scope_ambiguous) { 446 1.75 rpaulo /* 447 1.75 rpaulo * Application should provide a proper zone ID or the use of 448 1.75 rpaulo * default zone IDs should be enabled. Unfortunately, some 449 1.75 rpaulo * applications do not behave as it should, so we need a 450 1.75 rpaulo * workaround. Even if an appropriate ID is not determined 451 1.75 rpaulo * (when it's required), if we can determine the outgoing 452 1.75 rpaulo * interface. determine the zone ID based on the interface. 453 1.75 rpaulo */ 454 1.75 rpaulo error = in6_setscope(&dstsock->sin6_addr, oifp, NULL); 455 1.75 rpaulo if (error != 0) 456 1.2 itojun goto bad; 457 1.12 itojun } 458 1.75 rpaulo ip6->ip6_dst = dstsock->sin6_addr; 459 1.2 itojun 460 1.75 rpaulo /* fill in the rest of the IPv6 header fields */ 461 1.180 ozaki ip6->ip6_flow = in6p_flowinfo(inp) & IPV6_FLOWINFO_MASK; 462 1.20 itojun ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 463 1.20 itojun ip6->ip6_vfc |= IPV6_VERSION; 464 1.75 rpaulo /* ip6_plen will be filled in ip6_output, so not fill it here. */ 465 1.180 ozaki ip6->ip6_nxt = in6p_ip6(inp).ip6_nxt; 466 1.182 ozaki ip6->ip6_hlim = in6pcb_selecthlim(inp, oifp); 467 1.2 itojun 468 1.146 ozaki if_put(oifp, &psref); 469 1.146 ozaki oifp = NULL; 470 1.146 ozaki 471 1.2 itojun if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 || 472 1.180 ozaki in6p_cksum(inp) != -1) { 473 1.161 maxv const uint8_t nxt = ip6->ip6_nxt; 474 1.2 itojun int off; 475 1.67 yamt u_int16_t sum; 476 1.2 itojun 477 1.2 itojun /* compute checksum */ 478 1.2 itojun if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) 479 1.2 itojun off = offsetof(struct icmp6_hdr, icmp6_cksum); 480 1.2 itojun else 481 1.180 ozaki off = in6p_cksum(inp); 482 1.183 ozaki if (plen < 2 || plen - 2 < off) { 483 1.2 itojun error = EINVAL; 484 1.2 itojun goto bad; 485 1.2 itojun } 486 1.2 itojun off += sizeof(struct ip6_hdr); 487 1.2 itojun 488 1.68 yamt sum = 0; 489 1.84 christos m = m_copyback_cow(m, off, sizeof(sum), (void *)&sum, 490 1.68 yamt M_DONTWAIT); 491 1.68 yamt if (m == NULL) { 492 1.66 yamt error = ENOBUFS; 493 1.66 yamt goto bad; 494 1.66 yamt } 495 1.161 maxv sum = in6_cksum(m, nxt, sizeof(*ip6), plen); 496 1.84 christos m = m_copyback_cow(m, off, sizeof(sum), (void *)&sum, 497 1.68 yamt M_DONTWAIT); 498 1.68 yamt if (m == NULL) { 499 1.68 yamt error = ENOBUFS; 500 1.68 yamt goto bad; 501 1.68 yamt } 502 1.2 itojun } 503 1.27 itojun 504 1.144 ozaki { 505 1.144 ozaki struct ifnet *ret_oifp = NULL; 506 1.144 ozaki 507 1.179 ozaki error = ip6_output(m, optp, &inp->inp_route, 0, 508 1.180 ozaki in6p_moptions(inp), inp, &ret_oifp); 509 1.144 ozaki if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { 510 1.144 ozaki if (ret_oifp) 511 1.144 ozaki icmp6_ifoutstat_inc(ret_oifp, type, code); 512 1.144 ozaki ICMP6_STATINC(ICMP6_STAT_OUTHIST + type); 513 1.144 ozaki } else 514 1.144 ozaki RIP6_STATINC(RIP6_STAT_OPACKETS); 515 1.144 ozaki } 516 1.2 itojun 517 1.2 itojun goto freectl; 518 1.2 itojun 519 1.2 itojun bad: 520 1.185 rin m_freem(m); 521 1.2 itojun 522 1.2 itojun freectl: 523 1.76 rpaulo if (control) { 524 1.76 rpaulo ip6_clearpktopts(&opt, -1); 525 1.2 itojun m_freem(control); 526 1.76 rpaulo } 527 1.146 ozaki if_put(oifp, &psref); 528 1.145 ozaki curlwp_bindx(bound); 529 1.83 dyoung return error; 530 1.2 itojun } 531 1.2 itojun 532 1.40 itojun /* 533 1.2 itojun * Raw IPv6 socket option processing. 534 1.40 itojun */ 535 1.2 itojun int 536 1.100 plunky rip6_ctloutput(int op, struct socket *so, struct sockopt *sopt) 537 1.2 itojun { 538 1.2 itojun int error = 0; 539 1.2 itojun 540 1.100 plunky if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) { 541 1.100 plunky int optval; 542 1.100 plunky 543 1.87 dyoung /* need to fiddle w/ opt(IPPROTO_IPV6, IPV6_CHECKSUM)? */ 544 1.90 dyoung if (op == PRCO_GETOPT) { 545 1.100 plunky optval = 1; 546 1.100 plunky error = sockopt_set(sopt, &optval, sizeof(optval)); 547 1.100 plunky } else if (op == PRCO_SETOPT) { 548 1.100 plunky error = sockopt_getint(sopt, &optval); 549 1.100 plunky if (error) 550 1.100 plunky goto out; 551 1.100 plunky if (optval == 0) 552 1.100 plunky error = EINVAL; 553 1.100 plunky } 554 1.100 plunky 555 1.100 plunky goto out; 556 1.100 plunky } else if (sopt->sopt_level != IPPROTO_IPV6) 557 1.100 plunky return ip6_ctloutput(op, so, sopt); 558 1.87 dyoung 559 1.100 plunky switch (sopt->sopt_name) { 560 1.87 dyoung case MRT6_INIT: 561 1.87 dyoung case MRT6_DONE: 562 1.87 dyoung case MRT6_ADD_MIF: 563 1.87 dyoung case MRT6_DEL_MIF: 564 1.87 dyoung case MRT6_ADD_MFC: 565 1.87 dyoung case MRT6_DEL_MFC: 566 1.87 dyoung case MRT6_PIM: 567 1.87 dyoung if (op == PRCO_SETOPT) 568 1.100 plunky error = ip6_mrouter_set(so, sopt); 569 1.87 dyoung else if (op == PRCO_GETOPT) 570 1.100 plunky error = ip6_mrouter_get(so, sopt); 571 1.87 dyoung else 572 1.87 dyoung error = EINVAL; 573 1.87 dyoung break; 574 1.87 dyoung case IPV6_CHECKSUM: 575 1.100 plunky return ip6_raw_ctloutput(op, so, sopt); 576 1.27 itojun default: 577 1.100 plunky return ip6_ctloutput(op, so, sopt); 578 1.2 itojun } 579 1.100 plunky out: 580 1.87 dyoung return error; 581 1.2 itojun } 582 1.2 itojun 583 1.2 itojun extern u_long rip6_sendspace; 584 1.2 itojun extern u_long rip6_recvspace; 585 1.2 itojun 586 1.2 itojun int 587 1.116 rmind rip6_attach(struct socket *so, int proto) 588 1.116 rmind { 589 1.179 ozaki struct inpcb *inp; 590 1.116 rmind int s, error; 591 1.116 rmind 592 1.179 ozaki KASSERT(sotoinpcb(so) == NULL); 593 1.116 rmind sosetlock(so); 594 1.116 rmind 595 1.176 christos error = kauth_authorize_network(kauth_cred_get(), 596 1.116 rmind KAUTH_NETWORK_SOCKET, KAUTH_REQ_NETWORK_SOCKET_RAWSOCK, 597 1.116 rmind KAUTH_ARG(AF_INET6), 598 1.116 rmind KAUTH_ARG(SOCK_RAW), 599 1.116 rmind KAUTH_ARG(so->so_proto->pr_protocol)); 600 1.116 rmind if (error) { 601 1.116 rmind return error; 602 1.116 rmind } 603 1.116 rmind s = splsoftnet(); 604 1.116 rmind error = soreserve(so, rip6_sendspace, rip6_recvspace); 605 1.116 rmind if (error) { 606 1.116 rmind splx(s); 607 1.116 rmind return error; 608 1.116 rmind } 609 1.181 ozaki if ((error = inpcb_create(so, &raw6cbtable)) != 0) { 610 1.116 rmind splx(s); 611 1.116 rmind return error; 612 1.116 rmind } 613 1.116 rmind splx(s); 614 1.179 ozaki inp = sotoinpcb(so); 615 1.180 ozaki in6p_ip6(inp).ip6_nxt = proto; 616 1.180 ozaki in6p_cksum(inp) = -1; 617 1.116 rmind 618 1.180 ozaki in6p_icmp6filt(inp) = kmem_alloc(sizeof(struct icmp6_filter), KM_SLEEP); 619 1.180 ozaki ICMP6_FILTER_SETPASSALL(in6p_icmp6filt(inp)); 620 1.116 rmind KASSERT(solocked(so)); 621 1.116 rmind return error; 622 1.116 rmind } 623 1.116 rmind 624 1.116 rmind static void 625 1.116 rmind rip6_detach(struct socket *so) 626 1.116 rmind { 627 1.179 ozaki struct inpcb *inp = sotoinpcb(so); 628 1.116 rmind 629 1.116 rmind KASSERT(solocked(so)); 630 1.179 ozaki KASSERT(inp != NULL); 631 1.116 rmind 632 1.116 rmind if (so == ip6_mrouter) { 633 1.116 rmind ip6_mrouter_done(); 634 1.116 rmind } 635 1.116 rmind /* xxx: RSVP */ 636 1.180 ozaki if (in6p_icmp6filt(inp) != NULL) { 637 1.180 ozaki kmem_free(in6p_icmp6filt(inp), sizeof(struct icmp6_filter)); 638 1.180 ozaki in6p_icmp6filt(inp) = NULL; 639 1.116 rmind } 640 1.181 ozaki inpcb_destroy(inp); 641 1.116 rmind } 642 1.116 rmind 643 1.119 rtr static int 644 1.138 rtr rip6_accept(struct socket *so, struct sockaddr *nam) 645 1.127 rtr { 646 1.127 rtr KASSERT(solocked(so)); 647 1.127 rtr 648 1.127 rtr return EOPNOTSUPP; 649 1.127 rtr } 650 1.127 rtr 651 1.127 rtr static int 652 1.137 rtr rip6_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 653 1.129 rtr { 654 1.179 ozaki struct inpcb *inp = sotoinpcb(so); 655 1.137 rtr struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; 656 1.149 ozaki struct ifaddr *ifa = NULL; 657 1.129 rtr int error = 0; 658 1.149 ozaki int s; 659 1.129 rtr 660 1.129 rtr KASSERT(solocked(so)); 661 1.179 ozaki KASSERT(inp != NULL); 662 1.129 rtr KASSERT(nam != NULL); 663 1.129 rtr 664 1.137 rtr if (addr->sin6_len != sizeof(*addr)) 665 1.129 rtr return EINVAL; 666 1.143 ozaki if (IFNET_READER_EMPTY() || addr->sin6_family != AF_INET6) 667 1.129 rtr return EADDRNOTAVAIL; 668 1.129 rtr 669 1.129 rtr if ((error = sa6_embedscope(addr, ip6_use_defzone)) != 0) 670 1.129 rtr return error; 671 1.129 rtr 672 1.129 rtr /* 673 1.129 rtr * we don't support mapped address here, it would confuse 674 1.129 rtr * users so reject it 675 1.129 rtr */ 676 1.129 rtr if (IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) 677 1.129 rtr return EADDRNOTAVAIL; 678 1.149 ozaki s = pserialize_read_enter(); 679 1.129 rtr if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && 680 1.149 ozaki (ifa = ifa_ifwithaddr(sin6tosa(addr))) == NULL) { 681 1.149 ozaki error = EADDRNOTAVAIL; 682 1.149 ozaki goto out; 683 1.149 ozaki } 684 1.149 ozaki if (ifa && (ifatoia6(ifa))->ia6_flags & 685 1.151 roy (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED)) { 686 1.149 ozaki error = EADDRNOTAVAIL; 687 1.149 ozaki goto out; 688 1.149 ozaki } 689 1.149 ozaki 690 1.180 ozaki in6p_laddr(inp) = addr->sin6_addr; 691 1.149 ozaki error = 0; 692 1.149 ozaki out: 693 1.149 ozaki pserialize_read_exit(s); 694 1.149 ozaki return error; 695 1.129 rtr } 696 1.129 rtr 697 1.129 rtr static int 698 1.133 rtr rip6_listen(struct socket *so, struct lwp *l) 699 1.129 rtr { 700 1.129 rtr KASSERT(solocked(so)); 701 1.129 rtr 702 1.129 rtr return EOPNOTSUPP; 703 1.129 rtr } 704 1.129 rtr 705 1.129 rtr static int 706 1.140 rtr rip6_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 707 1.130 rtr { 708 1.179 ozaki struct inpcb *inp = sotoinpcb(so); 709 1.140 rtr struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam; 710 1.152 ozaki struct in6_addr in6a; 711 1.130 rtr struct ifnet *ifp = NULL; 712 1.130 rtr int scope_ambiguous = 0; 713 1.130 rtr int error = 0; 714 1.146 ozaki struct psref psref; 715 1.146 ozaki int bound; 716 1.130 rtr 717 1.130 rtr KASSERT(solocked(so)); 718 1.179 ozaki KASSERT(inp != NULL); 719 1.130 rtr KASSERT(nam != NULL); 720 1.130 rtr 721 1.143 ozaki if (IFNET_READER_EMPTY()) 722 1.130 rtr return EADDRNOTAVAIL; 723 1.130 rtr if (addr->sin6_family != AF_INET6) 724 1.130 rtr return EAFNOSUPPORT; 725 1.174 maxv if (addr->sin6_len != sizeof(*addr)) 726 1.174 maxv return EINVAL; 727 1.130 rtr 728 1.130 rtr /* 729 1.130 rtr * Application should provide a proper zone ID or the use of 730 1.130 rtr * default zone IDs should be enabled. Unfortunately, some 731 1.130 rtr * applications do not behave as it should, so we need a 732 1.130 rtr * workaround. Even if an appropriate ID is not determined, 733 1.130 rtr * we'll see if we can determine the outgoing interface. If we 734 1.130 rtr * can, determine the zone ID based on the interface below. 735 1.130 rtr */ 736 1.130 rtr if (addr->sin6_scope_id == 0 && !ip6_use_defzone) 737 1.130 rtr scope_ambiguous = 1; 738 1.130 rtr if ((error = sa6_embedscope(addr, ip6_use_defzone)) != 0) 739 1.130 rtr return error; 740 1.130 rtr 741 1.146 ozaki bound = curlwp_bind(); 742 1.130 rtr /* Source address selection. XXX: need pcblookup? */ 743 1.180 ozaki error = in6_selectsrc(addr, in6p_outputopts(inp), 744 1.180 ozaki in6p_moptions(inp), &inp->inp_route, 745 1.180 ozaki &in6p_laddr(inp), &ifp, &psref, &in6a); 746 1.152 ozaki if (error != 0) 747 1.144 ozaki goto out; 748 1.130 rtr /* XXX: see above */ 749 1.130 rtr if (ifp && scope_ambiguous && 750 1.130 rtr (error = in6_setscope(&addr->sin6_addr, ifp, NULL)) != 0) { 751 1.144 ozaki goto out; 752 1.130 rtr } 753 1.180 ozaki in6p_laddr(inp) = in6a; 754 1.180 ozaki in6p_faddr(inp) = addr->sin6_addr; 755 1.130 rtr soisconnected(so); 756 1.144 ozaki out: 757 1.146 ozaki if_put(ifp, &psref); 758 1.146 ozaki curlwp_bindx(bound); 759 1.130 rtr return error; 760 1.130 rtr } 761 1.130 rtr 762 1.130 rtr static int 763 1.136 rtr rip6_connect2(struct socket *so, struct socket *so2) 764 1.136 rtr { 765 1.136 rtr KASSERT(solocked(so)); 766 1.136 rtr 767 1.136 rtr return EOPNOTSUPP; 768 1.136 rtr } 769 1.136 rtr 770 1.136 rtr static int 771 1.132 rtr rip6_disconnect(struct socket *so) 772 1.132 rtr { 773 1.179 ozaki struct inpcb *inp = sotoinpcb(so); 774 1.132 rtr 775 1.132 rtr KASSERT(solocked(so)); 776 1.179 ozaki KASSERT(inp != NULL); 777 1.132 rtr 778 1.132 rtr if ((so->so_state & SS_ISCONNECTED) == 0) 779 1.132 rtr return ENOTCONN; 780 1.132 rtr 781 1.180 ozaki in6p_faddr(inp) = in6addr_any; 782 1.132 rtr so->so_state &= ~SS_ISCONNECTED; /* XXX */ 783 1.132 rtr return 0; 784 1.132 rtr } 785 1.132 rtr 786 1.132 rtr static int 787 1.132 rtr rip6_shutdown(struct socket *so) 788 1.132 rtr { 789 1.132 rtr KASSERT(solocked(so)); 790 1.132 rtr 791 1.132 rtr /* 792 1.178 andvar * Mark the connection as being incapable of further input. 793 1.132 rtr */ 794 1.132 rtr socantsendmore(so); 795 1.132 rtr return 0; 796 1.132 rtr } 797 1.132 rtr 798 1.132 rtr static int 799 1.132 rtr rip6_abort(struct socket *so) 800 1.132 rtr { 801 1.132 rtr KASSERT(solocked(so)); 802 1.132 rtr 803 1.132 rtr soisdisconnected(so); 804 1.132 rtr rip6_detach(so); 805 1.132 rtr return 0; 806 1.132 rtr } 807 1.132 rtr 808 1.132 rtr static int 809 1.121 rtr rip6_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 810 1.119 rtr { 811 1.121 rtr return in6_control(so, cmd, nam, ifp); 812 1.119 rtr } 813 1.119 rtr 814 1.122 rtr static int 815 1.122 rtr rip6_stat(struct socket *so, struct stat *ub) 816 1.122 rtr { 817 1.125 rtr KASSERT(solocked(so)); 818 1.125 rtr 819 1.124 rtr /* stat: don't bother with a blocksize */ 820 1.124 rtr return 0; 821 1.122 rtr } 822 1.122 rtr 823 1.126 rtr static int 824 1.138 rtr rip6_peeraddr(struct socket *so, struct sockaddr *nam) 825 1.126 rtr { 826 1.126 rtr KASSERT(solocked(so)); 827 1.179 ozaki KASSERT(sotoinpcb(so) != NULL); 828 1.126 rtr KASSERT(nam != NULL); 829 1.126 rtr 830 1.182 ozaki in6pcb_fetch_peeraddr(sotoinpcb(so), (struct sockaddr_in6 *)nam); 831 1.126 rtr return 0; 832 1.126 rtr } 833 1.126 rtr 834 1.126 rtr static int 835 1.138 rtr rip6_sockaddr(struct socket *so, struct sockaddr *nam) 836 1.126 rtr { 837 1.126 rtr KASSERT(solocked(so)); 838 1.179 ozaki KASSERT(sotoinpcb(so) != NULL); 839 1.126 rtr KASSERT(nam != NULL); 840 1.126 rtr 841 1.182 ozaki in6pcb_fetch_sockaddr(sotoinpcb(so), (struct sockaddr_in6 *)nam); 842 1.126 rtr return 0; 843 1.126 rtr } 844 1.126 rtr 845 1.128 rtr static int 846 1.135 rtr rip6_rcvd(struct socket *so, int flags, struct lwp *l) 847 1.135 rtr { 848 1.135 rtr KASSERT(solocked(so)); 849 1.135 rtr 850 1.135 rtr return EOPNOTSUPP; 851 1.135 rtr } 852 1.135 rtr 853 1.135 rtr static int 854 1.128 rtr rip6_recvoob(struct socket *so, struct mbuf *m, int flags) 855 1.128 rtr { 856 1.128 rtr KASSERT(solocked(so)); 857 1.128 rtr 858 1.128 rtr return EOPNOTSUPP; 859 1.128 rtr } 860 1.128 rtr 861 1.128 rtr static int 862 1.140 rtr rip6_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, 863 1.134 rtr struct mbuf *control, struct lwp *l) 864 1.134 rtr { 865 1.179 ozaki struct inpcb *inp = sotoinpcb(so); 866 1.134 rtr struct sockaddr_in6 tmp; 867 1.134 rtr struct sockaddr_in6 *dst; 868 1.134 rtr int error = 0; 869 1.134 rtr 870 1.134 rtr KASSERT(solocked(so)); 871 1.179 ozaki KASSERT(inp != NULL); 872 1.134 rtr KASSERT(m != NULL); 873 1.134 rtr 874 1.134 rtr /* 875 1.134 rtr * Ship a packet out. The appropriate raw output 876 1.134 rtr * routine handles any messaging necessary. 877 1.134 rtr */ 878 1.134 rtr 879 1.134 rtr /* always copy sockaddr to avoid overwrites */ 880 1.134 rtr if (so->so_state & SS_ISCONNECTED) { 881 1.134 rtr if (nam) { 882 1.134 rtr error = EISCONN; 883 1.134 rtr goto release; 884 1.134 rtr } 885 1.134 rtr /* XXX */ 886 1.180 ozaki sockaddr_in6_init(&tmp, &in6p_faddr(inp), 0, 0, 0); 887 1.134 rtr dst = &tmp; 888 1.134 rtr } else { 889 1.134 rtr if (nam == NULL) { 890 1.134 rtr error = ENOTCONN; 891 1.134 rtr goto release; 892 1.134 rtr } 893 1.140 rtr tmp = *(struct sockaddr_in6 *)nam; 894 1.134 rtr dst = &tmp; 895 1.134 rtr 896 1.134 rtr if (dst->sin6_family != AF_INET6) { 897 1.134 rtr error = EAFNOSUPPORT; 898 1.134 rtr goto release; 899 1.134 rtr } 900 1.175 maxv if (dst->sin6_len != sizeof(*dst)) { 901 1.175 maxv error = EINVAL; 902 1.175 maxv goto release; 903 1.175 maxv } 904 1.134 rtr } 905 1.134 rtr error = rip6_output(m, so, dst, control); 906 1.134 rtr m = NULL; 907 1.134 rtr 908 1.134 rtr release: 909 1.185 rin m_freem(m); 910 1.134 rtr 911 1.134 rtr return error; 912 1.134 rtr } 913 1.134 rtr 914 1.134 rtr static int 915 1.128 rtr rip6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 916 1.128 rtr { 917 1.128 rtr KASSERT(solocked(so)); 918 1.128 rtr 919 1.173 martin m_freem(m); 920 1.173 martin m_freem(control); 921 1.128 rtr 922 1.128 rtr return EOPNOTSUPP; 923 1.128 rtr } 924 1.128 rtr 925 1.136 rtr static int 926 1.136 rtr rip6_purgeif(struct socket *so, struct ifnet *ifp) 927 1.136 rtr { 928 1.136 rtr 929 1.136 rtr mutex_enter(softnet_lock); 930 1.182 ozaki in6pcb_purgeif0(&raw6cbtable, ifp); 931 1.155 ozaki #ifdef NET_MPSAFE 932 1.155 ozaki mutex_exit(softnet_lock); 933 1.153 knakahar #endif 934 1.136 rtr in6_purgeif(ifp); 935 1.155 ozaki #ifdef NET_MPSAFE 936 1.155 ozaki mutex_enter(softnet_lock); 937 1.155 ozaki #endif 938 1.182 ozaki in6pcb_purgeif(&raw6cbtable, ifp); 939 1.136 rtr mutex_exit(softnet_lock); 940 1.136 rtr 941 1.136 rtr return 0; 942 1.136 rtr } 943 1.136 rtr 944 1.95 thorpej static int 945 1.95 thorpej sysctl_net_inet6_raw6_stats(SYSCTLFN_ARGS) 946 1.95 thorpej { 947 1.95 thorpej 948 1.99 thorpej return (NETSTAT_SYSCTL(rip6stat_percpu, RIP6_NSTATS)); 949 1.95 thorpej } 950 1.95 thorpej 951 1.105 pooka static void 952 1.105 pooka sysctl_net_inet6_raw6_setup(struct sysctllog **clog) 953 1.69 atatat { 954 1.69 atatat 955 1.69 atatat sysctl_createv(clog, 0, NULL, NULL, 956 1.69 atatat CTLFLAG_PERMANENT, 957 1.69 atatat CTLTYPE_NODE, "inet6", NULL, 958 1.69 atatat NULL, 0, NULL, 0, 959 1.69 atatat CTL_NET, PF_INET6, CTL_EOL); 960 1.69 atatat sysctl_createv(clog, 0, NULL, NULL, 961 1.69 atatat CTLFLAG_PERMANENT, 962 1.69 atatat CTLTYPE_NODE, "raw6", 963 1.69 atatat SYSCTL_DESCR("Raw IPv6 settings"), 964 1.69 atatat NULL, 0, NULL, 0, 965 1.69 atatat CTL_NET, PF_INET6, IPPROTO_RAW, CTL_EOL); 966 1.69 atatat 967 1.69 atatat sysctl_createv(clog, 0, NULL, NULL, 968 1.69 atatat CTLFLAG_PERMANENT, 969 1.71 atatat CTLTYPE_STRUCT, "pcblist", 970 1.69 atatat SYSCTL_DESCR("Raw IPv6 control block list"), 971 1.69 atatat sysctl_inpcblist, 0, &raw6cbtable, 0, 972 1.69 atatat CTL_NET, PF_INET6, IPPROTO_RAW, 973 1.69 atatat CTL_CREATE, CTL_EOL); 974 1.73 rpaulo sysctl_createv(clog, 0, NULL, NULL, 975 1.73 rpaulo CTLFLAG_PERMANENT, 976 1.73 rpaulo CTLTYPE_STRUCT, "stats", 977 1.73 rpaulo SYSCTL_DESCR("Raw IPv6 statistics"), 978 1.95 thorpej sysctl_net_inet6_raw6_stats, 0, NULL, 0, 979 1.73 rpaulo CTL_NET, PF_INET6, IPPROTO_RAW, RAW6CTL_STATS, 980 1.73 rpaulo CTL_EOL); 981 1.69 atatat } 982 1.115 rmind 983 1.117 rmind PR_WRAP_USRREQS(rip6) 984 1.117 rmind #define rip6_attach rip6_attach_wrapper 985 1.117 rmind #define rip6_detach rip6_detach_wrapper 986 1.127 rtr #define rip6_accept rip6_accept_wrapper 987 1.129 rtr #define rip6_bind rip6_bind_wrapper 988 1.129 rtr #define rip6_listen rip6_listen_wrapper 989 1.130 rtr #define rip6_connect rip6_connect_wrapper 990 1.136 rtr #define rip6_connect2 rip6_connect2_wrapper 991 1.132 rtr #define rip6_disconnect rip6_disconnect_wrapper 992 1.132 rtr #define rip6_shutdown rip6_shutdown_wrapper 993 1.132 rtr #define rip6_abort rip6_abort_wrapper 994 1.119 rtr #define rip6_ioctl rip6_ioctl_wrapper 995 1.122 rtr #define rip6_stat rip6_stat_wrapper 996 1.126 rtr #define rip6_peeraddr rip6_peeraddr_wrapper 997 1.126 rtr #define rip6_sockaddr rip6_sockaddr_wrapper 998 1.135 rtr #define rip6_rcvd rip6_rcvd_wrapper 999 1.128 rtr #define rip6_recvoob rip6_recvoob_wrapper 1000 1.134 rtr #define rip6_send rip6_send_wrapper 1001 1.128 rtr #define rip6_sendoob rip6_sendoob_wrapper 1002 1.136 rtr #define rip6_purgeif rip6_purgeif_wrapper 1003 1.115 rmind 1004 1.115 rmind const struct pr_usrreqs rip6_usrreqs = { 1005 1.116 rmind .pr_attach = rip6_attach, 1006 1.116 rmind .pr_detach = rip6_detach, 1007 1.127 rtr .pr_accept = rip6_accept, 1008 1.129 rtr .pr_bind = rip6_bind, 1009 1.129 rtr .pr_listen = rip6_listen, 1010 1.130 rtr .pr_connect = rip6_connect, 1011 1.136 rtr .pr_connect2 = rip6_connect2, 1012 1.132 rtr .pr_disconnect = rip6_disconnect, 1013 1.132 rtr .pr_shutdown = rip6_shutdown, 1014 1.132 rtr .pr_abort = rip6_abort, 1015 1.119 rtr .pr_ioctl = rip6_ioctl, 1016 1.122 rtr .pr_stat = rip6_stat, 1017 1.126 rtr .pr_peeraddr = rip6_peeraddr, 1018 1.126 rtr .pr_sockaddr = rip6_sockaddr, 1019 1.135 rtr .pr_rcvd = rip6_rcvd, 1020 1.128 rtr .pr_recvoob = rip6_recvoob, 1021 1.134 rtr .pr_send = rip6_send, 1022 1.128 rtr .pr_sendoob = rip6_sendoob, 1023 1.136 rtr .pr_purgeif = rip6_purgeif, 1024 1.115 rmind }; 1025