udp: Dispatch UDP datagrams to the correct netisr to perform ip_output()
[dragonfly.git] / sys / netinet / udp_usrreq.c
1 /*
2  * Copyright (c) 2004 Jeffrey M. Hsu.  All rights reserved.
3  * Copyright (c) 2004 The DragonFly Project.  All rights reserved.
4  *
5  * This code is derived from software contributed to The DragonFly Project
6  * by Jeffrey M. Hsu.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of The DragonFly Project nor the names of its
17  *    contributors may be used to endorse or promote products derived
18  *    from this software without specific, prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
36  *      The Regents of the University of California.  All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. Neither the name of the University nor the names of its contributors
47  *    may be used to endorse or promote products derived from this software
48  *    without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60  * SUCH DAMAGE.
61  *
62  *      @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95
63  * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.64.2.18 2003/01/24 05:11:34 sam Exp $
64  */
65
66 #include "opt_ipsec.h"
67 #include "opt_inet6.h"
68
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/kernel.h>
72 #include <sys/malloc.h>
73 #include <sys/mbuf.h>
74 #include <sys/domain.h>
75 #include <sys/proc.h>
76 #include <sys/priv.h>
77 #include <sys/protosw.h>
78 #include <sys/socket.h>
79 #include <sys/socketvar.h>
80 #include <sys/sysctl.h>
81 #include <sys/syslog.h>
82 #include <sys/in_cksum.h>
83 #include <sys/ktr.h>
84
85 #include <sys/thread2.h>
86 #include <sys/socketvar2.h>
87 #include <sys/serialize.h>
88
89 #include <machine/stdarg.h>
90
91 #include <net/if.h>
92 #include <net/route.h>
93 #include <net/netmsg2.h>
94 #include <net/netisr2.h>
95
96 #include <netinet/in.h>
97 #include <netinet/in_systm.h>
98 #include <netinet/ip.h>
99 #ifdef INET6
100 #include <netinet/ip6.h>
101 #endif
102 #include <netinet/in_pcb.h>
103 #include <netinet/in_var.h>
104 #include <netinet/ip_var.h>
105 #ifdef INET6
106 #include <netinet6/ip6_var.h>
107 #endif
108 #include <netinet/ip_icmp.h>
109 #include <netinet/icmp_var.h>
110 #include <netinet/udp.h>
111 #include <netinet/udp_var.h>
112
113 #ifdef FAST_IPSEC
114 #include <netproto/ipsec/ipsec.h>
115 #endif
116
117 #ifdef IPSEC
118 #include <netinet6/ipsec.h>
119 #endif
120
121 #define UDP_KTR_STRING          "inp=%p"
122 #define UDP_KTR_ARGS            struct inpcb *inp
123
124 #ifndef KTR_UDP
125 #define KTR_UDP                 KTR_ALL
126 #endif
127
128 KTR_INFO_MASTER(udp);
129 KTR_INFO(KTR_UDP, udp, send_beg, 0, UDP_KTR_STRING, UDP_KTR_ARGS);
130 KTR_INFO(KTR_UDP, udp, send_end, 1, UDP_KTR_STRING, UDP_KTR_ARGS);
131 KTR_INFO(KTR_UDP, udp, send_ipout, 2, UDP_KTR_STRING, UDP_KTR_ARGS);
132 KTR_INFO(KTR_UDP, udp, redisp_ipout_beg, 3, UDP_KTR_STRING, UDP_KTR_ARGS);
133 KTR_INFO(KTR_UDP, udp, redisp_ipout_end, 4, UDP_KTR_STRING, UDP_KTR_ARGS);
134 KTR_INFO(KTR_UDP, udp, send_redisp, 5, UDP_KTR_STRING, UDP_KTR_ARGS);
135
136 #define logudp(name, inp)       KTR_LOG(udp_##name, inp)
137
138 /*
139  * UDP protocol implementation.
140  * Per RFC 768, August, 1980.
141  */
142 #ifndef COMPAT_42
143 static int      udpcksum = 1;
144 #else
145 static int      udpcksum = 0;           /* XXX */
146 #endif
147 SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW,
148     &udpcksum, 0, "Enable checksumming of UDP packets");
149
150 int     log_in_vain = 0;
151 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW,
152     &log_in_vain, 0, "Log all incoming UDP packets");
153
154 static int      blackhole = 0;
155 SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW,
156         &blackhole, 0, "Do not send port unreachables for refused connects");
157
158 static int      strict_mcast_mship = 1;
159 SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
160         &strict_mcast_mship, 0, "Only send multicast to member sockets");
161
162 int     udp_sosend_async = 1;
163 SYSCTL_INT(_net_inet_udp, OID_AUTO, sosend_async, CTLFLAG_RW,
164         &udp_sosend_async, 0, "UDP asynchronized pru_send");
165
166 int     udp_sosend_prepend = 1;
167 SYSCTL_INT(_net_inet_udp, OID_AUTO, sosend_prepend, CTLFLAG_RW,
168         &udp_sosend_prepend, 0,
169         "Prepend enough space for proto and link header in pru_send");
170
171 static int udp_reuseport_ext = 1;
172 SYSCTL_INT(_net_inet_udp, OID_AUTO, reuseport_ext, CTLFLAG_RW,
173         &udp_reuseport_ext, 0, "SO_REUSEPORT extension");
174
175 struct  inpcbinfo udbinfo;
176 struct  inpcbportinfo udbportinfo;
177
178 static struct netisr_barrier *udbinfo_br;
179 static struct lwkt_serialize udbinfo_slize = LWKT_SERIALIZE_INITIALIZER;
180
181 #ifndef UDBHASHSIZE
182 #define UDBHASHSIZE 16
183 #endif
184
185 struct  udpstat udpstat_percpu[MAXCPU] __cachealign;
186
187 #ifdef INET6
188 struct udp_in6 {
189         struct sockaddr_in6     uin6_sin;
190         u_char                  uin6_init_done : 1;
191 };
192 struct udp_ip6 {
193         struct ip6_hdr          uip6_ip6;
194         u_char                  uip6_init_done : 1;
195 };
196 #else
197 struct udp_in6;
198 struct udp_ip6;
199 #endif /* INET6 */
200
201 static void udp_append (struct inpcb *last, struct ip *ip,
202     struct mbuf *n, int off, struct sockaddr_in *udp_in,
203     struct udp_in6 *, struct udp_ip6 *);
204 #ifdef INET6
205 static void ip_2_ip6_hdr (struct ip6_hdr *ip6, struct ip *ip);
206 #endif
207
208 static int udp_connect_oncpu(struct socket *so, struct thread *td,
209                         struct sockaddr_in *sin, struct sockaddr_in *if_sin);
210
211 void
212 udp_init(void)
213 {
214         int cpu;
215
216         in_pcbinfo_init(&udbinfo);
217         in_pcbportinfo_init(&udbportinfo, UDBHASHSIZE, FALSE, 0);
218
219         udbinfo.hashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.hashmask);
220         udbinfo.portinfo = &udbportinfo;
221         udbinfo.wildcardhashbase = hashinit(UDBHASHSIZE, M_PCB,
222                                             &udbinfo.wildcardhashmask);
223         udbinfo.localgrphashbase = hashinit(UDBHASHSIZE, M_PCB,
224                                             &udbinfo.localgrphashmask);
225         udbinfo.ipi_size = sizeof(struct inpcb);
226
227         udbinfo_br = netisr_barrier_create();
228
229         /*
230          * Initialize UDP statistics counters for each CPU.
231          */
232         for (cpu = 0; cpu < ncpus; ++cpu)
233                 bzero(&udpstat_percpu[cpu], sizeof(struct udpstat));
234 }
235
236 static int
237 sysctl_udpstat(SYSCTL_HANDLER_ARGS)
238 {
239         int cpu, error = 0;
240
241         for (cpu = 0; cpu < ncpus; ++cpu) {
242                 if ((error = SYSCTL_OUT(req, &udpstat_percpu[cpu],
243                                         sizeof(struct udpstat))))
244                         break;
245                 if ((error = SYSCTL_IN(req, &udpstat_percpu[cpu],
246                                        sizeof(struct udpstat))))
247                         break;
248         }
249
250         return (error);
251 }
252 SYSCTL_PROC(_net_inet_udp, UDPCTL_STATS, stats, (CTLTYPE_OPAQUE | CTLFLAG_RW),
253     0, 0, sysctl_udpstat, "S,udpstat", "UDP statistics");
254
255 /*
256  * Check multicast packets to make sure they are only sent to sockets with
257  * multicast memberships for the packet's destination address and arrival
258  * interface.  Multicast packets to multicast-unaware sockets are also
259  * disallowed.
260  *
261  * Returns 0 if the packet is acceptable, -1 if it is not.
262  */
263 static __inline int
264 check_multicast_membership(struct ip *ip, struct inpcb *inp, struct mbuf *m)
265 {
266         int mshipno;
267         struct ip_moptions *mopt;
268
269         if (strict_mcast_mship == 0 ||
270             !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
271                 return (0);
272         }
273         mopt = inp->inp_moptions;
274         if (mopt == NULL)
275                 return (-1);
276         for (mshipno = 0; mshipno < mopt->imo_num_memberships; ++mshipno) {
277                 struct in_multi *maddr = mopt->imo_membership[mshipno];
278
279                 if (ip->ip_dst.s_addr == maddr->inm_addr.s_addr &&
280                     m->m_pkthdr.rcvif == maddr->inm_ifp) {
281                         return (0);
282                 }
283         }
284         return (-1);
285 }
286
287 int
288 udp_input(struct mbuf **mp, int *offp, int proto)
289 {
290         struct sockaddr_in udp_in = { sizeof udp_in, AF_INET };
291 #ifdef INET6
292         struct udp_in6 udp_in6 = {
293                 { sizeof udp_in6.uin6_sin, AF_INET6 }, 0
294         };
295         struct udp_ip6 udp_ip6;
296 #endif
297
298         int iphlen;
299         struct ip *ip;
300         struct udphdr *uh;
301         struct inpcb *inp;
302         struct mbuf *m;
303         struct mbuf *opts = NULL;
304         int len, off;
305         struct ip save_ip;
306         struct sockaddr *append_sa;
307
308         off = *offp;
309         m = *mp;
310         *mp = NULL;
311
312         iphlen = off;
313         udp_stat.udps_ipackets++;
314
315         /*
316          * Strip IP options, if any; should skip this,
317          * make available to user, and use on returned packets,
318          * but we don't yet have a way to check the checksum
319          * with options still present.
320          */
321         if (iphlen > sizeof(struct ip)) {
322                 ip_stripoptions(m);
323                 iphlen = sizeof(struct ip);
324         }
325
326         /*
327          * IP and UDP headers are together in first mbuf.
328          * Already checked and pulled up in ip_demux().
329          */
330         KASSERT(m->m_len >= iphlen + sizeof(struct udphdr),
331             ("UDP header not in one mbuf"));
332
333         ip = mtod(m, struct ip *);
334         uh = (struct udphdr *)((caddr_t)ip + iphlen);
335
336         /* destination port of 0 is illegal, based on RFC768. */
337         if (uh->uh_dport == 0)
338                 goto bad;
339
340         /*
341          * Make mbuf data length reflect UDP length.
342          * If not enough data to reflect UDP length, drop.
343          */
344         len = ntohs((u_short)uh->uh_ulen);
345         if (ip->ip_len != len) {
346                 if (len > ip->ip_len || len < sizeof(struct udphdr)) {
347                         udp_stat.udps_badlen++;
348                         goto bad;
349                 }
350                 m_adj(m, len - ip->ip_len);
351                 /* ip->ip_len = len; */
352         }
353         /*
354          * Save a copy of the IP header in case we want restore it
355          * for sending an ICMP error message in response.
356          */
357         save_ip = *ip;
358
359         /*
360          * Checksum extended UDP header and data.
361          */
362         if (uh->uh_sum) {
363                 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
364                         if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
365                                 uh->uh_sum = m->m_pkthdr.csum_data;
366                         else
367                                 uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
368                                     ip->ip_dst.s_addr, htonl((u_short)len +
369                                     m->m_pkthdr.csum_data + IPPROTO_UDP));
370                         uh->uh_sum ^= 0xffff;
371                 } else {
372                         char b[9];
373
374                         bcopy(((struct ipovly *)ip)->ih_x1, b, 9);
375                         bzero(((struct ipovly *)ip)->ih_x1, 9);
376                         ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
377                         uh->uh_sum = in_cksum(m, len + sizeof(struct ip));
378                         bcopy(b, ((struct ipovly *)ip)->ih_x1, 9);
379                 }
380                 if (uh->uh_sum) {
381                         udp_stat.udps_badsum++;
382                         m_freem(m);
383                         return(IPPROTO_DONE);
384                 }
385         } else
386                 udp_stat.udps_nosum++;
387
388         if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
389             in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
390                 struct inpcb *last;
391
392                 /*
393                  * Deliver a multicast or broadcast datagram to *all* sockets
394                  * for which the local and remote addresses and ports match
395                  * those of the incoming datagram.  This allows more than
396                  * one process to receive multi/broadcasts on the same port.
397                  * (This really ought to be done for unicast datagrams as
398                  * well, but that would cause problems with existing
399                  * applications that open both address-specific sockets and
400                  * a wildcard socket listening to the same port -- they would
401                  * end up receiving duplicates of every unicast datagram.
402                  * Those applications open the multiple sockets to overcome an
403                  * inadequacy of the UDP socket interface, but for backwards
404                  * compatibility we avoid the problem here rather than
405                  * fixing the interface.  Maybe 4.5BSD will remedy this?)
406                  */
407
408                 /*
409                  * Construct sockaddr format source address.
410                  */
411                 udp_in.sin_port = uh->uh_sport;
412                 udp_in.sin_addr = ip->ip_src;
413                 /*
414                  * Locate pcb(s) for datagram.
415                  * (Algorithm copied from raw_intr().)
416                  */
417                 last = NULL;
418 #ifdef INET6
419                 udp_in6.uin6_init_done = udp_ip6.uip6_init_done = 0;
420 #endif
421                 LIST_FOREACH(inp, &udbinfo.pcblisthead, inp_list) {
422                         KKASSERT((inp->inp_flags & INP_PLACEMARKER) == 0);
423 #ifdef INET6
424                         if (!(inp->inp_vflag & INP_IPV4))
425                                 continue;
426 #endif
427                         if (inp->inp_lport != uh->uh_dport)
428                                 continue;
429                         if (inp->inp_laddr.s_addr != INADDR_ANY) {
430                                 if (inp->inp_laddr.s_addr !=
431                                     ip->ip_dst.s_addr)
432                                         continue;
433                         }
434                         if (inp->inp_faddr.s_addr != INADDR_ANY) {
435                                 if (inp->inp_faddr.s_addr !=
436                                     ip->ip_src.s_addr ||
437                                     inp->inp_fport != uh->uh_sport)
438                                         continue;
439                         }
440
441                         if (check_multicast_membership(ip, inp, m) < 0)
442                                 continue;
443
444                         if (last != NULL) {
445                                 struct mbuf *n;
446
447 #ifdef IPSEC
448                                 /* check AH/ESP integrity. */
449                                 if (ipsec4_in_reject_so(m, last->inp_socket))
450                                         ipsecstat.in_polvio++;
451                                         /* do not inject data to pcb */
452                                 else
453 #endif /*IPSEC*/
454 #ifdef FAST_IPSEC
455                                 /* check AH/ESP integrity. */
456                                 if (ipsec4_in_reject(m, last))
457                                         ;
458                                 else
459 #endif /*FAST_IPSEC*/
460                                 if ((n = m_copypacket(m, MB_DONTWAIT)) != NULL)
461                                         udp_append(last, ip, n,
462                                             iphlen + sizeof(struct udphdr),
463                                             &udp_in,
464 #ifdef INET6
465                                             &udp_in6, &udp_ip6
466 #else
467                                             NULL, NULL
468 #endif
469                                             );
470                         }
471                         last = inp;
472                         /*
473                          * Don't look for additional matches if this one does
474                          * not have either the SO_REUSEPORT or SO_REUSEADDR
475                          * socket options set.  This heuristic avoids searching
476                          * through all pcbs in the common case of a non-shared
477                          * port.  It * assumes that an application will never
478                          * clear these options after setting them.
479                          */
480                         if (!(last->inp_socket->so_options &
481                             (SO_REUSEPORT | SO_REUSEADDR)))
482                                 break;
483                 }
484
485                 if (last == NULL) {
486                         /*
487                          * No matching pcb found; discard datagram.
488                          * (No need to send an ICMP Port Unreachable
489                          * for a broadcast or multicast datgram.)
490                          */
491                         udp_stat.udps_noportbcast++;
492                         goto bad;
493                 }
494 #ifdef IPSEC
495                 /* check AH/ESP integrity. */
496                 if (ipsec4_in_reject_so(m, last->inp_socket)) {
497                         ipsecstat.in_polvio++;
498                         goto bad;
499                 }
500 #endif /*IPSEC*/
501 #ifdef FAST_IPSEC
502                 /* check AH/ESP integrity. */
503                 if (ipsec4_in_reject(m, last))
504                         goto bad;
505 #endif /*FAST_IPSEC*/
506                 udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
507                     &udp_in,
508 #ifdef INET6
509                     &udp_in6, &udp_ip6
510 #else
511                     NULL, NULL
512 #endif
513                     );
514                 return(IPPROTO_DONE);
515         }
516         /*
517          * Locate pcb for datagram.
518          */
519         inp = in_pcblookup_pkthash(&udbinfo, ip->ip_src, uh->uh_sport,
520             ip->ip_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif,
521             udp_reuseport_ext ? m : NULL);
522         if (inp == NULL) {
523                 if (log_in_vain) {
524                         char buf[sizeof "aaa.bbb.ccc.ddd"];
525
526                         strcpy(buf, inet_ntoa(ip->ip_dst));
527                         log(LOG_INFO,
528                             "Connection attempt to UDP %s:%d from %s:%d\n",
529                             buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src),
530                             ntohs(uh->uh_sport));
531                 }
532                 udp_stat.udps_noport++;
533                 if (m->m_flags & (M_BCAST | M_MCAST)) {
534                         udp_stat.udps_noportbcast++;
535                         goto bad;
536                 }
537                 if (blackhole)
538                         goto bad;
539 #ifdef ICMP_BANDLIM
540                 if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0)
541                         goto bad;
542 #endif
543                 *ip = save_ip;
544                 ip->ip_len += iphlen;
545                 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
546                 return(IPPROTO_DONE);
547         }
548 #ifdef IPSEC
549         if (ipsec4_in_reject_so(m, inp->inp_socket)) {
550                 ipsecstat.in_polvio++;
551                 goto bad;
552         }
553 #endif /*IPSEC*/
554 #ifdef FAST_IPSEC
555         if (ipsec4_in_reject(m, inp))
556                 goto bad;
557 #endif /*FAST_IPSEC*/
558         /*
559          * Check the minimum TTL for socket.
560          */
561         if (ip->ip_ttl < inp->inp_ip_minttl)
562                 goto bad;
563
564         /*
565          * Construct sockaddr format source address.
566          * Stuff source address and datagram in user buffer.
567          */
568         udp_in.sin_port = uh->uh_sport;
569         udp_in.sin_addr = ip->ip_src;
570         if ((inp->inp_flags & INP_CONTROLOPTS) ||
571             (inp->inp_socket->so_options & SO_TIMESTAMP)) {
572 #ifdef INET6
573                 if (inp->inp_vflag & INP_IPV6) {
574                         int savedflags;
575
576                         ip_2_ip6_hdr(&udp_ip6.uip6_ip6, ip);
577                         savedflags = inp->inp_flags;
578                         inp->inp_flags &= ~INP_UNMAPPABLEOPTS;
579                         ip6_savecontrol(inp, &opts, &udp_ip6.uip6_ip6, m);
580                         inp->inp_flags = savedflags;
581                 } else
582 #endif
583                 ip_savecontrol(inp, &opts, ip, m);
584         }
585         m_adj(m, iphlen + sizeof(struct udphdr));
586 #ifdef INET6
587         if (inp->inp_vflag & INP_IPV6) {
588                 in6_sin_2_v4mapsin6(&udp_in, &udp_in6.uin6_sin);
589                 append_sa = (struct sockaddr *)&udp_in6;
590         } else
591 #endif
592                 append_sa = (struct sockaddr *)&udp_in;
593
594         lwkt_gettoken(&inp->inp_socket->so_rcv.ssb_token);
595         if (ssb_appendaddr(&inp->inp_socket->so_rcv, append_sa, m, opts) == 0) {
596                 udp_stat.udps_fullsock++;
597                 lwkt_reltoken(&inp->inp_socket->so_rcv.ssb_token);
598                 goto bad;
599         }
600         lwkt_reltoken(&inp->inp_socket->so_rcv.ssb_token);
601         sorwakeup(inp->inp_socket);
602         return(IPPROTO_DONE);
603 bad:
604         m_freem(m);
605         if (opts)
606                 m_freem(opts);
607         return(IPPROTO_DONE);
608 }
609
610 #ifdef INET6
611 static void
612 ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
613 {
614         bzero(ip6, sizeof *ip6);
615
616         ip6->ip6_vfc = IPV6_VERSION;
617         ip6->ip6_plen = ip->ip_len;
618         ip6->ip6_nxt = ip->ip_p;
619         ip6->ip6_hlim = ip->ip_ttl;
620         ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] =
621                 IPV6_ADDR_INT32_SMP;
622         ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
623         ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
624 }
625 #endif
626
627 /*
628  * subroutine of udp_input(), mainly for source code readability.
629  * caller must properly init udp_ip6 and udp_in6 beforehand.
630  */
631 static void
632 udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, int off,
633     struct sockaddr_in *udp_in,
634     struct udp_in6 *udp_in6, struct udp_ip6 *udp_ip6)
635 {
636         struct sockaddr *append_sa;
637         struct mbuf *opts = NULL;
638
639         if (last->inp_flags & INP_CONTROLOPTS ||
640             last->inp_socket->so_options & SO_TIMESTAMP) {
641 #ifdef INET6
642                 if (last->inp_vflag & INP_IPV6) {
643                         int savedflags;
644
645                         if (udp_ip6->uip6_init_done == 0) {
646                                 ip_2_ip6_hdr(&udp_ip6->uip6_ip6, ip);
647                                 udp_ip6->uip6_init_done = 1;
648                         }
649                         savedflags = last->inp_flags;
650                         last->inp_flags &= ~INP_UNMAPPABLEOPTS;
651                         ip6_savecontrol(last, &opts, &udp_ip6->uip6_ip6, n);
652                         last->inp_flags = savedflags;
653                 } else
654 #endif
655                 ip_savecontrol(last, &opts, ip, n);
656         }
657 #ifdef INET6
658         if (last->inp_vflag & INP_IPV6) {
659                 if (udp_in6->uin6_init_done == 0) {
660                         in6_sin_2_v4mapsin6(udp_in, &udp_in6->uin6_sin);
661                         udp_in6->uin6_init_done = 1;
662                 }
663                 append_sa = (struct sockaddr *)&udp_in6->uin6_sin;
664         } else
665 #endif
666                 append_sa = (struct sockaddr *)udp_in;
667         m_adj(n, off);
668         lwkt_gettoken(&last->inp_socket->so_rcv.ssb_token);
669         if (ssb_appendaddr(&last->inp_socket->so_rcv, append_sa, n, opts) == 0) {
670                 m_freem(n);
671                 if (opts)
672                         m_freem(opts);
673                 udp_stat.udps_fullsock++;
674         } else {
675                 sorwakeup(last->inp_socket);
676         }
677         lwkt_reltoken(&last->inp_socket->so_rcv.ssb_token);
678 }
679
680 /*
681  * Notify a udp user of an asynchronous error;
682  * just wake up so that he can collect error status.
683  */
684 void
685 udp_notify(struct inpcb *inp, int error)
686 {
687         inp->inp_socket->so_error = error;
688         sorwakeup(inp->inp_socket);
689         sowwakeup(inp->inp_socket);
690 }
691
692 struct netmsg_udp_notify {
693         struct netmsg_base base;
694         void            (*nm_notify)(struct inpcb *, int);
695         struct in_addr  nm_faddr;
696         int             nm_arg;
697 };
698
699 static void
700 udp_notifyall_oncpu(netmsg_t msg)
701 {
702         struct netmsg_udp_notify *nm = (struct netmsg_udp_notify *)msg;
703 #if 0
704         int nextcpu;
705 #endif
706
707         in_pcbnotifyall(&udbinfo.pcblisthead, nm->nm_faddr,
708                         nm->nm_arg, nm->nm_notify);
709         lwkt_replymsg(&nm->base.lmsg, 0);
710
711 #if 0
712         /* XXX currently udp only runs on cpu 0 */
713         nextcpu = mycpuid + 1;
714         if (nextcpu < ncpus2)
715                 lwkt_forwardmsg(netisr_cpuport(nextcpu), &nm->base.lmsg);
716         else
717                 lwkt_replymsg(&nmsg->base.lmsg, 0);
718 #endif
719 }
720
721 static void
722 udp_rtchange(struct inpcb *inp, int err)
723 {
724         /* XXX Nuke this, once UDP inpcbs are CPU localized */
725         if (inp->inp_route.ro_rt && inp->inp_route.ro_rt->rt_cpuid == mycpuid) {
726                 rtfree(inp->inp_route.ro_rt);
727                 inp->inp_route.ro_rt = NULL;
728                 /*
729                  * A new route can be allocated the next time
730                  * output is attempted.
731                  */
732         }
733 }
734
735 void
736 udp_ctlinput(netmsg_t msg)
737 {
738         struct sockaddr *sa = msg->ctlinput.nm_arg;
739         struct ip *ip = msg->ctlinput.nm_extra;
740         int cmd = msg->ctlinput.nm_cmd;
741         struct udphdr *uh;
742         void (*notify) (struct inpcb *, int) = udp_notify;
743         struct in_addr faddr;
744         struct inpcb *inp;
745
746         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
747
748         faddr = ((struct sockaddr_in *)sa)->sin_addr;
749         if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
750                 goto done;
751
752         if (PRC_IS_REDIRECT(cmd)) {
753                 ip = NULL;
754                 notify = udp_rtchange;
755         } else if (cmd == PRC_HOSTDEAD) {
756                 ip = NULL;
757         } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
758                 goto done;
759         }
760
761         if (ip) {
762                 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
763                 inp = in_pcblookup_hash(&udbinfo, faddr, uh->uh_dport,
764                                         ip->ip_src, uh->uh_sport, 0, NULL);
765                 if (inp != NULL && inp->inp_socket != NULL)
766                         (*notify)(inp, inetctlerrmap[cmd]);
767         } else if (PRC_IS_REDIRECT(cmd)) {
768                 struct netmsg_udp_notify *nm;
769
770                 KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
771                 nm = kmalloc(sizeof(*nm), M_LWKTMSG, M_INTWAIT);
772                 netmsg_init(&nm->base, NULL, &netisr_afree_rport,
773                             0, udp_notifyall_oncpu);
774                 nm->nm_faddr = faddr;
775                 nm->nm_arg = inetctlerrmap[cmd];
776                 nm->nm_notify = notify;
777                 lwkt_sendmsg(netisr_cpuport(0), &nm->base.lmsg);
778         } else {
779                 /*
780                  * XXX We should forward msg upon PRC_HOSTHEAD and ip == NULL,
781                  * once UDP inpcbs are CPU localized
782                  */
783                 KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
784                 in_pcbnotifyall(&udbinfo.pcblisthead, faddr, inetctlerrmap[cmd],
785                                 notify);
786         }
787 done:
788         lwkt_replymsg(&msg->lmsg, 0);
789 }
790
791 static int
792 udp_pcblist(SYSCTL_HANDLER_ARGS)
793 {
794         struct xinpcb *xi;
795         int error, nxi, i;
796
797         udbinfo_lock();
798         error = in_pcblist_global_nomarker(oidp, arg1, arg2, req, &xi, &nxi);
799         udbinfo_unlock();
800
801         if (error) {
802                 KKASSERT(xi == NULL);
803                 return error;
804         }
805         if (nxi == 0) {
806                 KKASSERT(xi == NULL);
807                 return 0;
808         }
809
810         for (i = 0; i < nxi; ++i) {
811                 error = SYSCTL_OUT(req, &xi[i], sizeof(xi[i]));
812                 if (error)
813                         break;
814         }
815         kfree(xi, M_TEMP);
816
817         return error;
818 }
819 SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, &udbinfo, 0,
820             udp_pcblist, "S,xinpcb", "List of active UDP sockets");
821
822 static int
823 udp_getcred(SYSCTL_HANDLER_ARGS)
824 {
825         struct sockaddr_in addrs[2];
826         struct ucred cred0, *cred = NULL;
827         struct inpcb *inp;
828         int error;
829
830         error = priv_check(req->td, PRIV_ROOT);
831         if (error)
832                 return (error);
833         error = SYSCTL_IN(req, addrs, sizeof addrs);
834         if (error)
835                 return (error);
836
837         udbinfo_lock();
838         inp = in_pcblookup_hash(&udbinfo, addrs[1].sin_addr, addrs[1].sin_port,
839                                 addrs[0].sin_addr, addrs[0].sin_port, 1, NULL);
840         if (inp == NULL || inp->inp_socket == NULL) {
841                 error = ENOENT;
842         } else {
843                 if (inp->inp_socket->so_cred != NULL) {
844                         cred0 = *(inp->inp_socket->so_cred);
845                         cred = &cred0;
846                 }
847         }
848         udbinfo_unlock();
849
850         if (error)
851                 return error;
852
853         return SYSCTL_OUT(req, cred, sizeof(struct ucred));
854 }
855
856 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
857     0, 0, udp_getcred, "S,ucred", "Get the ucred of a UDP connection");
858
859 static void
860 udp_send_redispatch(netmsg_t msg)
861 {
862         struct mbuf *m = msg->send.nm_m;
863         int pru_flags = msg->send.nm_flags;
864         struct inpcb *inp = msg->send.base.nm_so->so_pcb;
865         struct mbuf *m_opt = msg->send.nm_control; /* XXX save ipopt */
866         int flags = msg->send.nm_priv; /* ip_output flags */
867         int error;
868
869         logudp(redisp_ipout_beg, inp);
870
871         /*
872          * - Don't use inp route cache.  It should only be used in the
873          *   inp owner netisr.
874          * - Access to inp_moptions should be safe, since multicast UDP
875          *   datagrams are redispatched to netisr0 and inp_moptions is
876          *   changed only in netisr0.
877          */
878         error = ip_output(m, m_opt, NULL, flags, inp->inp_moptions, inp);
879         if ((pru_flags & PRUS_NOREPLY) == 0)
880                 lwkt_replymsg(&msg->send.base.lmsg, error);
881
882         if (m_opt != NULL) {
883                 /* Free saved ip options, if any */
884                 m_freem(m_opt);
885         }
886
887         logudp(redisp_ipout_end, inp);
888 }
889
890 static void
891 udp_send(netmsg_t msg)
892 {
893         struct socket *so = msg->send.base.nm_so;
894         struct mbuf *m = msg->send.nm_m;
895         struct sockaddr *dstaddr = msg->send.nm_addr;
896         int pru_flags = msg->send.nm_flags;
897         struct inpcb *inp = so->so_pcb;
898         struct thread *td = msg->send.nm_td;
899         int flags;
900
901         struct udpiphdr *ui;
902         int len = m->m_pkthdr.len;
903         struct sockaddr_in *sin;        /* really is initialized before use */
904         int error = 0, cpu;
905
906         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
907         KKASSERT(msg->send.nm_control == NULL);
908
909         logudp(send_beg, inp);
910
911         if (inp == NULL) {
912                 error = EINVAL;
913                 goto release;
914         }
915
916         if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
917                 error = EMSGSIZE;
918                 goto release;
919         }
920
921         if (inp->inp_lport == 0) {      /* unbound socket */
922                 error = in_pcbbind(inp, NULL, td);
923                 if (error)
924                         goto release;
925
926                 udbinfo_barrier_set();
927                 in_pcbinswildcardhash(inp);
928                 udbinfo_barrier_rem();
929         }
930
931         if (dstaddr != NULL) {          /* destination address specified */
932                 if (inp->inp_faddr.s_addr != INADDR_ANY) {
933                         /* already connected */
934                         error = EISCONN;
935                         goto release;
936                 }
937                 sin = (struct sockaddr_in *)dstaddr;
938                 if (!prison_remote_ip(td, (struct sockaddr *)&sin)) {
939                         error = EAFNOSUPPORT; /* IPv6 only jail */
940                         goto release;
941                 }
942         } else {
943                 if (inp->inp_faddr.s_addr == INADDR_ANY) {
944                         /* no destination specified and not already connected */
945                         error = ENOTCONN;
946                         goto release;
947                 }
948                 sin = NULL;
949         }
950
951         /*
952          * Calculate data length and get a mbuf
953          * for UDP and IP headers.
954          */
955         M_PREPEND(m, sizeof(struct udpiphdr), MB_DONTWAIT);
956         if (m == NULL) {
957                 error = ENOBUFS;
958                 goto release;
959         }
960
961         /*
962          * Fill in mbuf with extended UDP header
963          * and addresses and length put into network format.
964          */
965         ui = mtod(m, struct udpiphdr *);
966         bzero(ui->ui_x1, sizeof ui->ui_x1);     /* XXX still needed? */
967         ui->ui_pr = IPPROTO_UDP;
968
969         /*
970          * Set destination address.
971          */
972         if (dstaddr != NULL) {                  /* use specified destination */
973                 ui->ui_dst = sin->sin_addr;
974                 ui->ui_dport = sin->sin_port;
975         } else {                                /* use connected destination */
976                 ui->ui_dst = inp->inp_faddr;
977                 ui->ui_dport = inp->inp_fport;
978         }
979
980         /*
981          * Set source address.
982          */
983         if (inp->inp_laddr.s_addr == INADDR_ANY ||
984             IN_MULTICAST(ntohl(inp->inp_laddr.s_addr))) {
985                 struct sockaddr_in *if_sin;
986
987                 if (dstaddr == NULL) {  
988                         /*
989                          * connect() had (or should have) failed because
990                          * the interface had no IP address, but the
991                          * application proceeded to call send() anyways.
992                          */
993                         error = ENOTCONN;
994                         goto release;
995                 }
996
997                 /* Look up outgoing interface. */
998                 error = in_pcbladdr_find(inp, dstaddr, &if_sin, td, 1);
999                 if (error)
1000                         goto release;
1001                 ui->ui_src = if_sin->sin_addr;  /* use address of interface */
1002         } else {
1003                 ui->ui_src = inp->inp_laddr;    /* use non-null bound address */
1004         }
1005         ui->ui_sport = inp->inp_lport;
1006         KASSERT(inp->inp_lport != 0, ("inp lport should have been bound"));
1007
1008         /*
1009          * Release the original thread, since it is no longer used
1010          */
1011         if (pru_flags & PRUS_HELDTD) {
1012                 lwkt_rele(td);
1013                 pru_flags &= ~PRUS_HELDTD;
1014         }
1015         /*
1016          * Free the dest address, since it is no longer needed
1017          */
1018         if (pru_flags & PRUS_FREEADDR) {
1019                 kfree(dstaddr, M_SONAME);
1020                 pru_flags &= ~PRUS_FREEADDR;
1021         }
1022
1023         ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr));
1024
1025         /*
1026          * Set up checksum and output datagram.
1027          */
1028         if (udpcksum) {
1029                 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr,
1030                     htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
1031                 m->m_pkthdr.csum_flags = CSUM_UDP;
1032                 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
1033                 m->m_pkthdr.csum_thlen = sizeof(struct udphdr);
1034         } else {
1035                 ui->ui_sum = 0;
1036         }
1037         ((struct ip *)ui)->ip_len = sizeof(struct udpiphdr) + len;
1038         ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl;    /* XXX */
1039         ((struct ip *)ui)->ip_tos = inp->inp_ip_tos;    /* XXX */
1040         udp_stat.udps_opackets++;
1041
1042         flags = IP_DEBUGROUTE |
1043             (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST));
1044         if (pru_flags & PRUS_DONTROUTE)
1045                 flags |= SO_DONTROUTE;
1046
1047         cpu = udp_addrcpu_pkt(ui->ui_dst.s_addr, ui->ui_dport,
1048             ui->ui_src.s_addr, ui->ui_sport);
1049         if (cpu != mycpuid) {
1050                 struct mbuf *m_opt = NULL;
1051                 struct netmsg_pru_send *smsg;
1052                 struct lwkt_port *port = netisr_cpuport(cpu);
1053
1054                 /*
1055                  * Not on the CPU that matches this UDP datagram hash;
1056                  * redispatch to the correct CPU to do the ip_output().
1057                  */
1058                 if (inp->inp_options != NULL) {
1059                         /*
1060                          * If there are ip options, then save a copy,
1061                          * since accessing inp_options on other CPUs'
1062                          * is not safe.
1063                          *
1064                          * XXX optimize this?
1065                          */
1066                         m_opt = m_copym(inp->inp_options, 0, M_COPYALL,
1067                             MB_WAIT);
1068                 }
1069                 if ((pru_flags & PRUS_NOREPLY) == 0) {
1070                         /*
1071                          * Change some parts of the original netmsg and
1072                          * forward it to the target netisr.
1073                          *
1074                          * NOTE: so_port MUST NOT be checked in the target
1075                          * netisr.
1076                          */
1077                         smsg = &msg->send;
1078                         smsg->nm_priv = flags; /* ip_output flags */
1079                         smsg->nm_m = m;
1080                         smsg->nm_control = m_opt; /* XXX save ipopt */
1081                         smsg->base.lmsg.ms_flags |= MSGF_IGNSOPORT;
1082                         smsg->base.nm_dispatch = udp_send_redispatch;
1083                         lwkt_forwardmsg(port, &smsg->base.lmsg);
1084                 } else {
1085                         /*
1086                          * Recreate the netmsg, since the original mbuf
1087                          * could have been changed.  And send it to the
1088                          * target netisr.
1089                          *
1090                          * NOTE: so_port MUST NOT be checked in the target
1091                          * netisr.
1092                          */
1093                         smsg = &m->m_hdr.mh_sndmsg;
1094                         netmsg_init(&smsg->base, so, &netisr_apanic_rport,
1095                             MSGF_IGNSOPORT, udp_send_redispatch);
1096                         smsg->nm_priv = flags; /* ip_output flags */
1097                         smsg->nm_flags = pru_flags;
1098                         smsg->nm_m = m;
1099                         smsg->nm_control = m_opt; /* XXX save ipopt */
1100                         lwkt_sendmsg(port, &smsg->base.lmsg);
1101                 }
1102
1103                 /* This UDP datagram is redispatched; done */
1104                 logudp(send_redisp, inp);
1105                 return;
1106         }
1107
1108         logudp(send_ipout, inp);
1109         error = ip_output(m, inp->inp_options, &inp->inp_route, flags,
1110             inp->inp_moptions, inp);
1111         m = NULL;
1112
1113 release:
1114         if (m != NULL)
1115                 m_freem(m);
1116
1117         if (pru_flags & PRUS_HELDTD)
1118                 lwkt_rele(td);
1119         if (pru_flags & PRUS_FREEADDR)
1120                 kfree(dstaddr, M_SONAME);
1121         if ((pru_flags & PRUS_NOREPLY) == 0)
1122                 lwkt_replymsg(&msg->send.base.lmsg, error);
1123
1124         logudp(send_end, inp);
1125 }
1126
1127 u_long  udp_sendspace = 9216;           /* really max datagram size */
1128                                         /* 40 1K datagrams */
1129 SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
1130     &udp_sendspace, 0, "Maximum outgoing UDP datagram size");
1131
1132 u_long  udp_recvspace = 40 * (1024 +
1133 #ifdef INET6
1134                                       sizeof(struct sockaddr_in6)
1135 #else
1136                                       sizeof(struct sockaddr_in)
1137 #endif
1138                                       );
1139 SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
1140     &udp_recvspace, 0, "Maximum incoming UDP datagram size");
1141
1142 /*
1143  * NOTE: (so) is referenced from soabort*() and netmsg_pru_abort()
1144  *       will sofree() it when we return.
1145  */
1146 static void
1147 udp_abort(netmsg_t msg)
1148 {
1149         struct socket *so = msg->abort.base.nm_so;
1150         struct inpcb *inp;
1151         int error;
1152
1153         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1154
1155         inp = so->so_pcb;
1156         if (inp) {
1157                 soisdisconnected(so);
1158
1159                 udbinfo_barrier_set();
1160                 in_pcbdetach(inp);
1161                 udbinfo_barrier_rem();
1162                 error = 0;
1163         } else {
1164                 error = EINVAL;
1165         }
1166         lwkt_replymsg(&msg->abort.base.lmsg, error);
1167 }
1168
1169 static void
1170 udp_attach(netmsg_t msg)
1171 {
1172         struct socket *so = msg->attach.base.nm_so;
1173         struct pru_attach_info *ai = msg->attach.nm_ai;
1174         struct inpcb *inp;
1175         int error;
1176
1177         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1178
1179         inp = so->so_pcb;
1180         if (inp != NULL) {
1181                 error = EINVAL;
1182                 goto out;
1183         }
1184         error = soreserve(so, udp_sendspace, udp_recvspace, ai->sb_rlimit);
1185         if (error)
1186                 goto out;
1187
1188         udbinfo_barrier_set();
1189         error = in_pcballoc(so, &udbinfo);
1190         udbinfo_barrier_rem();
1191
1192         if (error)
1193                 goto out;
1194
1195         /*
1196          * Set default port for protocol processing prior to bind/connect.
1197          */
1198         sosetport(so, netisr_cpuport(0));
1199
1200         inp = (struct inpcb *)so->so_pcb;
1201         inp->inp_vflag |= INP_IPV4;
1202         inp->inp_ip_ttl = ip_defttl;
1203         error = 0;
1204 out:
1205         lwkt_replymsg(&msg->attach.base.lmsg, error);
1206 }
1207
1208 static void
1209 udp_bind(netmsg_t msg)
1210 {
1211         struct socket *so = msg->bind.base.nm_so;
1212         struct sockaddr *nam = msg->bind.nm_nam;
1213         struct thread *td = msg->bind.nm_td;
1214         struct sockaddr_in *sin = (struct sockaddr_in *)nam;
1215         struct inpcb *inp;
1216         int error;
1217
1218         inp = so->so_pcb;
1219         if (inp) {
1220                 error = in_pcbbind(inp, nam, td);
1221                 if (error == 0) {
1222                         if (sin->sin_addr.s_addr != INADDR_ANY)
1223                                 inp->inp_flags |= INP_WASBOUND_NOTANY;
1224
1225                         udbinfo_barrier_set();
1226                         in_pcbinswildcardhash(inp);
1227                         udbinfo_barrier_rem();
1228                 }
1229         } else {
1230                 error = EINVAL;
1231         }
1232         lwkt_replymsg(&msg->bind.base.lmsg, error);
1233 }
1234
1235 static void
1236 udp_connect(netmsg_t msg)
1237 {
1238         struct socket *so = msg->connect.base.nm_so;
1239         struct sockaddr *nam = msg->connect.nm_nam;
1240         struct thread *td = msg->connect.nm_td;
1241         struct inpcb *inp;
1242         struct sockaddr_in *sin = (struct sockaddr_in *)nam;
1243         struct sockaddr_in *if_sin;
1244         lwkt_port_t port;
1245         int error;
1246
1247         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1248
1249         inp = so->so_pcb;
1250         if (inp == NULL) {
1251                 error = EINVAL;
1252                 goto out;
1253         }
1254
1255         if (msg->connect.nm_flags & PRUC_RECONNECT) {
1256                 panic("UDP does not support RECONNECT");
1257 #ifdef notyet
1258                 msg->connect.nm_flags &= ~PRUC_RECONNECT;
1259                 in_pcblink(inp, &udbinfo);
1260 #endif
1261         }
1262
1263         if (inp->inp_faddr.s_addr != INADDR_ANY) {
1264                 error = EISCONN;
1265                 goto out;
1266         }
1267         error = 0;
1268
1269         /*
1270          * Bind if we have to
1271          */
1272         if (td->td_proc && td->td_proc->p_ucred->cr_prison != NULL &&
1273             inp->inp_laddr.s_addr == INADDR_ANY) {
1274                 error = in_pcbbind(inp, NULL, td);
1275                 if (error)
1276                         goto out;
1277         }
1278
1279         /*
1280          * Calculate the correct protocol processing thread.  The connect
1281          * operation must run there.
1282          */
1283         error = in_pcbladdr(inp, nam, &if_sin, td);
1284         if (error)
1285                 goto out;
1286         if (!prison_remote_ip(td, nam)) {
1287                 error = EAFNOSUPPORT; /* IPv6 only jail */
1288                 goto out;
1289         }
1290
1291         port = udp_addrport(sin->sin_addr.s_addr, sin->sin_port,
1292                             inp->inp_laddr.s_addr, inp->inp_lport);
1293         if (port != &curthread->td_msgport) {
1294 #ifdef notyet
1295                 struct route *ro = &inp->inp_route;
1296
1297                 /*
1298                  * in_pcbladdr() may have allocated a route entry for us
1299                  * on the current CPU, but we need a route entry on the
1300                  * inpcb's owner CPU, so free it here.
1301                  */
1302                 if (ro->ro_rt != NULL)
1303                         RTFREE(ro->ro_rt);
1304                 bzero(ro, sizeof(*ro));
1305
1306                 /*
1307                  * We are moving the protocol processing port the socket
1308                  * is on, we have to unlink here and re-link on the
1309                  * target cpu.
1310                  */
1311                 in_pcbunlink(so->so_pcb, &udbinfo);
1312                 /* in_pcbunlink(so->so_pcb, &udbinfo[mycpu->gd_cpuid]); */
1313                 sosetport(so, port);
1314                 msg->connect.nm_flags |= PRUC_RECONNECT;
1315                 msg->connect.base.nm_dispatch = udp_connect;
1316
1317                 lwkt_forwardmsg(port, &msg->connect.base.lmsg);
1318                 /* msg invalid now */
1319                 return;
1320 #else
1321                 panic("UDP activity should only be in netisr0");
1322 #endif
1323         }
1324         KKASSERT(port == &curthread->td_msgport);
1325         error = udp_connect_oncpu(so, td, sin, if_sin);
1326 out:
1327         KKASSERT(msg->connect.nm_m == NULL);
1328         lwkt_replymsg(&msg->connect.base.lmsg, error);
1329 }
1330
1331 static int
1332 udp_connect_oncpu(struct socket *so, struct thread *td,
1333                   struct sockaddr_in *sin, struct sockaddr_in *if_sin)
1334 {
1335         struct inpcb *inp;
1336         int error;
1337
1338         udbinfo_barrier_set();
1339
1340         inp = so->so_pcb;
1341         if (inp->inp_flags & INP_WILDCARD)
1342                 in_pcbremwildcardhash(inp);
1343         error = in_pcbconnect(inp, (struct sockaddr *)sin, td);
1344
1345         if (error == 0) {
1346                 /*
1347                  * No more errors can occur, finish adjusting the socket
1348                  * and change the processing port to reflect the connected
1349                  * socket.  Once set we can no longer safely mess with the
1350                  * socket.
1351                  */
1352                 soisconnected(so);
1353         } else if (error == EAFNOSUPPORT) {     /* connection dissolved */
1354                 /*
1355                  * Follow traditional BSD behavior and retain
1356                  * the local port binding.  But, fix the old misbehavior
1357                  * of overwriting any previously bound local address.
1358                  */
1359                 if (!(inp->inp_flags & INP_WASBOUND_NOTANY))
1360                         inp->inp_laddr.s_addr = INADDR_ANY;
1361                 in_pcbinswildcardhash(inp);
1362         }
1363
1364         udbinfo_barrier_rem();
1365         return error;
1366 }
1367
1368 static void
1369 udp_detach(netmsg_t msg)
1370 {
1371         struct socket *so = msg->detach.base.nm_so;
1372         struct inpcb *inp;
1373         int error;
1374
1375         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1376
1377         inp = so->so_pcb;
1378         if (inp) {
1379                 udbinfo_barrier_set();
1380                 in_pcbdetach(inp);
1381                 udbinfo_barrier_rem();
1382                 error = 0;
1383         } else {
1384                 error = EINVAL;
1385         }
1386         lwkt_replymsg(&msg->detach.base.lmsg, error);
1387 }
1388
1389 static void
1390 udp_disconnect(netmsg_t msg)
1391 {
1392         struct socket *so = msg->disconnect.base.nm_so;
1393         struct route *ro;
1394         struct inpcb *inp;
1395         int error;
1396
1397         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1398
1399         inp = so->so_pcb;
1400         if (inp == NULL) {
1401                 error = EINVAL;
1402                 goto out;
1403         }
1404         if (inp->inp_faddr.s_addr == INADDR_ANY) {
1405                 error = ENOTCONN;
1406                 goto out;
1407         }
1408
1409         soreference(so);
1410
1411         udbinfo_barrier_set();
1412         in_pcbdisconnect(inp);
1413         udbinfo_barrier_rem();
1414
1415         soclrstate(so, SS_ISCONNECTED);         /* XXX */
1416         sofree(so);
1417
1418         ro = &inp->inp_route;
1419         if (ro->ro_rt != NULL)
1420                 RTFREE(ro->ro_rt);
1421         bzero(ro, sizeof(*ro));
1422         error = 0;
1423 out:
1424         lwkt_replymsg(&msg->disconnect.base.lmsg, error);
1425 }
1426
1427 void
1428 udp_shutdown(netmsg_t msg)
1429 {
1430         struct socket *so = msg->shutdown.base.nm_so;
1431         struct inpcb *inp;
1432         int error;
1433
1434         KKASSERT(&curthread->td_msgport == netisr_cpuport(0));
1435
1436         inp = so->so_pcb;
1437         if (inp) {
1438                 socantsendmore(so);
1439                 error = 0;
1440         } else {
1441                 error = EINVAL;
1442         }
1443         lwkt_replymsg(&msg->shutdown.base.lmsg, error);
1444 }
1445
1446 void
1447 udbinfo_lock(void)
1448 {
1449         lwkt_serialize_enter(&udbinfo_slize);
1450 }
1451
1452 void
1453 udbinfo_unlock(void)
1454 {
1455         lwkt_serialize_exit(&udbinfo_slize);
1456 }
1457
1458 void
1459 udbinfo_barrier_set(void)
1460 {
1461         netisr_barrier_set(udbinfo_br);
1462         udbinfo_lock();
1463 }
1464
1465 void
1466 udbinfo_barrier_rem(void)
1467 {
1468         udbinfo_unlock();
1469         netisr_barrier_rem(udbinfo_br);
1470 }
1471
1472 struct pr_usrreqs udp_usrreqs = {
1473         .pru_abort = udp_abort,
1474         .pru_accept = pr_generic_notsupp,
1475         .pru_attach = udp_attach,
1476         .pru_bind = udp_bind,
1477         .pru_connect = udp_connect,
1478         .pru_connect2 = pr_generic_notsupp,
1479         .pru_control = in_control_dispatch,
1480         .pru_detach = udp_detach,
1481         .pru_disconnect = udp_disconnect,
1482         .pru_listen = pr_generic_notsupp,
1483         .pru_peeraddr = in_setpeeraddr_dispatch,
1484         .pru_rcvd = pr_generic_notsupp,
1485         .pru_rcvoob = pr_generic_notsupp,
1486         .pru_send = udp_send,
1487         .pru_sense = pru_sense_null,
1488         .pru_shutdown = udp_shutdown,
1489         .pru_sockaddr = in_setsockaddr_dispatch,
1490         .pru_sosend = sosendudp,
1491         .pru_soreceive = soreceive
1492 };
1493