]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netinet6/udp6_usrreq.c
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r303571, and update
[FreeBSD/FreeBSD.git] / sys / netinet6 / udp6_usrreq.c
1 /*-
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * Copyright (c) 2010-2011 Juniper Networks, Inc.
4  * Copyright (c) 2014 Kevin Lo
5  * All rights reserved.
6  *
7  * Portions of this software were developed by Robert N. M. Watson under
8  * contract to Juniper Networks, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the project nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *      $KAME: udp6_usrreq.c,v 1.27 2001/05/21 05:45:10 jinmei Exp $
35  *      $KAME: udp6_output.c,v 1.31 2001/05/21 16:39:15 jinmei Exp $
36  */
37
38 /*-
39  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
40  *      The Regents of the University of California.
41  * All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. Neither the name of the University nor the names of its contributors
52  *    may be used to endorse or promote products derived from this software
53  *    without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  *
67  *      @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95
68  */
69
70 #include <sys/cdefs.h>
71 __FBSDID("$FreeBSD$");
72
73 #include "opt_inet.h"
74 #include "opt_inet6.h"
75 #include "opt_ipsec.h"
76 #include "opt_rss.h"
77
78 #include <sys/param.h>
79 #include <sys/jail.h>
80 #include <sys/kernel.h>
81 #include <sys/lock.h>
82 #include <sys/mbuf.h>
83 #include <sys/priv.h>
84 #include <sys/proc.h>
85 #include <sys/protosw.h>
86 #include <sys/sdt.h>
87 #include <sys/signalvar.h>
88 #include <sys/socket.h>
89 #include <sys/socketvar.h>
90 #include <sys/sx.h>
91 #include <sys/sysctl.h>
92 #include <sys/syslog.h>
93 #include <sys/systm.h>
94
95 #include <net/if.h>
96 #include <net/if_var.h>
97 #include <net/if_types.h>
98 #include <net/route.h>
99 #include <net/rss_config.h>
100
101 #include <netinet/in.h>
102 #include <netinet/in_kdtrace.h>
103 #include <netinet/in_pcb.h>
104 #include <netinet/in_systm.h>
105 #include <netinet/in_var.h>
106 #include <netinet/ip.h>
107 #include <netinet/ip_icmp.h>
108 #include <netinet/ip6.h>
109 #include <netinet/icmp_var.h>
110 #include <netinet/icmp6.h>
111 #include <netinet/ip_var.h>
112 #include <netinet/udp.h>
113 #include <netinet/udp_var.h>
114 #include <netinet/udplite.h>
115
116 #include <netinet6/ip6protosw.h>
117 #include <netinet6/ip6_var.h>
118 #include <netinet6/in6_pcb.h>
119 #include <netinet6/in6_rss.h>
120 #include <netinet6/udp6_var.h>
121 #include <netinet6/scope6_var.h>
122
123 #include <netipsec/ipsec_support.h>
124
125 #include <security/mac/mac_framework.h>
126
127 /*
128  * UDP protocol implementation.
129  * Per RFC 768, August, 1980.
130  */
131
132 extern struct protosw   inetsw[];
133 static void             udp6_detach(struct socket *so);
134
135 static int
136 udp6_append(struct inpcb *inp, struct mbuf *n, int off,
137     struct sockaddr_in6 *fromsa)
138 {
139         struct socket *so;
140         struct mbuf *opts = NULL, *tmp_opts;
141         struct udpcb *up;
142
143         INP_LOCK_ASSERT(inp);
144
145         /*
146          * Engage the tunneling protocol.
147          */
148         up = intoudpcb(inp);
149         if (up->u_tun_func != NULL) {
150                 in_pcbref(inp);
151                 INP_RUNLOCK(inp);
152                 (*up->u_tun_func)(n, off, inp, (struct sockaddr *)&fromsa[0],
153                     up->u_tun_ctx);
154                 INP_RLOCK(inp);
155                 return (in_pcbrele_rlocked(inp));
156         }
157 #if defined(IPSEC) || defined(IPSEC_SUPPORT)
158         /* Check AH/ESP integrity. */
159         if (IPSEC_ENABLED(ipv6)) {
160                 if (IPSEC_CHECK_POLICY(ipv6, n, inp) != 0) {
161                         m_freem(n);
162                         return (0);
163                 }
164         }
165 #endif /* IPSEC */
166 #ifdef MAC
167         if (mac_inpcb_check_deliver(inp, n) != 0) {
168                 m_freem(n);
169                 return (0);
170         }
171 #endif
172         opts = NULL;
173         if (inp->inp_flags & INP_CONTROLOPTS ||
174             inp->inp_socket->so_options & SO_TIMESTAMP)
175                 ip6_savecontrol(inp, n, &opts);
176         if ((inp->inp_vflag & INP_IPV6) && (inp->inp_flags2 & INP_ORIGDSTADDR)) {
177                 tmp_opts = sbcreatecontrol((caddr_t)&fromsa[1],
178                         sizeof(struct sockaddr_in6), IPV6_ORIGDSTADDR, IPPROTO_IPV6);
179                 if (tmp_opts) {
180                         if (opts) {
181                                 tmp_opts->m_next = opts;
182                                 opts = tmp_opts;
183                         } else
184                                 opts = tmp_opts;
185                 }
186
187         }
188         m_adj(n, off + sizeof(struct udphdr));
189
190         so = inp->inp_socket;
191         SOCKBUF_LOCK(&so->so_rcv);
192         if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n,
193             opts) == 0) {
194                 SOCKBUF_UNLOCK(&so->so_rcv);
195                 m_freem(n);
196                 if (opts)
197                         m_freem(opts);
198                 UDPSTAT_INC(udps_fullsock);
199         } else
200                 sorwakeup_locked(so);
201         return (0);
202 }
203
204 int
205 udp6_input(struct mbuf **mp, int *offp, int proto)
206 {
207         struct mbuf *m = *mp;
208         struct ifnet *ifp;
209         struct ip6_hdr *ip6;
210         struct udphdr *uh;
211         struct inpcb *inp;
212         struct inpcbinfo *pcbinfo;
213         struct udpcb *up;
214         int off = *offp;
215         int cscov_partial;
216         int plen, ulen;
217         struct sockaddr_in6 fromsa[2];
218         struct m_tag *fwd_tag;
219         uint16_t uh_sum;
220         uint8_t nxt;
221
222         ifp = m->m_pkthdr.rcvif;
223         ip6 = mtod(m, struct ip6_hdr *);
224
225 #ifndef PULLDOWN_TEST
226         IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE);
227         ip6 = mtod(m, struct ip6_hdr *);
228         uh = (struct udphdr *)((caddr_t)ip6 + off);
229 #else
230         IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(*uh));
231         if (!uh)
232                 return (IPPROTO_DONE);
233 #endif
234
235         UDPSTAT_INC(udps_ipackets);
236
237         /*
238          * Destination port of 0 is illegal, based on RFC768.
239          */
240         if (uh->uh_dport == 0)
241                 goto badunlocked;
242
243         plen = ntohs(ip6->ip6_plen) - off + sizeof(*ip6);
244         ulen = ntohs((u_short)uh->uh_ulen);
245
246         nxt = proto;
247         cscov_partial = (nxt == IPPROTO_UDPLITE) ? 1 : 0;
248         if (nxt == IPPROTO_UDPLITE) {
249                 /* Zero means checksum over the complete packet. */
250                 if (ulen == 0)
251                         ulen = plen;
252                 if (ulen == plen)
253                         cscov_partial = 0;
254                 if ((ulen < sizeof(struct udphdr)) || (ulen > plen)) {
255                         /* XXX: What is the right UDPLite MIB counter? */
256                         goto badunlocked;
257                 }
258                 if (uh->uh_sum == 0) {
259                         /* XXX: What is the right UDPLite MIB counter? */
260                         goto badunlocked;
261                 }
262         } else {
263                 if ((ulen < sizeof(struct udphdr)) || (plen != ulen)) {
264                         UDPSTAT_INC(udps_badlen);
265                         goto badunlocked;
266                 }
267                 if (uh->uh_sum == 0) {
268                         UDPSTAT_INC(udps_nosum);
269                         goto badunlocked;
270                 }
271         }
272
273         if ((m->m_pkthdr.csum_flags & CSUM_DATA_VALID_IPV6) &&
274             !cscov_partial) {
275                 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
276                         uh_sum = m->m_pkthdr.csum_data;
277                 else
278                         uh_sum = in6_cksum_pseudo(ip6, ulen, nxt,
279                             m->m_pkthdr.csum_data);
280                 uh_sum ^= 0xffff;
281         } else
282                 uh_sum = in6_cksum_partial(m, nxt, off, plen, ulen);
283
284         if (uh_sum != 0) {
285                 UDPSTAT_INC(udps_badsum);
286                 goto badunlocked;
287         }
288
289         /*
290          * Construct sockaddr format source address.
291          */
292         init_sin6(&fromsa[0], m, 0);
293         fromsa[0].sin6_port = uh->uh_sport;
294         init_sin6(&fromsa[1], m, 1);
295         fromsa[1].sin6_port = uh->uh_dport;
296
297         pcbinfo = udp_get_inpcbinfo(nxt);
298         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
299                 struct inpcb *last;
300                 struct inpcbhead *pcblist;
301                 struct ip6_moptions *imo;
302
303                 INP_INFO_RLOCK(pcbinfo);
304                 /*
305                  * In the event that laddr should be set to the link-local
306                  * address (this happens in RIPng), the multicast address
307                  * specified in the received packet will not match laddr.  To
308                  * handle this situation, matching is relaxed if the
309                  * receiving interface is the same as one specified in the
310                  * socket and if the destination multicast address matches
311                  * one of the multicast groups specified in the socket.
312                  */
313
314                 /*
315                  * KAME note: traditionally we dropped udpiphdr from mbuf
316                  * here.  We need udphdr for IPsec processing so we do that
317                  * later.
318                  */
319                 pcblist = udp_get_pcblist(nxt);
320                 last = NULL;
321                 LIST_FOREACH(inp, pcblist, inp_list) {
322                         if ((inp->inp_vflag & INP_IPV6) == 0)
323                                 continue;
324                         if (inp->inp_lport != uh->uh_dport)
325                                 continue;
326                         if (inp->inp_fport != 0 &&
327                             inp->inp_fport != uh->uh_sport)
328                                 continue;
329                         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
330                                 if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
331                                                         &ip6->ip6_dst))
332                                         continue;
333                         }
334                         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
335                                 if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr,
336                                                         &ip6->ip6_src) ||
337                                     inp->inp_fport != uh->uh_sport)
338                                         continue;
339                         }
340
341                         /*
342                          * XXXRW: Because we weren't holding either the inpcb
343                          * or the hash lock when we checked for a match 
344                          * before, we should probably recheck now that the 
345                          * inpcb lock is (supposed to be) held.
346                          */
347
348                         /*
349                          * Handle socket delivery policy for any-source
350                          * and source-specific multicast. [RFC3678]
351                          */
352                         imo = inp->in6p_moptions;
353                         if (imo && IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
354                                 struct sockaddr_in6      mcaddr;
355                                 int                      blocked;
356
357                                 INP_RLOCK(inp);
358
359                                 bzero(&mcaddr, sizeof(struct sockaddr_in6));
360                                 mcaddr.sin6_len = sizeof(struct sockaddr_in6);
361                                 mcaddr.sin6_family = AF_INET6;
362                                 mcaddr.sin6_addr = ip6->ip6_dst;
363
364                                 blocked = im6o_mc_filter(imo, ifp,
365                                         (struct sockaddr *)&mcaddr,
366                                         (struct sockaddr *)&fromsa[0]);
367                                 if (blocked != MCAST_PASS) {
368                                         if (blocked == MCAST_NOTGMEMBER)
369                                                 IP6STAT_INC(ip6s_notmember);
370                                         if (blocked == MCAST_NOTSMEMBER ||
371                                             blocked == MCAST_MUTED)
372                                                 UDPSTAT_INC(udps_filtermcast);
373                                         INP_RUNLOCK(inp); /* XXX */
374                                         continue;
375                                 }
376
377                                 INP_RUNLOCK(inp);
378                         }
379                         if (last != NULL) {
380                                 struct mbuf *n;
381
382                                 if ((n = m_copym(m, 0, M_COPYALL, M_NOWAIT)) !=
383                                     NULL) {
384                                         INP_RLOCK(last);
385                                         UDP_PROBE(receive, NULL, last, ip6,
386                                             last, uh);
387                                         if (udp6_append(last, n, off, fromsa))
388                                                 goto inp_lost;
389                                         INP_RUNLOCK(last);
390                                 }
391                         }
392                         last = inp;
393                         /*
394                          * Don't look for additional matches if this one does
395                          * not have either the SO_REUSEPORT or SO_REUSEADDR
396                          * socket options set.  This heuristic avoids
397                          * searching through all pcbs in the common case of a
398                          * non-shared port.  It assumes that an application
399                          * will never clear these options after setting them.
400                          */
401                         if ((last->inp_socket->so_options &
402                              (SO_REUSEPORT|SO_REUSEADDR)) == 0)
403                                 break;
404                 }
405
406                 if (last == NULL) {
407                         /*
408                          * No matching pcb found; discard datagram.  (No need
409                          * to send an ICMP Port Unreachable for a broadcast
410                          * or multicast datgram.)
411                          */
412                         UDPSTAT_INC(udps_noport);
413                         UDPSTAT_INC(udps_noportmcast);
414                         goto badheadlocked;
415                 }
416                 INP_RLOCK(last);
417                 INP_INFO_RUNLOCK(pcbinfo);
418                 UDP_PROBE(receive, NULL, last, ip6, last, uh);
419                 if (udp6_append(last, m, off, fromsa) == 0) 
420                         INP_RUNLOCK(last);
421         inp_lost:
422                 return (IPPROTO_DONE);
423         }
424         /*
425          * Locate pcb for datagram.
426          */
427
428         /*
429          * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
430          */
431         if ((m->m_flags & M_IP6_NEXTHOP) &&
432             (fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL) {
433                 struct sockaddr_in6 *next_hop6;
434
435                 next_hop6 = (struct sockaddr_in6 *)(fwd_tag + 1);
436
437                 /*
438                  * Transparently forwarded. Pretend to be the destination.
439                  * Already got one like this?
440                  */
441                 inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
442                     uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
443                     INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif, m);
444                 if (!inp) {
445                         /*
446                          * It's new.  Try to find the ambushing socket.
447                          * Because we've rewritten the destination address,
448                          * any hardware-generated hash is ignored.
449                          */
450                         inp = in6_pcblookup(pcbinfo, &ip6->ip6_src,
451                             uh->uh_sport, &next_hop6->sin6_addr,
452                             next_hop6->sin6_port ? htons(next_hop6->sin6_port) :
453                             uh->uh_dport, INPLOOKUP_WILDCARD |
454                             INPLOOKUP_RLOCKPCB, m->m_pkthdr.rcvif);
455                 }
456                 /* Remove the tag from the packet. We don't need it anymore. */
457                 m_tag_delete(m, fwd_tag);
458                 m->m_flags &= ~M_IP6_NEXTHOP;
459         } else
460                 inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_src,
461                     uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
462                     INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
463                     m->m_pkthdr.rcvif, m);
464         if (inp == NULL) {
465                 if (udp_log_in_vain) {
466                         char ip6bufs[INET6_ADDRSTRLEN];
467                         char ip6bufd[INET6_ADDRSTRLEN];
468
469                         log(LOG_INFO,
470                             "Connection attempt to UDP [%s]:%d from [%s]:%d\n",
471                             ip6_sprintf(ip6bufd, &ip6->ip6_dst),
472                             ntohs(uh->uh_dport),
473                             ip6_sprintf(ip6bufs, &ip6->ip6_src),
474                             ntohs(uh->uh_sport));
475                 }
476                 UDPSTAT_INC(udps_noport);
477                 if (m->m_flags & M_MCAST) {
478                         printf("UDP6: M_MCAST is set in a unicast packet.\n");
479                         UDPSTAT_INC(udps_noportmcast);
480                         goto badunlocked;
481                 }
482                 if (V_udp_blackhole)
483                         goto badunlocked;
484                 if (badport_bandlim(BANDLIM_ICMP6_UNREACH) < 0)
485                         goto badunlocked;
486                 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
487                 return (IPPROTO_DONE);
488         }
489         INP_RLOCK_ASSERT(inp);
490         up = intoudpcb(inp);
491         if (cscov_partial) {
492                 if (up->u_rxcslen == 0 || up->u_rxcslen > ulen) {
493                         INP_RUNLOCK(inp);
494                         m_freem(m);
495                         return (IPPROTO_DONE);
496                 }
497         }
498         UDP_PROBE(receive, NULL, inp, ip6, inp, uh);
499         if (udp6_append(inp, m, off, fromsa) == 0)
500                 INP_RUNLOCK(inp);
501         return (IPPROTO_DONE);
502
503 badheadlocked:
504         INP_INFO_RUNLOCK(pcbinfo);
505 badunlocked:
506         if (m)
507                 m_freem(m);
508         return (IPPROTO_DONE);
509 }
510
511 static void
512 udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
513     struct inpcbinfo *pcbinfo)
514 {
515         struct udphdr uh;
516         struct ip6_hdr *ip6;
517         struct mbuf *m;
518         int off = 0;
519         struct ip6ctlparam *ip6cp = NULL;
520         const struct sockaddr_in6 *sa6_src = NULL;
521         void *cmdarg;
522         struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
523         struct udp_portonly {
524                 u_int16_t uh_sport;
525                 u_int16_t uh_dport;
526         } *uhp;
527
528         if (sa->sa_family != AF_INET6 ||
529             sa->sa_len != sizeof(struct sockaddr_in6))
530                 return;
531
532         if ((unsigned)cmd >= PRC_NCMDS)
533                 return;
534         if (PRC_IS_REDIRECT(cmd))
535                 notify = in6_rtchange, d = NULL;
536         else if (cmd == PRC_HOSTDEAD)
537                 d = NULL;
538         else if (inet6ctlerrmap[cmd] == 0)
539                 return;
540
541         /* if the parameter is from icmp6, decode it. */
542         if (d != NULL) {
543                 ip6cp = (struct ip6ctlparam *)d;
544                 m = ip6cp->ip6c_m;
545                 ip6 = ip6cp->ip6c_ip6;
546                 off = ip6cp->ip6c_off;
547                 cmdarg = ip6cp->ip6c_cmdarg;
548                 sa6_src = ip6cp->ip6c_src;
549         } else {
550                 m = NULL;
551                 ip6 = NULL;
552                 cmdarg = NULL;
553                 sa6_src = &sa6_any;
554         }
555
556         if (ip6) {
557                 /*
558                  * XXX: We assume that when IPV6 is non NULL,
559                  * M and OFF are valid.
560                  */
561
562                 /* Check if we can safely examine src and dst ports. */
563                 if (m->m_pkthdr.len < off + sizeof(*uhp))
564                         return;
565
566                 bzero(&uh, sizeof(uh));
567                 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
568
569                 if (!PRC_IS_REDIRECT(cmd)) {
570                         /* Check to see if its tunneled */
571                         struct inpcb *inp;
572                         inp = in6_pcblookup_mbuf(pcbinfo, &ip6->ip6_dst,
573                             uh.uh_dport, &ip6->ip6_src, uh.uh_sport,
574                             INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB,
575                             m->m_pkthdr.rcvif, m);
576                         if (inp != NULL) {
577                                 struct udpcb *up;
578                                 
579                                 up = intoudpcb(inp);
580                                 if (up->u_icmp_func) {
581                                         /* Yes it is. */
582                                         INP_RUNLOCK(inp);
583                                         (*up->u_icmp_func)(cmd, (struct sockaddr *)ip6cp->ip6c_src,
584                                               d, up->u_tun_ctx);
585                                         return;
586                                 } else {
587                                         /* Can't find it. */
588                                         INP_RUNLOCK(inp);
589                                 }
590                         }
591                 }
592                 (void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport,
593                     (struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd,
594                     cmdarg, notify);
595         } else
596                 (void)in6_pcbnotify(pcbinfo, sa, 0,
597                     (const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
598 }
599
600 void
601 udp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
602 {
603
604         return (udp6_common_ctlinput(cmd, sa, d, &V_udbinfo));
605 }
606
607 void
608 udplite6_ctlinput(int cmd, struct sockaddr *sa, void *d)
609 {
610
611         return (udp6_common_ctlinput(cmd, sa, d, &V_ulitecbinfo));
612 }
613
614 static int
615 udp6_getcred(SYSCTL_HANDLER_ARGS)
616 {
617         struct xucred xuc;
618         struct sockaddr_in6 addrs[2];
619         struct inpcb *inp;
620         int error;
621
622         error = priv_check(req->td, PRIV_NETINET_GETCRED);
623         if (error)
624                 return (error);
625
626         if (req->newlen != sizeof(addrs))
627                 return (EINVAL);
628         if (req->oldlen != sizeof(struct xucred))
629                 return (EINVAL);
630         error = SYSCTL_IN(req, addrs, sizeof(addrs));
631         if (error)
632                 return (error);
633         if ((error = sa6_embedscope(&addrs[0], V_ip6_use_defzone)) != 0 ||
634             (error = sa6_embedscope(&addrs[1], V_ip6_use_defzone)) != 0) {
635                 return (error);
636         }
637         inp = in6_pcblookup(&V_udbinfo, &addrs[1].sin6_addr,
638             addrs[1].sin6_port, &addrs[0].sin6_addr, addrs[0].sin6_port,
639             INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
640         if (inp != NULL) {
641                 INP_RLOCK_ASSERT(inp);
642                 if (inp->inp_socket == NULL)
643                         error = ENOENT;
644                 if (error == 0)
645                         error = cr_canseesocket(req->td->td_ucred,
646                             inp->inp_socket);
647                 if (error == 0)
648                         cru2x(inp->inp_cred, &xuc);
649                 INP_RUNLOCK(inp);
650         } else
651                 error = ENOENT;
652         if (error == 0)
653                 error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
654         return (error);
655 }
656
657 SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW, 0,
658     0, udp6_getcred, "S,xucred", "Get the xucred of a UDP6 connection");
659
660 static int
661 udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
662     struct mbuf *control, struct thread *td)
663 {
664         u_int32_t ulen = m->m_pkthdr.len;
665         u_int32_t plen = sizeof(struct udphdr) + ulen;
666         struct ip6_hdr *ip6;
667         struct udphdr *udp6;
668         struct in6_addr *laddr, *faddr, in6a;
669         struct sockaddr_in6 *sin6 = NULL;
670         int cscov_partial = 0;
671         int scope_ambiguous = 0;
672         u_short fport;
673         int error = 0;
674         uint8_t nxt;
675         uint16_t cscov = 0;
676         struct ip6_pktopts *optp, opt;
677         int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
678         int flags;
679         struct sockaddr_in6 tmp;
680
681         INP_WLOCK_ASSERT(inp);
682         INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
683
684         if (addr6) {
685                 /* addr6 has been validated in udp6_send(). */
686                 sin6 = (struct sockaddr_in6 *)addr6;
687
688                 /* protect *sin6 from overwrites */
689                 tmp = *sin6;
690                 sin6 = &tmp;
691
692                 /*
693                  * Application should provide a proper zone ID or the use of
694                  * default zone IDs should be enabled.  Unfortunately, some
695                  * applications do not behave as it should, so we need a
696                  * workaround.  Even if an appropriate ID is not determined,
697                  * we'll see if we can determine the outgoing interface.  If we
698                  * can, determine the zone ID based on the interface below.
699                  */
700                 if (sin6->sin6_scope_id == 0 && !V_ip6_use_defzone)
701                         scope_ambiguous = 1;
702                 if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0)
703                         return (error);
704         }
705
706         nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ?
707             IPPROTO_UDP : IPPROTO_UDPLITE;
708         if (control) {
709                 if ((error = ip6_setpktopts(control, &opt,
710                     inp->in6p_outputopts, td->td_ucred, nxt)) != 0)
711                         goto release;
712                 optp = &opt;
713         } else
714                 optp = inp->in6p_outputopts;
715
716         if (sin6) {
717                 faddr = &sin6->sin6_addr;
718
719                 /*
720                  * Since we saw no essential reason for calling in_pcbconnect,
721                  * we get rid of such kind of logic, and call in6_selectsrc
722                  * and in6_pcbsetport in order to fill in the local address
723                  * and the local port.
724                  */
725                 if (sin6->sin6_port == 0) {
726                         error = EADDRNOTAVAIL;
727                         goto release;
728                 }
729
730                 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
731                         /* how about ::ffff:0.0.0.0 case? */
732                         error = EISCONN;
733                         goto release;
734                 }
735
736                 fport = sin6->sin6_port; /* allow 0 port */
737
738                 if (IN6_IS_ADDR_V4MAPPED(faddr)) {
739                         if ((inp->inp_flags & IN6P_IPV6_V6ONLY)) {
740                                 /*
741                                  * I believe we should explicitly discard the
742                                  * packet when mapped addresses are disabled,
743                                  * rather than send the packet as an IPv6 one.
744                                  * If we chose the latter approach, the packet
745                                  * might be sent out on the wire based on the
746                                  * default route, the situation which we'd
747                                  * probably want to avoid.
748                                  * (20010421 jinmei@kame.net)
749                                  */
750                                 error = EINVAL;
751                                 goto release;
752                         }
753                         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) &&
754                             !IN6_IS_ADDR_V4MAPPED(&inp->in6p_laddr)) {
755                                 /*
756                                  * when remote addr is an IPv4-mapped address,
757                                  * local addr should not be an IPv6 address,
758                                  * since you cannot determine how to map IPv6
759                                  * source address to IPv4.
760                                  */
761                                 error = EINVAL;
762                                 goto release;
763                         }
764
765                         af = AF_INET;
766                 }
767
768                 if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
769                         error = in6_selectsrc_socket(sin6, optp, inp,
770                             td->td_ucred, scope_ambiguous, &in6a, NULL);
771                         if (error)
772                                 goto release;
773                         laddr = &in6a;
774                 } else
775                         laddr = &inp->in6p_laddr;       /* XXX */
776                 if (laddr == NULL) {
777                         if (error == 0)
778                                 error = EADDRNOTAVAIL;
779                         goto release;
780                 }
781                 if (inp->inp_lport == 0 &&
782                     (error = in6_pcbsetport(laddr, inp, td->td_ucred)) != 0) {
783                         /* Undo an address bind that may have occurred. */
784                         inp->in6p_laddr = in6addr_any;
785                         goto release;
786                 }
787         } else {
788                 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
789                         error = ENOTCONN;
790                         goto release;
791                 }
792                 if (IN6_IS_ADDR_V4MAPPED(&inp->in6p_faddr)) {
793                         if ((inp->inp_flags & IN6P_IPV6_V6ONLY)) {
794                                 /*
795                                  * XXX: this case would happen when the
796                                  * application sets the V6ONLY flag after
797                                  * connecting the foreign address.
798                                  * Such applications should be fixed,
799                                  * so we bark here.
800                                  */
801                                 log(LOG_INFO, "udp6_output: IPV6_V6ONLY "
802                                     "option was set for a connected socket\n");
803                                 error = EINVAL;
804                                 goto release;
805                         } else
806                                 af = AF_INET;
807                 }
808                 laddr = &inp->in6p_laddr;
809                 faddr = &inp->in6p_faddr;
810                 fport = inp->inp_fport;
811         }
812
813         if (af == AF_INET)
814                 hlen = sizeof(struct ip);
815
816         /*
817          * Calculate data length and get a mbuf
818          * for UDP and IP6 headers.
819          */
820         M_PREPEND(m, hlen + sizeof(struct udphdr), M_NOWAIT);
821         if (m == NULL) {
822                 error = ENOBUFS;
823                 goto release;
824         }
825
826         /*
827          * Stuff checksum and output datagram.
828          */
829         udp6 = (struct udphdr *)(mtod(m, caddr_t) + hlen);
830         udp6->uh_sport = inp->inp_lport; /* lport is always set in the PCB */
831         udp6->uh_dport = fport;
832         if (nxt == IPPROTO_UDPLITE) {
833                 struct udpcb *up;
834
835                 up = intoudpcb(inp);
836                 cscov = up->u_txcslen;
837                 if (cscov >= plen)
838                         cscov = 0;
839                 udp6->uh_ulen = htons(cscov);
840                 /*
841                  * For UDP-Lite, checksum coverage length of zero means
842                  * the entire UDPLite packet is covered by the checksum.
843                  */
844                 cscov_partial = (cscov == 0) ? 0 : 1;
845         } else if (plen <= 0xffff)
846                 udp6->uh_ulen = htons((u_short)plen);
847         else
848                 udp6->uh_ulen = 0;
849         udp6->uh_sum = 0;
850
851         switch (af) {
852         case AF_INET6:
853                 ip6 = mtod(m, struct ip6_hdr *);
854                 ip6->ip6_flow   = inp->inp_flow & IPV6_FLOWINFO_MASK;
855                 ip6->ip6_vfc    &= ~IPV6_VERSION_MASK;
856                 ip6->ip6_vfc    |= IPV6_VERSION;
857                 ip6->ip6_plen   = htons((u_short)plen);
858                 ip6->ip6_nxt    = nxt;
859                 ip6->ip6_hlim   = in6_selecthlim(inp, NULL);
860                 ip6->ip6_src    = *laddr;
861                 ip6->ip6_dst    = *faddr;
862
863                 if (cscov_partial) {
864                         if ((udp6->uh_sum = in6_cksum_partial(m, nxt,
865                             sizeof(struct ip6_hdr), plen, cscov)) == 0)
866                                 udp6->uh_sum = 0xffff;
867                 } else {
868                         udp6->uh_sum = in6_cksum_pseudo(ip6, plen, nxt, 0);
869                         m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
870                         m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
871                 }
872
873 #ifdef  RSS
874                 {
875                         uint32_t hash_val, hash_type;
876                         uint8_t pr;
877
878                         pr = inp->inp_socket->so_proto->pr_protocol;
879                         /*
880                          * Calculate an appropriate RSS hash for UDP and
881                          * UDP Lite.
882                          *
883                          * The called function will take care of figuring out
884                          * whether a 2-tuple or 4-tuple hash is required based
885                          * on the currently configured scheme.
886                          *
887                          * Later later on connected socket values should be
888                          * cached in the inpcb and reused, rather than constantly
889                          * re-calculating it.
890                          *
891                          * UDP Lite is a different protocol number and will
892                          * likely end up being hashed as a 2-tuple until
893                          * RSS / NICs grow UDP Lite protocol awareness.
894                          */
895                         if (rss_proto_software_hash_v6(faddr, laddr, fport,
896                             inp->inp_lport, pr, &hash_val, &hash_type) == 0) {
897                                 m->m_pkthdr.flowid = hash_val;
898                                 M_HASHTYPE_SET(m, hash_type);
899                         }
900                 }
901 #endif
902                 flags = 0;
903 #ifdef  RSS
904                 /*
905                  * Don't override with the inp cached flowid.
906                  *
907                  * Until the whole UDP path is vetted, it may actually
908                  * be incorrect.
909                  */
910                 flags |= IP_NODEFAULTFLOWID;
911 #endif
912
913                 UDP_PROBE(send, NULL, inp, ip6, inp, udp6);
914                 UDPSTAT_INC(udps_opackets);
915                 error = ip6_output(m, optp, &inp->inp_route6, flags,
916                     inp->in6p_moptions, NULL, inp);
917                 break;
918         case AF_INET:
919                 error = EAFNOSUPPORT;
920                 goto release;
921         }
922         goto releaseopt;
923
924 release:
925         m_freem(m);
926
927 releaseopt:
928         if (control) {
929                 ip6_clearpktopts(&opt, -1);
930                 m_freem(control);
931         }
932         return (error);
933 }
934
935 static void
936 udp6_abort(struct socket *so)
937 {
938         struct inpcb *inp;
939         struct inpcbinfo *pcbinfo;
940
941         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
942         inp = sotoinpcb(so);
943         KASSERT(inp != NULL, ("udp6_abort: inp == NULL"));
944
945         INP_WLOCK(inp);
946 #ifdef INET
947         if (inp->inp_vflag & INP_IPV4) {
948                 struct pr_usrreqs *pru;
949                 uint8_t nxt;
950
951                 nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ?
952                     IPPROTO_UDP : IPPROTO_UDPLITE;
953                 INP_WUNLOCK(inp);
954                 pru = inetsw[ip_protox[nxt]].pr_usrreqs;
955                 (*pru->pru_abort)(so);
956                 return;
957         }
958 #endif
959
960         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
961                 INP_HASH_WLOCK(pcbinfo);
962                 in6_pcbdisconnect(inp);
963                 inp->in6p_laddr = in6addr_any;
964                 INP_HASH_WUNLOCK(pcbinfo);
965                 soisdisconnected(so);
966         }
967         INP_WUNLOCK(inp);
968 }
969
970 static int
971 udp6_attach(struct socket *so, int proto, struct thread *td)
972 {
973         struct inpcb *inp;
974         struct inpcbinfo *pcbinfo;
975         int error;
976
977         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
978         inp = sotoinpcb(so);
979         KASSERT(inp == NULL, ("udp6_attach: inp != NULL"));
980
981         if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
982                 error = soreserve(so, udp_sendspace, udp_recvspace);
983                 if (error)
984                         return (error);
985         }
986         INP_INFO_WLOCK(pcbinfo);
987         error = in_pcballoc(so, pcbinfo);
988         if (error) {
989                 INP_INFO_WUNLOCK(pcbinfo);
990                 return (error);
991         }
992         inp = (struct inpcb *)so->so_pcb;
993         inp->inp_vflag |= INP_IPV6;
994         if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0)
995                 inp->inp_vflag |= INP_IPV4;
996         inp->in6p_hops = -1;    /* use kernel default */
997         inp->in6p_cksum = -1;   /* just to be sure */
998         /*
999          * XXX: ugly!!
1000          * IPv4 TTL initialization is necessary for an IPv6 socket as well,
1001          * because the socket may be bound to an IPv6 wildcard address,
1002          * which may match an IPv4-mapped IPv6 address.
1003          */
1004         inp->inp_ip_ttl = V_ip_defttl;
1005
1006         error = udp_newudpcb(inp);
1007         if (error) {
1008                 in_pcbdetach(inp);
1009                 in_pcbfree(inp);
1010                 INP_INFO_WUNLOCK(pcbinfo);
1011                 return (error);
1012         }
1013         INP_WUNLOCK(inp);
1014         INP_INFO_WUNLOCK(pcbinfo);
1015         return (0);
1016 }
1017
1018 static int
1019 udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
1020 {
1021         struct inpcb *inp;
1022         struct inpcbinfo *pcbinfo;
1023         int error;
1024
1025         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1026         inp = sotoinpcb(so);
1027         KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
1028
1029         INP_WLOCK(inp);
1030         INP_HASH_WLOCK(pcbinfo);
1031         inp->inp_vflag &= ~INP_IPV4;
1032         inp->inp_vflag |= INP_IPV6;
1033         if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1034                 struct sockaddr_in6 *sin6_p;
1035
1036                 sin6_p = (struct sockaddr_in6 *)nam;
1037
1038                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))
1039                         inp->inp_vflag |= INP_IPV4;
1040 #ifdef INET
1041                 else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
1042                         struct sockaddr_in sin;
1043
1044                         in6_sin6_2_sin(&sin, sin6_p);
1045                         inp->inp_vflag |= INP_IPV4;
1046                         inp->inp_vflag &= ~INP_IPV6;
1047                         error = in_pcbbind(inp, (struct sockaddr *)&sin,
1048                             td->td_ucred);
1049                         goto out;
1050                 }
1051 #endif
1052         }
1053
1054         error = in6_pcbbind(inp, nam, td->td_ucred);
1055 #ifdef INET
1056 out:
1057 #endif
1058         INP_HASH_WUNLOCK(pcbinfo);
1059         INP_WUNLOCK(inp);
1060         return (error);
1061 }
1062
1063 static void
1064 udp6_close(struct socket *so)
1065 {
1066         struct inpcb *inp;
1067         struct inpcbinfo *pcbinfo;
1068
1069         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1070         inp = sotoinpcb(so);
1071         KASSERT(inp != NULL, ("udp6_close: inp == NULL"));
1072
1073         INP_WLOCK(inp);
1074 #ifdef INET
1075         if (inp->inp_vflag & INP_IPV4) {
1076                 struct pr_usrreqs *pru;
1077                 uint8_t nxt;
1078
1079                 nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ?
1080                     IPPROTO_UDP : IPPROTO_UDPLITE;
1081                 INP_WUNLOCK(inp);
1082                 pru = inetsw[ip_protox[nxt]].pr_usrreqs;
1083                 (*pru->pru_disconnect)(so);
1084                 return;
1085         }
1086 #endif
1087         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1088                 INP_HASH_WLOCK(pcbinfo);
1089                 in6_pcbdisconnect(inp);
1090                 inp->in6p_laddr = in6addr_any;
1091                 INP_HASH_WUNLOCK(pcbinfo);
1092                 soisdisconnected(so);
1093         }
1094         INP_WUNLOCK(inp);
1095 }
1096
1097 static int
1098 udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
1099 {
1100         struct inpcb *inp;
1101         struct inpcbinfo *pcbinfo;
1102         struct sockaddr_in6 *sin6;
1103         int error;
1104
1105         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1106         inp = sotoinpcb(so);
1107         sin6 = (struct sockaddr_in6 *)nam;
1108         KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
1109
1110         /*
1111          * XXXRW: Need to clarify locking of v4/v6 flags.
1112          */
1113         INP_WLOCK(inp);
1114 #ifdef INET
1115         if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1116                 struct sockaddr_in sin;
1117
1118                 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) != 0) {
1119                         error = EINVAL;
1120                         goto out;
1121                 }
1122                 if ((inp->inp_vflag & INP_IPV4) == 0) {
1123                         error = EAFNOSUPPORT;
1124                         goto out;
1125                 }
1126                 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1127                         error = EISCONN;
1128                         goto out;
1129                 }
1130                 in6_sin6_2_sin(&sin, sin6);
1131                 inp->inp_vflag |= INP_IPV4;
1132                 inp->inp_vflag &= ~INP_IPV6;
1133                 error = prison_remote_ip4(td->td_ucred, &sin.sin_addr);
1134                 if (error != 0)
1135                         goto out;
1136                 INP_HASH_WLOCK(pcbinfo);
1137                 error = in_pcbconnect(inp, (struct sockaddr *)&sin,
1138                     td->td_ucred);
1139                 INP_HASH_WUNLOCK(pcbinfo);
1140                 if (error == 0)
1141                         soisconnected(so);
1142                 goto out;
1143         } else {
1144                 if ((inp->inp_vflag & INP_IPV6) == 0) {
1145                         error = EAFNOSUPPORT;
1146                         goto out;
1147                 }
1148         }
1149 #endif
1150         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1151                 error = EISCONN;
1152                 goto out;
1153         }
1154         inp->inp_vflag &= ~INP_IPV4;
1155         inp->inp_vflag |= INP_IPV6;
1156         error = prison_remote_ip6(td->td_ucred, &sin6->sin6_addr);
1157         if (error != 0)
1158                 goto out;
1159         INP_HASH_WLOCK(pcbinfo);
1160         error = in6_pcbconnect(inp, nam, td->td_ucred);
1161         INP_HASH_WUNLOCK(pcbinfo);
1162         if (error == 0)
1163                 soisconnected(so);
1164 out:
1165         INP_WUNLOCK(inp);
1166         return (error);
1167 }
1168
1169 static void
1170 udp6_detach(struct socket *so)
1171 {
1172         struct inpcb *inp;
1173         struct inpcbinfo *pcbinfo;
1174         struct udpcb *up;
1175
1176         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1177         inp = sotoinpcb(so);
1178         KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
1179
1180         INP_INFO_WLOCK(pcbinfo);
1181         INP_WLOCK(inp);
1182         up = intoudpcb(inp);
1183         KASSERT(up != NULL, ("%s: up == NULL", __func__));
1184         in_pcbdetach(inp);
1185         in_pcbfree(inp);
1186         INP_INFO_WUNLOCK(pcbinfo);
1187         udp_discardcb(up);
1188 }
1189
1190 static int
1191 udp6_disconnect(struct socket *so)
1192 {
1193         struct inpcb *inp;
1194         struct inpcbinfo *pcbinfo;
1195         int error;
1196
1197         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1198         inp = sotoinpcb(so);
1199         KASSERT(inp != NULL, ("udp6_disconnect: inp == NULL"));
1200
1201         INP_WLOCK(inp);
1202 #ifdef INET
1203         if (inp->inp_vflag & INP_IPV4) {
1204                 struct pr_usrreqs *pru;
1205                 uint8_t nxt;
1206
1207                 nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ?
1208                     IPPROTO_UDP : IPPROTO_UDPLITE;
1209                 INP_WUNLOCK(inp);
1210                 pru = inetsw[ip_protox[nxt]].pr_usrreqs;
1211                 (void)(*pru->pru_disconnect)(so);
1212                 return (0);
1213         }
1214 #endif
1215
1216         if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
1217                 error = ENOTCONN;
1218                 goto out;
1219         }
1220
1221         INP_HASH_WLOCK(pcbinfo);
1222         in6_pcbdisconnect(inp);
1223         inp->in6p_laddr = in6addr_any;
1224         INP_HASH_WUNLOCK(pcbinfo);
1225         SOCK_LOCK(so);
1226         so->so_state &= ~SS_ISCONNECTED;                /* XXX */
1227         SOCK_UNLOCK(so);
1228 out:
1229         INP_WUNLOCK(inp);
1230         return (0);
1231 }
1232
1233 static int
1234 udp6_send(struct socket *so, int flags, struct mbuf *m,
1235     struct sockaddr *addr, struct mbuf *control, struct thread *td)
1236 {
1237         struct inpcb *inp;
1238         struct inpcbinfo *pcbinfo;
1239         int error = 0;
1240
1241         pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
1242         inp = sotoinpcb(so);
1243         KASSERT(inp != NULL, ("udp6_send: inp == NULL"));
1244
1245         INP_WLOCK(inp);
1246         if (addr) {
1247                 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
1248                         error = EINVAL;
1249                         goto bad;
1250                 }
1251                 if (addr->sa_family != AF_INET6) {
1252                         error = EAFNOSUPPORT;
1253                         goto bad;
1254                 }
1255         }
1256
1257 #ifdef INET
1258         if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
1259                 int hasv4addr;
1260                 struct sockaddr_in6 *sin6 = NULL;
1261
1262                 if (addr == NULL)
1263                         hasv4addr = (inp->inp_vflag & INP_IPV4);
1264                 else {
1265                         sin6 = (struct sockaddr_in6 *)addr;
1266                         hasv4addr = IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)
1267                             ? 1 : 0;
1268                 }
1269                 if (hasv4addr) {
1270                         struct pr_usrreqs *pru;
1271                         uint8_t nxt;
1272
1273                         nxt = (inp->inp_socket->so_proto->pr_protocol ==
1274                             IPPROTO_UDP) ? IPPROTO_UDP : IPPROTO_UDPLITE;
1275                         /*
1276                          * XXXRW: We release UDP-layer locks before calling
1277                          * udp_send() in order to avoid recursion.  However,
1278                          * this does mean there is a short window where inp's
1279                          * fields are unstable.  Could this lead to a
1280                          * potential race in which the factors causing us to
1281                          * select the UDPv4 output routine are invalidated?
1282                          */
1283                         INP_WUNLOCK(inp);
1284                         if (sin6)
1285                                 in6_sin6_2_sin_in_sock(addr);
1286                         pru = inetsw[ip_protox[nxt]].pr_usrreqs;
1287                         /* addr will just be freed in sendit(). */
1288                         return ((*pru->pru_send)(so, flags, m, addr, control,
1289                             td));
1290                 }
1291         }
1292 #endif
1293 #ifdef MAC
1294         mac_inpcb_create_mbuf(inp, m);
1295 #endif
1296         INP_HASH_WLOCK(pcbinfo);
1297         error = udp6_output(inp, m, addr, control, td);
1298         INP_HASH_WUNLOCK(pcbinfo);
1299         INP_WUNLOCK(inp);
1300         return (error);
1301
1302 bad:
1303         INP_WUNLOCK(inp);
1304         m_freem(m);
1305         return (error);
1306 }
1307
1308 struct pr_usrreqs udp6_usrreqs = {
1309         .pru_abort =            udp6_abort,
1310         .pru_attach =           udp6_attach,
1311         .pru_bind =             udp6_bind,
1312         .pru_connect =          udp6_connect,
1313         .pru_control =          in6_control,
1314         .pru_detach =           udp6_detach,
1315         .pru_disconnect =       udp6_disconnect,
1316         .pru_peeraddr =         in6_mapped_peeraddr,
1317         .pru_send =             udp6_send,
1318         .pru_shutdown =         udp_shutdown,
1319         .pru_sockaddr =         in6_mapped_sockaddr,
1320         .pru_soreceive =        soreceive_dgram,
1321         .pru_sosend =           sosend_dgram,
1322         .pru_sosetlabel =       in_pcbsosetlabel,
1323         .pru_close =            udp6_close
1324 };