2 * Copyright (c) 2004 Jeffrey M. Hsu. All rights reserved.
3 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
5 * This code is derived from software contributed to The DragonFly Project
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
35 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
36 * The Regents of the University of California. All rights reserved.
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
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.
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
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 $
66 #include "opt_ipsec.h"
67 #include "opt_inet6.h"
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/kernel.h>
72 #include <sys/malloc.h>
74 #include <sys/domain.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>
85 #include <sys/thread2.h>
86 #include <sys/socketvar2.h>
87 #include <sys/serialize.h>
89 #include <machine/stdarg.h>
92 #include <net/route.h>
93 #include <net/netmsg2.h>
94 #include <net/netisr2.h>
96 #include <netinet/in.h>
97 #include <netinet/in_systm.h>
98 #include <netinet/ip.h>
100 #include <netinet/ip6.h>
102 #include <netinet/in_pcb.h>
103 #include <netinet/in_var.h>
104 #include <netinet/ip_var.h>
106 #include <netinet6/ip6_var.h>
108 #include <netinet/ip_icmp.h>
109 #include <netinet/icmp_var.h>
110 #include <netinet/udp.h>
111 #include <netinet/udp_var.h>
114 #include <netproto/ipsec/ipsec.h>
118 #include <netinet6/ipsec.h>
121 #define MSGF_UDP_SEND MSGF_PROTO1
123 #define INP_DIRECT_DETACH INP_FLAG_PROTO2
125 #define UDP_KTR_STRING "inp=%p"
126 #define UDP_KTR_ARGS struct inpcb *inp
129 #define KTR_UDP KTR_ALL
132 KTR_INFO_MASTER(udp);
133 KTR_INFO(KTR_UDP, udp, send_beg, 0, UDP_KTR_STRING, UDP_KTR_ARGS);
134 KTR_INFO(KTR_UDP, udp, send_end, 1, UDP_KTR_STRING, UDP_KTR_ARGS);
135 KTR_INFO(KTR_UDP, udp, send_ipout, 2, UDP_KTR_STRING, UDP_KTR_ARGS);
136 KTR_INFO(KTR_UDP, udp, redisp_ipout_beg, 3, UDP_KTR_STRING, UDP_KTR_ARGS);
137 KTR_INFO(KTR_UDP, udp, redisp_ipout_end, 4, UDP_KTR_STRING, UDP_KTR_ARGS);
138 KTR_INFO(KTR_UDP, udp, send_redisp, 5, UDP_KTR_STRING, UDP_KTR_ARGS);
139 KTR_INFO(KTR_UDP, udp, send_inswildcard, 6, UDP_KTR_STRING, UDP_KTR_ARGS);
141 #define logudp(name, inp) KTR_LOG(udp_##name, inp)
144 * UDP protocol implementation.
145 * Per RFC 768, August, 1980.
148 static int udpcksum = 1;
150 static int udpcksum = 0; /* XXX */
152 SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW,
153 &udpcksum, 0, "Enable checksumming of UDP packets");
156 SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW,
157 &log_in_vain, 0, "Log all incoming UDP packets");
159 static int blackhole = 0;
160 SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW,
161 &blackhole, 0, "Do not send port unreachables for refused connects");
163 static int strict_mcast_mship = 1;
164 SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
165 &strict_mcast_mship, 0, "Only send multicast to member sockets");
167 int udp_sosend_async = 1;
168 SYSCTL_INT(_net_inet_udp, OID_AUTO, sosend_async, CTLFLAG_RW,
169 &udp_sosend_async, 0, "UDP asynchronized pru_send");
171 int udp_sosend_prepend = 1;
172 SYSCTL_INT(_net_inet_udp, OID_AUTO, sosend_prepend, CTLFLAG_RW,
173 &udp_sosend_prepend, 0,
174 "Prepend enough space for proto and link header in pru_send");
176 static int udp_reuseport_ext = 1;
177 SYSCTL_INT(_net_inet_udp, OID_AUTO, reuseport_ext, CTLFLAG_RW,
178 &udp_reuseport_ext, 0, "SO_REUSEPORT extension");
180 struct inpcbinfo udbinfo[MAXCPU];
183 #define UDBHASHSIZE 16
186 struct udpstat udpstat_percpu[MAXCPU] __cachealign;
188 static void udp_append(struct inpcb *last, struct ip *ip,
189 struct mbuf *n, int off, struct sockaddr_in *udp_in);
191 static int udp_connect_oncpu(struct inpcb *inp, struct sockaddr_in *sin,
192 struct sockaddr_in *if_sin);
194 static boolean_t udp_inswildcardhash(struct inpcb *inp,
195 struct netmsg_base *msg, int error);
196 static void udp_remwildcardhash(struct inpcb *inp);
201 struct inpcbportinfo *portinfo;
204 portinfo = kmalloc_cachealign(sizeof(*portinfo) * ncpus2, M_PCB,
207 for (cpu = 0; cpu < ncpus2; cpu++) {
208 struct inpcbinfo *uicb = &udbinfo[cpu];
212 * UDP pcb list, wildcard hash table and localgroup hash
215 in_pcbinfo_init(uicb, cpu, TRUE);
216 uicb->hashbase = hashinit(UDBHASHSIZE, M_PCB, &uicb->hashmask);
218 in_pcbportinfo_init(&portinfo[cpu], UDBHASHSIZE, TRUE, cpu);
219 uicb->portinfo = portinfo;
220 uicb->portinfo_mask = ncpus2_mask;
222 uicb->wildcardhashbase = hashinit(UDBHASHSIZE, M_PCB,
223 &uicb->wildcardhashmask);
224 uicb->localgrphashbase = hashinit(UDBHASHSIZE, M_PCB,
225 &uicb->localgrphashmask);
227 uicb->ipi_size = sizeof(struct inpcb);
231 * Initialize UDP statistics counters for each CPU.
233 for (cpu = 0; cpu < ncpus; ++cpu)
234 bzero(&udpstat_percpu[cpu], sizeof(struct udpstat));
238 sysctl_udpstat(SYSCTL_HANDLER_ARGS)
242 for (cpu = 0; cpu < ncpus; ++cpu) {
243 if ((error = SYSCTL_OUT(req, &udpstat_percpu[cpu],
244 sizeof(struct udpstat))))
246 if ((error = SYSCTL_IN(req, &udpstat_percpu[cpu],
247 sizeof(struct udpstat))))
253 SYSCTL_PROC(_net_inet_udp, UDPCTL_STATS, stats, (CTLTYPE_OPAQUE | CTLFLAG_RW),
254 0, 0, sysctl_udpstat, "S,udpstat", "UDP statistics");
257 udp_ctloutput(netmsg_t msg)
259 struct socket *so = msg->base.nm_so;
260 struct sockopt *sopt = msg->ctloutput.nm_sopt;
261 struct inpcb *inp = so->so_pcb;
264 lwkt_replymsg(&msg->lmsg, EINVAL);
268 if (sopt->sopt_level == IPPROTO_IP && sopt->sopt_dir == SOPT_SET) {
269 switch (sopt->sopt_name) {
270 case IP_MULTICAST_IF:
271 case IP_MULTICAST_VIF:
272 case IP_MULTICAST_TTL:
273 case IP_MULTICAST_LOOP:
274 case IP_ADD_MEMBERSHIP:
275 case IP_DROP_MEMBERSHIP:
277 * This pr_ctloutput msg will be forwarded
278 * to netisr0 to run; we can't do direct
282 * Don't optimize for the sockets whose
283 * current so_port is netisr0's msgport.
284 * These sockets could be connect(2)'ed
285 * later and the so_port will be changed.
287 inp->inp_flags &= ~INP_DIRECT_DETACH;
291 return ip_ctloutput(msg);
295 * Check multicast packets to make sure they are only sent to sockets with
296 * multicast memberships for the packet's destination address and arrival
297 * interface. Multicast packets to multicast-unaware sockets are also
300 * Returns 0 if the packet is acceptable, -1 if it is not.
303 check_multicast_membership(const struct ip *ip, const struct inpcb *inp,
304 const struct mbuf *m)
306 const struct ip_moptions *mopt;
309 if (strict_mcast_mship == 0 ||
310 !IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
316 mopt = inp->inp_moptions;
319 for (mshipno = 0; mshipno < mopt->imo_num_memberships; ++mshipno) {
320 const struct in_multi *maddr = mopt->imo_membership[mshipno];
322 if (ip->ip_dst.s_addr == maddr->inm_addr.s_addr &&
323 m->m_pkthdr.rcvif == maddr->inm_ifp) {
330 struct udp_mcast_arg {
336 struct sockaddr_in *udp_in;
340 udp_mcast_input(struct udp_mcast_arg *arg)
342 struct inpcb *inp = arg->inp;
343 struct inpcb *last = arg->last;
344 struct ip *ip = arg->ip;
345 struct mbuf *m = arg->m;
347 if (check_multicast_membership(ip, inp, m) < 0)
348 return ERESTART; /* caller continue */
354 /* check AH/ESP integrity. */
355 if (ipsec4_in_reject_so(m, last->inp_socket))
356 ipsecstat.in_polvio++;
357 /* do not inject data to pcb */
361 /* check AH/ESP integrity. */
362 if (ipsec4_in_reject(m, last))
365 #endif /*FAST_IPSEC*/
366 if ((n = m_copypacket(m, M_NOWAIT)) != NULL)
367 udp_append(last, ip, n,
368 arg->iphlen + sizeof(struct udphdr),
371 arg->last = last = inp;
374 * Don't look for additional matches if this one does
375 * not have either the SO_REUSEPORT or SO_REUSEADDR
376 * socket options set. This heuristic avoids searching
377 * through all pcbs in the common case of a non-shared
378 * port. It * assumes that an application will never
379 * clear these options after setting them.
381 if (!(last->inp_socket->so_options &
382 (SO_REUSEPORT | SO_REUSEADDR)))
383 return EJUSTRETURN; /* caller stop */
388 udp_input(struct mbuf **mp, int *offp, int proto)
390 struct sockaddr_in udp_in = { sizeof udp_in, AF_INET };
396 struct mbuf *opts = NULL;
399 struct inpcbinfo *pcbinfo = &udbinfo[mycpuid];
406 udp_stat.udps_ipackets++;
409 * Strip IP options, if any; should skip this,
410 * make available to user, and use on returned packets,
411 * but we don't yet have a way to check the checksum
412 * with options still present.
414 if (iphlen > sizeof(struct ip)) {
416 iphlen = sizeof(struct ip);
420 * IP and UDP headers are together in first mbuf.
421 * Already checked and pulled up in ip_demux().
423 KASSERT(m->m_len >= iphlen + sizeof(struct udphdr),
424 ("UDP header not in one mbuf"));
426 ip = mtod(m, struct ip *);
427 uh = (struct udphdr *)((caddr_t)ip + iphlen);
429 /* destination port of 0 is illegal, based on RFC768. */
430 if (uh->uh_dport == 0)
434 * Make mbuf data length reflect UDP length.
435 * If not enough data to reflect UDP length, drop.
437 len = ntohs((u_short)uh->uh_ulen);
438 if (ip->ip_len != len) {
439 if (len > ip->ip_len || len < sizeof(struct udphdr)) {
440 udp_stat.udps_badlen++;
443 m_adj(m, len - ip->ip_len);
444 /* ip->ip_len = len; */
447 * Save a copy of the IP header in case we want restore it
448 * for sending an ICMP error message in response.
453 * Checksum extended UDP header and data.
456 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
457 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR)
458 uh->uh_sum = m->m_pkthdr.csum_data;
460 uh->uh_sum = in_pseudo(ip->ip_src.s_addr,
461 ip->ip_dst.s_addr, htonl((u_short)len +
462 m->m_pkthdr.csum_data + IPPROTO_UDP));
463 uh->uh_sum ^= 0xffff;
467 bcopy(((struct ipovly *)ip)->ih_x1, b, 9);
468 bzero(((struct ipovly *)ip)->ih_x1, 9);
469 ((struct ipovly *)ip)->ih_len = uh->uh_ulen;
470 uh->uh_sum = in_cksum(m, len + sizeof(struct ip));
471 bcopy(b, ((struct ipovly *)ip)->ih_x1, 9);
474 udp_stat.udps_badsum++;
476 return(IPPROTO_DONE);
479 udp_stat.udps_nosum++;
481 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
482 in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {
483 struct inpcbhead *connhead;
484 struct inpcontainer *ic, *ic_marker;
485 struct inpcontainerhead *ichead;
486 struct udp_mcast_arg arg;
491 * Deliver a multicast or broadcast datagram to *all* sockets
492 * for which the local and remote addresses and ports match
493 * those of the incoming datagram. This allows more than
494 * one process to receive multi/broadcasts on the same port.
495 * (This really ought to be done for unicast datagrams as
496 * well, but that would cause problems with existing
497 * applications that open both address-specific sockets and
498 * a wildcard socket listening to the same port -- they would
499 * end up receiving duplicates of every unicast datagram.
500 * Those applications open the multiple sockets to overcome an
501 * inadequacy of the UDP socket interface, but for backwards
502 * compatibility we avoid the problem here rather than
503 * fixing the interface. Maybe 4.5BSD will remedy this?)
507 * Construct sockaddr format source address.
509 udp_in.sin_port = uh->uh_sport;
510 udp_in.sin_addr = ip->ip_src;
511 arg.udp_in = &udp_in;
513 * Locate pcb(s) for datagram.
514 * (Algorithm copied from raw_intr().)
519 connhead = &pcbinfo->hashbase[
520 INP_PCBCONNHASH(ip->ip_src.s_addr, uh->uh_sport,
521 ip->ip_dst.s_addr, uh->uh_dport, pcbinfo->hashmask)];
522 LIST_FOREACH(inp, connhead, inp_hash) {
524 if (!INP_ISIPV4(inp))
527 if (!in_hosteq(inp->inp_faddr, ip->ip_src) ||
528 !in_hosteq(inp->inp_laddr, ip->ip_dst) ||
529 inp->inp_fport != uh->uh_sport ||
530 inp->inp_lport != uh->uh_dport)
538 error = udp_mcast_input(&arg);
539 if (error == ERESTART)
543 if (error == EJUSTRETURN)
547 ichead = &pcbinfo->wildcardhashbase[
548 INP_PCBWILDCARDHASH(uh->uh_dport,
549 pcbinfo->wildcardhashmask)];
550 ic_marker = in_pcbcontainer_marker(mycpuid);
552 GET_PCBINFO_TOKEN(pcbinfo);
553 LIST_INSERT_HEAD(ichead, ic_marker, ic_list);
554 while ((ic = LIST_NEXT(ic_marker, ic_list)) != NULL) {
555 LIST_REMOVE(ic_marker, ic_list);
556 LIST_INSERT_AFTER(ic, ic_marker, ic_list);
559 if (inp->inp_flags & INP_PLACEMARKER)
562 if (!INP_ISIPV4(inp))
565 if (inp->inp_lport != uh->uh_dport)
567 if (inp->inp_laddr.s_addr != INADDR_ANY &&
568 inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
576 error = udp_mcast_input(&arg);
577 if (error == ERESTART)
581 if (error == EJUSTRETURN)
584 LIST_REMOVE(ic_marker, ic_list);
585 REL_PCBINFO_TOKEN(pcbinfo);
589 * No matching pcb found; discard datagram.
590 * (No need to send an ICMP Port Unreachable
591 * for a broadcast or multicast datgram.)
593 udp_stat.udps_noportbcast++;
597 /* check AH/ESP integrity. */
598 if (ipsec4_in_reject_so(m, last->inp_socket)) {
599 ipsecstat.in_polvio++;
604 /* check AH/ESP integrity. */
605 if (ipsec4_in_reject(m, last))
607 #endif /*FAST_IPSEC*/
608 udp_append(last, ip, m, iphlen + sizeof(struct udphdr),
610 return(IPPROTO_DONE);
613 * Locate pcb for datagram.
615 inp = in_pcblookup_pkthash(pcbinfo, ip->ip_src, uh->uh_sport,
616 ip->ip_dst, uh->uh_dport, TRUE, m->m_pkthdr.rcvif,
617 udp_reuseport_ext ? m : NULL);
620 char buf[sizeof "aaa.bbb.ccc.ddd"];
622 strcpy(buf, inet_ntoa(ip->ip_dst));
624 "Connection attempt to UDP %s:%d from %s:%d\n",
625 buf, ntohs(uh->uh_dport), inet_ntoa(ip->ip_src),
626 ntohs(uh->uh_sport));
628 udp_stat.udps_noport++;
629 if (m->m_flags & (M_BCAST | M_MCAST)) {
630 udp_stat.udps_noportbcast++;
636 if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0)
640 ip->ip_len += iphlen;
641 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
642 return(IPPROTO_DONE);
644 KASSERT(INP_ISIPV4(inp), ("not inet inpcb"));
646 if (ipsec4_in_reject_so(m, inp->inp_socket)) {
647 ipsecstat.in_polvio++;
652 if (ipsec4_in_reject(m, inp))
654 #endif /*FAST_IPSEC*/
656 * Check the minimum TTL for socket.
658 if (ip->ip_ttl < inp->inp_ip_minttl)
662 * Construct sockaddr format source address.
663 * Stuff source address and datagram in user buffer.
665 udp_in.sin_port = uh->uh_sport;
666 udp_in.sin_addr = ip->ip_src;
667 if ((inp->inp_flags & INP_CONTROLOPTS) ||
668 (inp->inp_socket->so_options & SO_TIMESTAMP))
669 ip_savecontrol(inp, &opts, ip, m);
670 m_adj(m, iphlen + sizeof(struct udphdr));
672 lwkt_gettoken(&inp->inp_socket->so_rcv.ssb_token);
673 if (ssb_appendaddr(&inp->inp_socket->so_rcv,
674 (struct sockaddr *)&udp_in, m, opts) == 0) {
675 lwkt_reltoken(&inp->inp_socket->so_rcv.ssb_token);
676 udp_stat.udps_fullsock++;
679 lwkt_reltoken(&inp->inp_socket->so_rcv.ssb_token);
680 sorwakeup(inp->inp_socket);
681 return(IPPROTO_DONE);
686 return(IPPROTO_DONE);
690 * subroutine of udp_input(), mainly for source code readability.
691 * caller must properly init udp_ip6 and udp_in6 beforehand.
694 udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, int off,
695 struct sockaddr_in *udp_in)
697 struct mbuf *opts = NULL;
700 KASSERT(INP_ISIPV4(last), ("not inet inpcb"));
702 if (last->inp_flags & INP_CONTROLOPTS ||
703 last->inp_socket->so_options & SO_TIMESTAMP)
704 ip_savecontrol(last, &opts, ip, n);
707 lwkt_gettoken(&last->inp_socket->so_rcv.ssb_token);
708 ret = ssb_appendaddr(&last->inp_socket->so_rcv,
709 (struct sockaddr *)udp_in, n, opts);
710 lwkt_reltoken(&last->inp_socket->so_rcv.ssb_token);
715 udp_stat.udps_fullsock++;
717 sorwakeup(last->inp_socket);
722 * Notify a udp user of an asynchronous error;
723 * just wake up so that he can collect error status.
726 udp_notify(struct inpcb *inp, int error)
728 inp->inp_socket->so_error = error;
729 sorwakeup(inp->inp_socket);
730 sowwakeup(inp->inp_socket);
733 struct netmsg_udp_notify {
734 struct netmsg_base base;
735 inp_notify_t nm_notify;
736 struct in_addr nm_faddr;
741 udp_notifyall_oncpu(netmsg_t msg)
743 struct netmsg_udp_notify *nm = (struct netmsg_udp_notify *)msg;
744 int nextcpu, cpu = mycpuid;
746 in_pcbnotifyall(&udbinfo[cpu], nm->nm_faddr, nm->nm_arg, nm->nm_notify);
749 if (nextcpu < ncpus2)
750 lwkt_forwardmsg(netisr_cpuport(nextcpu), &nm->base.lmsg);
752 lwkt_replymsg(&nm->base.lmsg, 0);
756 udp_get_inpnotify(int cmd, const struct sockaddr *sa,
757 struct ip **ip0, int *cpuid)
759 struct in_addr faddr;
760 struct ip *ip = *ip0;
761 inp_notify_t notify = udp_notify;
763 faddr = ((const struct sockaddr_in *)sa)->sin_addr;
764 if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
767 if (PRC_IS_REDIRECT(cmd)) {
769 notify = in_rtchange;
770 } else if (cmd == PRC_HOSTDEAD) {
772 } else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
778 /* Go through all CPUs */
781 const struct udphdr *uh;
783 uh = (const struct udphdr *)
784 ((caddr_t)ip + (ip->ip_hl << 2));
785 *cpuid = udp_addrcpu(faddr.s_addr, uh->uh_dport,
786 ip->ip_src.s_addr, uh->uh_sport);
795 udp_ctlinput(netmsg_t msg)
797 struct sockaddr *sa = msg->ctlinput.nm_arg;
798 struct ip *ip = msg->ctlinput.nm_extra;
799 int cmd = msg->ctlinput.nm_cmd, cpuid;
801 struct in_addr faddr;
803 notify = udp_get_inpnotify(cmd, sa, &ip, &cpuid);
807 faddr = ((struct sockaddr_in *)sa)->sin_addr;
809 const struct udphdr *uh;
812 if (cpuid != mycpuid)
815 uh = (const struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
816 inp = in_pcblookup_hash(&udbinfo[mycpuid], faddr, uh->uh_dport,
817 ip->ip_src, uh->uh_sport, 0, NULL);
818 if (inp != NULL && inp->inp_socket != NULL)
819 notify(inp, inetctlerrmap[cmd]);
820 } else if (msg->ctlinput.nm_direct) {
821 if (cpuid != ncpus && cpuid != mycpuid)
823 if (mycpuid >= ncpus2)
826 in_pcbnotifyall(&udbinfo[mycpuid], faddr, inetctlerrmap[cmd],
829 struct netmsg_udp_notify *nm;
832 nm = kmalloc(sizeof(*nm), M_LWKTMSG, M_INTWAIT);
833 netmsg_init(&nm->base, NULL, &netisr_afree_rport,
834 0, udp_notifyall_oncpu);
835 nm->nm_faddr = faddr;
836 nm->nm_arg = inetctlerrmap[cmd];
837 nm->nm_notify = notify;
838 lwkt_sendmsg(netisr_cpuport(0), &nm->base.lmsg);
841 lwkt_replymsg(&msg->lmsg, 0);
844 SYSCTL_PROC(_net_inet_udp, UDPCTL_PCBLIST, pcblist, CTLFLAG_RD, udbinfo, 0,
845 in_pcblist_global_ncpus2, "S,xinpcb", "List of active UDP sockets");
848 udp_getcred(SYSCTL_HANDLER_ARGS)
850 struct sockaddr_in addrs[2];
851 struct ucred cred0, *cred = NULL;
853 int error, cpu, origcpu;
855 error = priv_check(req->td, PRIV_ROOT);
858 error = SYSCTL_IN(req, addrs, sizeof addrs);
863 cpu = udp_addrcpu(addrs[1].sin_addr.s_addr, addrs[1].sin_port,
864 addrs[0].sin_addr.s_addr, addrs[0].sin_port);
866 lwkt_migratecpu(cpu);
868 inp = in_pcblookup_hash(&udbinfo[cpu],
869 addrs[1].sin_addr, addrs[1].sin_port,
870 addrs[0].sin_addr, addrs[0].sin_port, TRUE, NULL);
871 if (inp == NULL || inp->inp_socket == NULL) {
873 } else if (inp->inp_socket->so_cred != NULL) {
874 cred0 = *(inp->inp_socket->so_cred);
878 lwkt_migratecpu(origcpu);
883 return SYSCTL_OUT(req, cred, sizeof(struct ucred));
885 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
886 0, 0, udp_getcred, "S,ucred", "Get the ucred of a UDP connection");
889 udp_send_redispatch(netmsg_t msg)
891 struct mbuf *m = msg->send.nm_m;
892 int pru_flags = msg->send.nm_flags;
893 struct inpcb *inp = msg->send.base.nm_so->so_pcb;
894 struct mbuf *m_opt = msg->send.nm_control; /* XXX save ipopt */
895 int flags = msg->send.nm_priv; /* ip_output flags */
898 logudp(redisp_ipout_beg, inp);
901 * - Don't use inp route cache. It should only be used in the
903 * - Access to inp_moptions should be safe, since multicast UDP
904 * datagrams are redispatched to netisr0 and inp_moptions is
905 * changed only in netisr0.
907 error = ip_output(m, m_opt, NULL, flags, inp->inp_moptions, inp);
908 if ((pru_flags & PRUS_NOREPLY) == 0)
909 lwkt_replymsg(&msg->send.base.lmsg, error);
912 /* Free saved ip options, if any */
916 logudp(redisp_ipout_end, inp);
920 udp_send(netmsg_t msg)
922 struct socket *so = msg->send.base.nm_so;
923 struct mbuf *m = msg->send.nm_m;
924 struct sockaddr *dstaddr = msg->send.nm_addr;
925 int pru_flags = msg->send.nm_flags;
926 struct inpcb *inp = so->so_pcb;
927 struct thread *td = msg->send.nm_td;
931 int len = m->m_pkthdr.len;
932 struct sockaddr_in *sin; /* really is initialized before use */
935 KKASSERT(msg->send.nm_control == NULL);
937 logudp(send_beg, inp);
944 if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
949 if (inp->inp_lport == 0) { /* unbound socket */
952 error = in_pcbbind(inp, NULL, td);
957 * Need to call udp_send again, after this inpcb is
958 * inserted into wildcard hash table.
960 msg->send.base.lmsg.ms_flags |= MSGF_UDP_SEND;
961 forwarded = udp_inswildcardhash(inp, &msg->send.base, 0);
964 * The message is further forwarded, so we are
967 logudp(send_inswildcard, inp);
972 if (dstaddr != NULL) { /* destination address specified */
973 if (inp->inp_faddr.s_addr != INADDR_ANY) {
974 /* already connected */
978 sin = (struct sockaddr_in *)dstaddr;
979 if (!prison_remote_ip(td, (struct sockaddr *)&sin)) {
980 error = EAFNOSUPPORT; /* IPv6 only jail */
984 if (inp->inp_faddr.s_addr == INADDR_ANY) {
985 /* no destination specified and not already connected */
993 * Calculate data length and get a mbuf
994 * for UDP and IP headers.
996 M_PREPEND(m, sizeof(struct udpiphdr), M_NOWAIT);
1003 * Fill in mbuf with extended UDP header
1004 * and addresses and length put into network format.
1006 ui = mtod(m, struct udpiphdr *);
1007 bzero(ui->ui_x1, sizeof ui->ui_x1); /* XXX still needed? */
1008 ui->ui_pr = IPPROTO_UDP;
1011 * Set destination address.
1013 if (dstaddr != NULL) { /* use specified destination */
1014 ui->ui_dst = sin->sin_addr;
1015 ui->ui_dport = sin->sin_port;
1016 } else { /* use connected destination */
1017 ui->ui_dst = inp->inp_faddr;
1018 ui->ui_dport = inp->inp_fport;
1022 * Set source address.
1024 if (inp->inp_laddr.s_addr == INADDR_ANY ||
1025 IN_MULTICAST(ntohl(inp->inp_laddr.s_addr))) {
1026 struct sockaddr_in *if_sin;
1028 if (dstaddr == NULL) {
1030 * connect() had (or should have) failed because
1031 * the interface had no IP address, but the
1032 * application proceeded to call send() anyways.
1038 /* Look up outgoing interface. */
1039 error = in_pcbladdr_find(inp, dstaddr, &if_sin, td, 1);
1042 ui->ui_src = if_sin->sin_addr; /* use address of interface */
1044 ui->ui_src = inp->inp_laddr; /* use non-null bound address */
1046 ui->ui_sport = inp->inp_lport;
1047 KASSERT(inp->inp_lport != 0, ("inp lport should have been bound"));
1050 * Release the original thread, since it is no longer used
1052 if (pru_flags & PRUS_HELDTD) {
1054 pru_flags &= ~PRUS_HELDTD;
1057 * Free the dest address, since it is no longer needed
1059 if (pru_flags & PRUS_FREEADDR) {
1060 kfree(dstaddr, M_SONAME);
1061 pru_flags &= ~PRUS_FREEADDR;
1064 ui->ui_ulen = htons((u_short)len + sizeof(struct udphdr));
1067 * Set up checksum and output datagram.
1070 ui->ui_sum = in_pseudo(ui->ui_src.s_addr, ui->ui_dst.s_addr,
1071 htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP));
1072 m->m_pkthdr.csum_flags = CSUM_UDP;
1073 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
1074 m->m_pkthdr.csum_thlen = sizeof(struct udphdr);
1078 ((struct ip *)ui)->ip_len = sizeof(struct udpiphdr) + len;
1079 ((struct ip *)ui)->ip_ttl = inp->inp_ip_ttl; /* XXX */
1080 ((struct ip *)ui)->ip_tos = inp->inp_ip_tos; /* XXX */
1081 udp_stat.udps_opackets++;
1083 flags = IP_DEBUGROUTE |
1084 (inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST));
1085 if (pru_flags & PRUS_DONTROUTE)
1086 flags |= SO_DONTROUTE;
1088 if (inp->inp_flags & INP_CONNECTED) {
1090 * For connected socket, this datagram has already
1091 * been in the correct netisr; no need to rehash.
1096 cpu = udp_addrcpu(ui->ui_dst.s_addr, ui->ui_dport,
1097 ui->ui_src.s_addr, ui->ui_sport);
1098 if (cpu != mycpuid) {
1099 struct mbuf *m_opt = NULL;
1100 struct netmsg_pru_send *smsg;
1101 struct lwkt_port *port = netisr_cpuport(cpu);
1104 * Not on the CPU that matches this UDP datagram hash;
1105 * redispatch to the correct CPU to do the ip_output().
1107 if (inp->inp_options != NULL) {
1109 * If there are ip options, then save a copy,
1110 * since accessing inp_options on other CPUs'
1113 * XXX optimize this?
1115 m_opt = m_copym(inp->inp_options, 0, M_COPYALL,
1118 if ((pru_flags & PRUS_NOREPLY) == 0) {
1120 * Change some parts of the original netmsg and
1121 * forward it to the target netisr.
1123 * NOTE: so_port MUST NOT be checked in the target
1127 smsg->nm_priv = flags; /* ip_output flags */
1129 smsg->nm_control = m_opt; /* XXX save ipopt */
1130 smsg->base.lmsg.ms_flags |= MSGF_IGNSOPORT;
1131 smsg->base.nm_dispatch = udp_send_redispatch;
1132 lwkt_forwardmsg(port, &smsg->base.lmsg);
1135 * Recreate the netmsg, since the original mbuf
1136 * could have been changed. And send it to the
1139 * NOTE: so_port MUST NOT be checked in the target
1142 smsg = &m->m_hdr.mh_sndmsg;
1143 netmsg_init(&smsg->base, so, &netisr_apanic_rport,
1144 MSGF_IGNSOPORT, udp_send_redispatch);
1145 smsg->nm_priv = flags; /* ip_output flags */
1146 smsg->nm_flags = pru_flags;
1148 smsg->nm_control = m_opt; /* XXX save ipopt */
1149 lwkt_sendmsg(port, &smsg->base.lmsg);
1152 /* This UDP datagram is redispatched; done */
1153 logudp(send_redisp, inp);
1158 logudp(send_ipout, inp);
1159 error = ip_output(m, inp->inp_options, &inp->inp_route, flags,
1160 inp->inp_moptions, inp);
1167 if (pru_flags & PRUS_HELDTD)
1169 if (pru_flags & PRUS_FREEADDR)
1170 kfree(dstaddr, M_SONAME);
1171 if ((pru_flags & PRUS_NOREPLY) == 0)
1172 lwkt_replymsg(&msg->send.base.lmsg, error);
1174 logudp(send_end, inp);
1177 u_long udp_sendspace = 9216; /* really max datagram size */
1178 /* 40 1K datagrams */
1179 SYSCTL_INT(_net_inet_udp, UDPCTL_MAXDGRAM, maxdgram, CTLFLAG_RW,
1180 &udp_sendspace, 0, "Maximum outgoing UDP datagram size");
1182 u_long udp_recvspace = 40 * (1024 +
1184 sizeof(struct sockaddr_in6)
1186 sizeof(struct sockaddr_in)
1189 SYSCTL_INT(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
1190 &udp_recvspace, 0, "Maximum incoming UDP datagram size");
1193 * This should never happen, since UDP socket does not support
1194 * connection acception (SO_ACCEPTCONN, i.e. listen(2)).
1197 udp_abort(netmsg_t msg __unused)
1199 panic("udp_abort is called");
1203 udp_preattach(struct socket *so, int proto __unused, struct pru_attach_info *ai)
1205 return soreserve(so, udp_sendspace, udp_recvspace, ai->sb_rlimit);
1209 udp_attach(netmsg_t msg)
1211 struct socket *so = msg->attach.base.nm_so;
1212 struct pru_attach_info *ai = msg->attach.nm_ai;
1216 KASSERT(so->so_pcb == NULL, ("udp socket attached"));
1219 error = udp_preattach(so, 0 /* don't care */, ai);
1223 /* Post attach; do nothing */
1226 error = in_pcballoc(so, &udbinfo[mycpuid]);
1231 inp->inp_flags |= INP_DIRECT_DETACH;
1232 inp->inp_ip_ttl = ip_defttl;
1235 lwkt_replymsg(&msg->attach.base.lmsg, error);
1239 udp_inswildcard_replymsg(netmsg_t msg)
1241 lwkt_msg_t lmsg = &msg->lmsg;
1243 if (lmsg->ms_flags & MSGF_UDP_SEND) {
1245 /* msg is replied by udp_send() */
1247 lwkt_replymsg(lmsg, lmsg->ms_error);
1252 udp_soreuseport_dispatch(netmsg_t msg)
1254 /* This inpcb has already been in the wildcard hash. */
1255 in_pcblink_flags(msg->base.nm_so->so_pcb, &udbinfo[mycpuid], 0);
1256 udp_inswildcard_replymsg(msg);
1260 udp_sosetport(struct lwkt_msg *msg, lwkt_port_t port)
1262 sosetport(((struct netmsg_base *)msg)->nm_so, port);
1266 udp_inswildcardhash_oncpu(struct inpcb *inp, struct netmsg_base *msg)
1270 KASSERT(inp->inp_pcbinfo == &udbinfo[mycpuid],
1271 ("not on owner cpu"));
1273 in_pcbinswildcardhash(inp);
1274 for (cpu = 0; cpu < ncpus2; ++cpu) {
1275 if (cpu == mycpuid) {
1277 * This inpcb has been inserted by the above
1278 * in_pcbinswildcardhash().
1282 in_pcbinswildcardhash_oncpu(inp, &udbinfo[cpu]);
1285 if (inp->inp_socket->so_options & SO_REUSEPORT) {
1287 * For SO_REUSEPORT socket, redistribute it based on its
1288 * local group index.
1290 cpu = inp->inp_lgrpindex & ncpus2_mask;
1291 if (cpu != mycpuid) {
1292 struct lwkt_port *port = netisr_cpuport(cpu);
1293 lwkt_msg_t lmsg = &msg->lmsg;
1296 * We are moving the protocol processing port the
1297 * socket is on, we have to unlink here and re-link
1298 * on the target cpu (this inpcb is still left in
1299 * the wildcard hash).
1301 in_pcbunlink_flags(inp, &udbinfo[mycpuid], 0);
1302 msg->nm_dispatch = udp_soreuseport_dispatch;
1305 * See the related comment in tcp_usrreq.c
1308 lwkt_setmsg_receipt(lmsg, udp_sosetport);
1309 lwkt_forwardmsg(port, lmsg);
1310 return TRUE; /* forwarded */
1317 udp_inswildcardhash_dispatch(netmsg_t msg)
1319 struct inpcb *inp = msg->base.nm_so->so_pcb;
1320 boolean_t forwarded;
1322 KASSERT(inp->inp_lport != 0, ("local port not set yet"));
1323 KASSERT((ntohs(inp->inp_lport) & ncpus2_mask) == mycpuid,
1324 ("not target cpu"));
1326 in_pcblink(inp, &udbinfo[mycpuid]);
1328 forwarded = udp_inswildcardhash_oncpu(inp, &msg->base);
1330 /* The message is further forwarded, so we are done here. */
1333 udp_inswildcard_replymsg(msg);
1337 udp_inswildcardhash(struct inpcb *inp, struct netmsg_base *msg, int error)
1339 lwkt_msg_t lmsg = &msg->lmsg;
1342 ASSERT_INP_NOTINHASH(inp);
1344 /* This inpcb could no longer be directly detached */
1345 inp->inp_flags &= ~INP_DIRECT_DETACH;
1348 * Always clear the route cache, so we don't need to
1349 * worry about any owner CPU changes later.
1351 in_pcbresetroute(inp);
1353 KASSERT(inp->inp_lport != 0, ("local port not set yet"));
1354 cpu = ntohs(inp->inp_lport) & ncpus2_mask;
1356 lmsg->ms_error = error;
1357 if (cpu != mycpuid) {
1358 struct lwkt_port *port = netisr_cpuport(cpu);
1361 * We are moving the protocol processing port the socket
1362 * is on, we have to unlink here and re-link on the
1365 in_pcbunlink(inp, &udbinfo[mycpuid]);
1366 msg->nm_dispatch = udp_inswildcardhash_dispatch;
1368 /* See the related comment in tcp_usrreq.c tcp_connect() */
1369 lwkt_setmsg_receipt(lmsg, udp_sosetport);
1370 lwkt_forwardmsg(port, lmsg);
1371 return TRUE; /* forwarded */
1374 return udp_inswildcardhash_oncpu(inp, msg);
1378 udp_bind(netmsg_t msg)
1380 struct socket *so = msg->bind.base.nm_so;
1386 struct sockaddr *nam = msg->bind.nm_nam;
1387 struct thread *td = msg->bind.nm_td;
1389 error = in_pcbbind(inp, nam, td);
1391 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
1392 boolean_t forwarded;
1394 if (sin->sin_addr.s_addr != INADDR_ANY)
1395 inp->inp_flags |= INP_WASBOUND_NOTANY;
1397 forwarded = udp_inswildcardhash(inp,
1398 &msg->bind.base, 0);
1401 * The message is further forwarded, so
1410 lwkt_replymsg(&msg->bind.base.lmsg, error);
1414 udp_preconnect(struct socket *so, const struct sockaddr *nam __unused,
1415 struct thread *td __unused)
1417 sosetstate(so, SS_ISCONNECTED); /* XXX */
1422 udp_connect(netmsg_t msg)
1424 struct socket *so = msg->connect.base.nm_so;
1425 struct sockaddr *nam = msg->connect.nm_nam;
1426 struct thread *td = msg->connect.nm_td;
1428 struct sockaddr_in *sin = (struct sockaddr_in *)nam;
1429 struct sockaddr_in *if_sin;
1430 struct lwkt_port *port;
1433 KKASSERT(msg->connect.nm_m == NULL);
1441 if (msg->connect.nm_flags & PRUC_RECONNECT) {
1442 msg->connect.nm_flags &= ~PRUC_RECONNECT;
1443 in_pcblink(inp, &udbinfo[mycpuid]);
1446 if (inp->inp_faddr.s_addr != INADDR_ANY) {
1453 * Bind if we have to
1455 if (inp->inp_lport == 0) {
1456 error = in_pcbbind(inp, NULL, td);
1462 * Calculate the correct protocol processing thread. The connect
1463 * operation must run there.
1465 error = in_pcbladdr(inp, nam, &if_sin, td);
1468 if (!prison_remote_ip(td, nam)) {
1469 error = EAFNOSUPPORT; /* IPv6 only jail */
1473 port = udp_addrport(sin->sin_addr.s_addr, sin->sin_port,
1474 inp->inp_laddr.s_addr != INADDR_ANY ?
1475 inp->inp_laddr.s_addr : if_sin->sin_addr.s_addr, inp->inp_lport);
1476 if (port != &curthread->td_msgport) {
1477 lwkt_msg_t lmsg = &msg->connect.base.lmsg;
1478 int nm_flags = PRUC_RECONNECT;
1481 * in_pcbladdr() may have allocated a route entry for us
1482 * on the current CPU, but we need a route entry on the
1483 * inpcb's owner CPU, so free it here.
1485 in_pcbresetroute(inp);
1487 if (inp->inp_flags & INP_WILDCARD) {
1489 * Remove this inpcb from the wildcard hash before
1490 * the socket's msgport changes.
1492 udp_remwildcardhash(inp);
1495 if (so->so_orig_port == NULL) {
1497 * First time change protocol processing port.
1498 * Save the current port for synchronization upon
1501 so->so_orig_port = &curthread->td_msgport;
1504 * We have changed protocol processing port more
1505 * than once. We could not do direct detach
1506 * anymore, because we lose the track of the
1507 * original protocol processing ports to perform
1508 * synchronization upon udp_detach. This should
1511 inp->inp_flags &= ~INP_DIRECT_DETACH;
1515 * We are moving the protocol processing port the socket
1516 * is on, we have to unlink here and re-link on the
1519 in_pcbunlink(inp, &udbinfo[mycpuid]);
1520 msg->connect.nm_flags |= nm_flags;
1522 /* See the related comment in tcp_usrreq.c tcp_connect() */
1523 lwkt_setmsg_receipt(lmsg, udp_sosetport);
1524 lwkt_forwardmsg(port, lmsg);
1525 /* msg invalid now */
1528 error = udp_connect_oncpu(inp, sin, if_sin);
1530 if (msg->connect.nm_flags & PRUC_HELDTD)
1532 if (error && (msg->connect.nm_flags & PRUC_ASYNC)) {
1533 so->so_error = error;
1534 soclrstate(so, SS_ISCONNECTED); /* XXX */
1536 if (error && inp != NULL && inp->inp_lport != 0 &&
1537 (inp->inp_flags & INP_WILDCARD) == 0) {
1538 boolean_t forwarded;
1540 /* Connect failed; put it to wildcard hash. */
1541 forwarded = udp_inswildcardhash(inp, &msg->connect.base,
1545 * The message is further forwarded, so we are done
1551 lwkt_replymsg(&msg->connect.base.lmsg, error);
1555 udp_remwildcardhash(struct inpcb *inp)
1559 KASSERT(inp->inp_pcbinfo == &udbinfo[mycpuid],
1560 ("not on owner cpu"));
1562 for (cpu = 0; cpu < ncpus2; ++cpu) {
1563 if (cpu == mycpuid) {
1565 * This inpcb will be removed by the later
1566 * in_pcbremwildcardhash().
1570 in_pcbremwildcardhash_oncpu(inp, &udbinfo[cpu]);
1572 in_pcbremwildcardhash(inp);
1576 udp_connect_oncpu(struct inpcb *inp, struct sockaddr_in *sin,
1577 struct sockaddr_in *if_sin)
1579 struct socket *so = inp->inp_socket;
1582 oinp = in_pcblookup_hash(inp->inp_pcbinfo,
1583 sin->sin_addr, sin->sin_port,
1584 inp->inp_laddr.s_addr != INADDR_ANY ?
1585 inp->inp_laddr : if_sin->sin_addr, inp->inp_lport, FALSE, NULL);
1590 * No more errors can occur, finish adjusting the socket
1591 * and change the processing port to reflect the connected
1592 * socket. Once set we can no longer safely mess with the
1596 if (inp->inp_flags & INP_WILDCARD)
1597 udp_remwildcardhash(inp);
1599 if (inp->inp_laddr.s_addr == INADDR_ANY)
1600 inp->inp_laddr = if_sin->sin_addr;
1601 inp->inp_faddr = sin->sin_addr;
1602 inp->inp_fport = sin->sin_port;
1603 in_pcbinsconnhash(inp);
1611 udp_detach2(struct socket *so)
1613 in_pcbdetach(so->so_pcb);
1619 udp_detach_final_dispatch(netmsg_t msg)
1621 udp_detach2(msg->base.nm_so);
1625 udp_detach_oncpu_dispatch(netmsg_t msg)
1627 struct netmsg_base *clomsg = &msg->base;
1628 struct socket *so = clomsg->nm_so;
1629 struct inpcb *inp = so->so_pcb;
1630 struct thread *td = curthread;
1631 int nextcpu, cpuid = mycpuid;
1633 KASSERT(td->td_type == TD_TYPE_NETISR, ("not in netisr"));
1635 if (inp->inp_flags & INP_WILDCARD) {
1637 * This inp will be removed on the inp's
1638 * owner CPU later, so don't do it now.
1640 if (&td->td_msgport != so->so_port)
1641 in_pcbremwildcardhash_oncpu(inp, &udbinfo[cpuid]);
1646 * Free and clear multicast socket option,
1647 * which is only accessed in netisr0.
1649 ip_freemoptions(inp->inp_moptions);
1650 inp->inp_moptions = NULL;
1653 nextcpu = cpuid + 1;
1654 if (nextcpu < ncpus2) {
1655 lwkt_forwardmsg(netisr_cpuport(nextcpu), &clomsg->lmsg);
1658 * No one could see this inpcb now; destroy this
1659 * inpcb in its owner netisr.
1661 netmsg_init(clomsg, so, &netisr_apanic_rport, 0,
1662 udp_detach_final_dispatch);
1663 lwkt_sendmsg(so->so_port, &clomsg->lmsg);
1668 udp_detach_syncorig_dispatch(netmsg_t msg)
1670 struct netmsg_base *clomsg = &msg->base;
1671 struct socket *so = clomsg->nm_so;
1674 * Original protocol processing port is synchronized;
1675 * destroy this inpcb in its owner netisr.
1677 netmsg_init(clomsg, so, &netisr_apanic_rport, 0,
1678 udp_detach_final_dispatch);
1679 lwkt_sendmsg(so->so_port, &clomsg->lmsg);
1683 udp_detach(netmsg_t msg)
1685 struct socket *so = msg->detach.base.nm_so;
1686 struct netmsg_base *clomsg;
1691 lwkt_replymsg(&msg->detach.base.lmsg, EINVAL);
1696 * Reply EJUSTRETURN ASAP, we will call sodiscard() and
1699 lwkt_replymsg(&msg->detach.base.lmsg, EJUSTRETURN);
1702 /* Only one CPU, detach the inpcb directly. */
1708 * Remove this inpcb from the inpcb list first, so that
1709 * no one could find this inpcb from the inpcb list.
1713 if (inp->inp_flags & INP_DIRECT_DETACH) {
1715 * Direct detaching is allowed
1717 KASSERT((inp->inp_flags & INP_WILDCARD) == 0,
1718 ("in the wildcardhash"));
1719 KASSERT(inp->inp_moptions == NULL, ("has mcast options"));
1720 if (so->so_orig_port == NULL) {
1724 * Protocol processing port changed once, so
1725 * we need to make sure that there are nothing
1726 * left on the original protocol processing
1727 * port before we destroy this socket and inpcb.
1728 * This is more lightweight than going through
1729 * all UDP processing netisrs.
1731 clomsg = &so->so_clomsg;
1732 netmsg_init(clomsg, so, &netisr_apanic_rport,
1733 MSGF_IGNSOPORT, udp_detach_syncorig_dispatch);
1734 lwkt_sendmsg(so->so_orig_port, &clomsg->lmsg);
1740 * Go through netisrs which process UDP to make sure
1741 * no one could find this inpcb anymore.
1743 clomsg = &so->so_clomsg;
1744 netmsg_init(clomsg, so, &netisr_apanic_rport, MSGF_IGNSOPORT,
1745 udp_detach_oncpu_dispatch);
1746 lwkt_sendmsg(netisr_cpuport(0), &clomsg->lmsg);
1750 udp_disconnect(netmsg_t msg)
1752 struct socket *so = msg->disconnect.base.nm_so;
1754 boolean_t forwarded;
1762 if (inp->inp_faddr.s_addr == INADDR_ANY) {
1767 soclrstate(so, SS_ISCONNECTED); /* XXX */
1769 in_pcbdisconnect(inp);
1772 * Follow traditional BSD behavior and retain the local port
1773 * binding. But, fix the old misbehavior of overwriting any
1774 * previously bound local address.
1776 if (!(inp->inp_flags & INP_WASBOUND_NOTANY))
1777 inp->inp_laddr.s_addr = INADDR_ANY;
1779 if (so->so_state & SS_ISCLOSING) {
1781 * If this socket is being closed, there is no need
1782 * to put this socket back into wildcard hash table.
1788 forwarded = udp_inswildcardhash(inp, &msg->disconnect.base, 0);
1791 * The message is further forwarded, so we are done
1797 lwkt_replymsg(&msg->disconnect.base.lmsg, error);
1801 udp_shutdown(netmsg_t msg)
1803 struct socket *so = msg->shutdown.base.nm_so;
1814 lwkt_replymsg(&msg->shutdown.base.lmsg, error);
1817 struct pr_usrreqs udp_usrreqs = {
1818 .pru_abort = udp_abort,
1819 .pru_accept = pr_generic_notsupp,
1820 .pru_attach = udp_attach,
1821 .pru_bind = udp_bind,
1822 .pru_connect = udp_connect,
1823 .pru_connect2 = pr_generic_notsupp,
1824 .pru_control = in_control_dispatch,
1825 .pru_detach = udp_detach,
1826 .pru_disconnect = udp_disconnect,
1827 .pru_listen = pr_generic_notsupp,
1828 .pru_peeraddr = in_setpeeraddr_dispatch,
1829 .pru_rcvd = pr_generic_notsupp,
1830 .pru_rcvoob = pr_generic_notsupp,
1831 .pru_send = udp_send,
1832 .pru_sense = pru_sense_null,
1833 .pru_shutdown = udp_shutdown,
1834 .pru_sockaddr = in_setsockaddr_dispatch,
1835 .pru_sosend = sosendudp,
1836 .pru_soreceive = soreceive,
1837 .pru_preconnect = udp_preconnect,
1838 .pru_preattach = udp_preattach