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