2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "afs/param.h"
15 #include "rx/rx_kcommon.h"
20 #include "inet/common.h"
21 #include "sys/tiuser.h"
22 #include "sys/t_kuser.h"
23 #include "sys/stropts.h"
24 #include "sys/stream.h"
25 #include "sys/tihdr.h"
26 #include "sys/fcntl.h"
28 #include "netinet/ip6.h"
29 #define ipif_local_addr ipif_lcl_addr
31 #define V4_PART_OF_V6(v6) v6.s6_addr32[3]
35 #include "inet/ip_if.h"
36 #include "netinet/udp.h"
43 #include "h/cmn_err.h"
45 #include "netinet/in.h"
49 * Function pointers for kernel socket routines
51 #ifdef SOLOOKUP_TAKES_SOCKPARAMS
52 struct sonode *(*sockfs_socreate)
53 (struct sockparams *, int, int, int, int, int *) = NULL;
54 int (*sockfs_solookup)
55 (int, int, int, struct sockparams **) = NULL;
57 struct sonode *(*sockfs_socreate)
58 (vnode_t *, int, int, int, int, struct sonode *, int *) = NULL;
59 struct vnode *(*sockfs_solookup)
60 (int, int, int, char *, int *) = NULL;
61 #endif /* SOLOOKUP_TAKES_SOCKPARAMS */
63 (struct sonode *, struct sockaddr *, int, int, int) = NULL;
64 int (*sockfs_sorecvmsg)
65 (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
66 int (*sockfs_sosendmsg)
67 (struct sonode *, struct nmsghdr *, struct uio *) = NULL;
68 int (*sockfs_sosetsockopt)
69 (struct sonode *, int, int, void *, int) = NULL;
70 #ifndef AFS_SUN510_ENV
71 int (*sockfs_sounbind)
72 (struct sonode *, int);
73 void (*sockfs_sockfree)
78 #define UDP_MOD_NAME "udp"
81 static afs_uint32 myNetAddrs[ADDRSPERSITE];
82 static int myNetMTUs[ADDRSPERSITE];
83 static int numMyNetAddrs = 0;
90 #ifndef AFS_SUN510_ENV
95 int mtus[ADDRSPERSITE];
96 afs_uint32 addrs[ADDRSPERSITE];
99 memset(mtus, 0, sizeof(mtus));
100 memset(addrs, 0, sizeof(addrs));
102 #ifdef AFS_SUN510_ENV
103 (void) rw_enter(&afsifinfo_lock, RW_READER);
105 for (i = 0; (afsifinfo[i].ipaddr != NULL) && (i < ADDRSPERSITE); i++) {
107 /* Ignore addresses which are down.. */
108 if (!(afsifinfo[i].flags & IFF_UP))
111 /* Compute the Rx interface MTU */
112 rxmtu = (afsifinfo[i].mtu - RX_IPUDP_SIZE);
114 ifinaddr = afsifinfo[i].ipaddr;
115 if (myNetAddrs[i] != ifinaddr)
118 /* Copy interface MTU and address; adjust maxmtu */
120 rxmtu = rxi_AdjustIfMTU(rxmtu);
121 maxmtu = rxmtu * rxi_nRecvFrags +
122 ((rxi_nRecvFrags - 1) * UDP_HDR_SIZE);
123 maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
126 if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
127 rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu);
129 MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
134 (void) rw_exit(&afsifinfo_lock);
136 rx_maxJumboRecvSize =
137 RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
138 (rxi_nDgramPackets - 1) * RX_JUMBOHEADERSIZE;
139 rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
144 for (j = 0; j < i; j++) {
145 myNetMTUs[j] = mtus[j];
146 myNetAddrs[j] = addrs[j];
154 for (ill = ill_g_head; ill; ill = ill->ill_next) {
156 /* Make sure this is an IPv4 ILL */
161 /* Iterate over all the addresses on this ILL */
162 for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
163 if (i >= ADDRSPERSITE)
166 /* Ignore addresses which are down.. */
167 if (!(ipif->ipif_flags & IFF_UP))
170 /* Compute the Rx interface MTU */
171 rxmtu = (ipif->ipif_mtu - RX_IPUDP_SIZE);
173 ifinaddr = ntohl(ipif->ipif_local_addr);
174 if (myNetAddrs[i] != ifinaddr)
177 /* Copy interface MTU and address; adjust maxmtu */
179 rxmtu = rxi_AdjustIfMTU(rxmtu);
181 rxmtu * rxi_nRecvFrags +
182 ((rxi_nRecvFrags - 1) * UDP_HDR_SIZE);
183 maxmtu = rxi_AdjustMaxMTU(rxmtu, maxmtu);
187 if (ifinaddr != 0x7f000001 && maxmtu > rx_maxReceiveSize) {
188 rx_maxReceiveSize = MIN(RX_MAX_PACKET_SIZE, maxmtu);
190 MIN(rx_maxReceiveSize, rx_maxReceiveSizeUser);
195 rx_maxJumboRecvSize =
196 RX_HEADER_SIZE + rxi_nDgramPackets * RX_JUMBOBUFFERSIZE +
197 (rxi_nDgramPackets - 1) * RX_JUMBOHEADERSIZE;
198 rx_maxJumboRecvSize = MAX(rx_maxJumboRecvSize, rx_maxReceiveSize);
203 for (j = 0; j < i; j++) {
204 myNetMTUs[j] = mtus[j];
205 myNetAddrs[j] = addrs[j];
214 rxi_FindIfMTU(afs_uint32 addr)
216 afs_uint32 myAddr, netMask;
219 #ifdef AFS_SUN510_ENV
226 if (numMyNetAddrs == 0)
228 myAddr = ntohl(addr);
230 if (IN_CLASSA(myAddr))
231 netMask = IN_CLASSA_NET;
232 else if (IN_CLASSB(myAddr))
233 netMask = IN_CLASSB_NET;
234 else if (IN_CLASSC(myAddr))
235 netMask = IN_CLASSC_NET;
239 #ifdef AFS_SUN510_ENV
240 (void) rw_enter(&afsifinfo_lock, RW_READER);
242 for (i = 0; (afsifinfo[i].ipaddr != NULL) && (i < ADDRSPERSITE); i++) {
243 afs_uint32 thisAddr, subnetMask;
246 /* Ignore addresses which are down.. */
247 if ((afsifinfo[i].flags & IFF_UP) == 0)
250 thisAddr = afsifinfo[i].ipaddr;
251 subnetMask = afsifinfo[i].netmask;
252 thisMtu = afsifinfo[i].mtu;
254 if ((myAddr & netMask) == (thisAddr & netMask)) {
255 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
256 if (myAddr == thisAddr) {
261 if (match_value < 3) {
267 if (match_value < 2) {
274 (void) rw_exit(&afsifinfo_lock);
279 for (ill = ill_g_head; ill; ill = ill->ill_next) {
281 /* Make sure this is an IPv4 ILL */
286 /* Iterate over all the addresses on this ILL */
287 for (ipif = ill->ill_ipif; ipif; ipif = ipif->ipif_next) {
288 afs_uint32 thisAddr, subnetMask;
291 thisAddr = ipif->ipif_local_addr;
292 subnetMask = ipif->ipif_net_mask;
293 thisMtu = ipif->ipif_mtu;
295 if ((myAddr & netMask) == (thisAddr & netMask)) {
296 if ((myAddr & subnetMask) == (thisAddr & subnetMask)) {
297 if (myAddr == thisAddr) {
302 if (match_value < 3) {
308 if (match_value < 2) {
320 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
324 struct sockaddr_in rx_sockaddr;
326 /* Allocate a new socket at specified port in network byte order. */
328 rxk_NewSocketHost(afs_uint32 ahost, short aport)
332 struct sockaddr_in addr;
335 #ifdef SOLOOKUP_TAKES_SOCKPARAMS
336 struct sockparams *sp;
339 AFS_STATCNT(osi_NewSocket);
341 if (sockfs_solookup == NULL) {
343 #ifdef SOLOOKUP_TAKES_SOCKPARAMS
344 (int (*)())modlookup("sockfs", "solookup");
346 (struct vnode * (*)())modlookup("sockfs", "solookup");
348 if (sockfs_solookup == NULL) {
352 if (sockfs_socreate == NULL) {
354 (struct sonode * (*)())modlookup("sockfs", "socreate");
355 if (sockfs_socreate == NULL) {
359 if (sockfs_sobind == NULL) {
360 sockfs_sobind = (int (*)())modlookup("sockfs", "sobind");
361 if (sockfs_sobind == NULL) {
365 if (sockfs_sosetsockopt == NULL) {
366 sockfs_sosetsockopt = (int (*)())modlookup("sockfs", "sosetsockopt");
367 if (sockfs_sosetsockopt == NULL) {
371 if (sockfs_sosendmsg == NULL) {
372 sockfs_sosendmsg = (int (*)())modlookup("sockfs", "sosendmsg");
373 if (sockfs_sosendmsg == NULL) {
377 if (sockfs_sorecvmsg == NULL) {
378 sockfs_sorecvmsg = (int (*)())modlookup("sockfs", "sorecvmsg");
379 if (sockfs_sorecvmsg == NULL) {
383 #ifndef AFS_SUN510_ENV
384 if (sockfs_sounbind == NULL) {
385 sockfs_sounbind = (int (*)())modlookup("sockfs", "sounbind");
386 if (sockfs_sounbind == NULL)
389 if (sockfs_sockfree == NULL) {
390 sockfs_sockfree = (void (*)())modlookup("sockfs", "sockfree");
391 if (sockfs_sockfree == NULL)
396 #ifdef SOLOOKUP_TAKES_SOCKPARAMS
397 error = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, &sp);
402 so = sockfs_socreate(sp, AF_INET, SOCK_DGRAM, 0, SOV_STREAM, &error);
404 accessvp = sockfs_solookup(AF_INET, SOCK_DGRAM, 0, "/dev/udp", &error);
405 if (accessvp == NULL) {
409 so = sockfs_socreate(accessvp, AF_INET, SOCK_DGRAM, 0, SOV_STREAM, NULL,
411 #endif /* SOLOOKUP_TAKES_SOCKPARAMS */
417 addr.sin_family = AF_INET;
418 addr.sin_port = aport;
419 addr.sin_addr.s_addr = ahost; /* I wonder what the odds are on
420 needing to unbyteswap this */
421 error = sockfs_sobind(so, (struct sockaddr *)&addr, sizeof(addr), 0, 0);
427 error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_SNDBUF, &len, sizeof(len));
433 error = sockfs_sosetsockopt(so, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
438 return (osi_socket *)so;
442 rxk_NewSocket(short aport)
444 return rxk_NewSocketHost(htonl(INADDR_ANY), aport);
448 osi_FreeSocket(register osi_socket asocket)
450 extern int rxk_ListenerPid;
451 struct sonode *so = (struct sonode *)asocket;
452 struct sockaddr_in taddr;
457 AFS_STATCNT(osi_FreeSocket);
459 taddr.sin_family = AF_INET;
460 taddr.sin_port = rx_port;
461 taddr.sin_addr.s_addr = htonl(0x7f000001);
466 while (rxk_ListenerPid) {
467 osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0);
468 afs_osi_Sleep(&rxk_ListenerPid);
471 /* Was sockfs_sounbind(so, 0); sockfs_sockfree(so); That's wrong */
473 #ifdef AFS_SUN511_ENV
474 VOP_CLOSE(vp, FREAD|FWRITE, 1, (offset_t)0, CRED(), NULL);
476 VOP_CLOSE(vp, FREAD|FWRITE, 1, (offset_t)0, CRED());
484 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
485 int nvecs, afs_int32 asize, int istack)
487 struct sonode *so = (struct sonode *)asocket;
490 struct iovec iov[RX_MAXIOVECS];
494 if (nvecs > RX_MAXIOVECS) {
495 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
498 msg.msg_name = (struct sockaddr *)addr;
499 msg.msg_namelen = sizeof(struct sockaddr_in);
501 msg.msg_iovlen = nvecs;
502 msg.msg_control = NULL;
503 msg.msg_controllen = 0;
506 for (i = 0; i < nvecs; i++) {
507 iov[i].iov_base = dvec[i].iov_base;
508 iov[i].iov_len = dvec[i].iov_len;
510 uio.uio_iov = &iov[0];
511 uio.uio_iovcnt = nvecs;
513 uio.uio_segflg = UIO_SYSSPACE;
514 uio.uio_fmode = FREAD | FWRITE;
516 uio.uio_resid = asize;
518 error = sockfs_sosendmsg(so, &msg, &uio);
524 osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
525 int nvecs, int *alength)
527 struct sonode *asocket = (struct sonode *)so;
530 struct iovec iov[RX_MAXIOVECS];
534 if (nvecs > RX_MAXIOVECS) {
535 osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
539 msg.msg_namelen = sizeof(struct sockaddr_in);
542 msg.msg_control = NULL;
543 msg.msg_controllen = 0;
546 for (i = 0; i < nvecs; i++) {
547 iov[i].iov_base = dvec[i].iov_base;
548 iov[i].iov_len = dvec[i].iov_len;
550 uio.uio_iov = &iov[0];
551 uio.uio_iovcnt = nvecs;
553 uio.uio_segflg = UIO_SYSSPACE;
556 uio.uio_resid = *alength;
558 error = sockfs_sorecvmsg(asocket, &msg, &uio);
560 if (msg.msg_name == NULL) {
563 memcpy(addr, msg.msg_name, msg.msg_namelen);
564 kmem_free(msg.msg_name, msg.msg_namelen);
565 *alength = *alength - uio.uio_resid;
569 if (error == EINTR && ISSIG(curthread, FORREAL)) {
570 klwp_t *lwp = ttolwp(curthread);
571 proc_t *p = ttoproc(curthread);
572 int sig = lwp->lwp_cursig;
574 if (sig == SIGKILL) {
575 mutex_enter(&p->p_lock);
576 p->p_flag &= ~SKILLED;
577 mutex_exit(&p->p_lock);
580 if (lwp->lwp_curinfo) {
581 siginfofree(lwp->lwp_curinfo);
582 lwp->lwp_curinfo = NULL;
589 #if defined(AFS_SUN510_ENV)
590 /* How often afs collects interface info. Tunable via /etc/system: */
591 /* set afs:afs_if_poll_interval = integer (value is in seconds) */
592 static int afs_if_poll_interval = 30;
594 /* Global array which holds the interface info for consumers */
595 struct afs_ifinfo afsifinfo[ADDRSPERSITE];
598 osi_StartNetIfPoller()
600 (void) ddi_taskq_dispatch(afs_taskq, (void(*) (void*)) osi_NetIfPoller,
608 ldi_ident_t li = NULL;
609 ldi_handle_t lh = NULL;
613 struct lifreq *lifrp;
614 struct sockaddr_in *sin4_local;
615 struct sockaddr_in *sin4_dst;
617 caddr_t lifcbuf = NULL;
618 int i, count, error, rv;
625 if (afs_termState == AFSOP_STOP_NETIF) {
626 afs_warn("NetIfPoller... ");
627 rw_destroy(&afsifinfo_lock);
628 ddi_taskq_destroy(afs_taskq);
629 afs_termState = AFSOP_STOP_COMPLETE;
630 osi_rxWakeup(&afs_termState);
633 /* Get our permissions */
636 /* Initialize and open /dev/udp for receiving ioctls */
637 udpmajor = ddi_name_to_major(UDP_MOD_NAME);
639 error = ldi_ident_from_major(udpmajor, &li);
641 cmn_err(CE_WARN, "osi_NetIfPoller: ldi_ident_from_major failed: %d",
646 error = ldi_open_by_name(UDP_DEV_NAME, FREAD, cr, &lh, li);
649 "osi_NetIfPoller: ldi_open_by_name failed: %d", error);
653 /* First, how many interfaces do we have? */
654 (void) bzero((void *)&lifn, sizeof(struct lifnum));
655 lifn.lifn_family = AF_INET;
657 error = ldi_ioctl(lh, SIOCGLIFNUM, (intptr_t)&lifn,
661 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFNUM failed: %d", error);
664 ifcount = lifn.lifn_count;
666 /* Set up some stuff for storing the results of SIOCGLIFCONF */
667 (void) bzero((void *)&lifc, sizeof(struct lifconf));
669 lifcbuf = kmem_zalloc(ifcount * sizeof(struct lifreq), KM_SLEEP);
671 lifc.lifc_family = AF_INET;
672 lifc.lifc_flags = IFF_UP;
673 lifc.lifc_len = ifcount * sizeof(struct lifreq);
674 lifc.lifc_buf = lifcbuf;
676 /* Get info on each of our available interfaces. */
677 error = ldi_ioctl(lh, SIOCGLIFCONF, (intptr_t)&lifc,
681 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFCONF failed: %d", error);
684 lifrp = lifc.lifc_req;
688 /* Loop through our interfaces and pick out the info we want */
689 for (i = lifc.lifc_len / sizeof(struct lifreq);
690 i > 0; i--, lifrp++) {
692 if (count >= ADDRSPERSITE)
695 (void) bzero((void *)&lifr, sizeof(struct lifreq));
697 (void) strncpy(lifr.lifr_name, lifrp->lifr_name,
698 sizeof(lifr.lifr_name));
700 /* Get this interface's Flags */
701 error = ldi_ioctl(lh, SIOCGLIFFLAGS, (intptr_t)&lifr,
705 "osi_NetIfPoller: ldi_ioctl: SIOCGLIFFLAGS failed: %d",
710 /* Ignore plumbed but down interfaces. */
711 if ((lifr.lifr_flags & IFF_UP) == 0)
714 flags = lifr.lifr_flags;
716 /* Get this interface's MTU */
717 error = ldi_ioctl(lh, SIOCGLIFMTU, (intptr_t)&lifr,
723 mtu = lifr.lifr_metric;
726 /* Get this interface's Metric */
727 error = ldi_ioctl(lh, SIOCGLIFMETRIC, (intptr_t)&lifr,
733 metric = lifr.lifr_metric;
736 sin4_local = (struct sockaddr_in *) &lifrp->lifr_addr;
737 sin4_dst = (struct sockaddr_in *) &lifrp->lifr_dstaddr;
739 /* Acquire global array write lock */
740 (void) rw_enter(&afsifinfo_lock, RW_WRITER);
742 /* Copy our collected data into the global array */
743 (void) strncpy(afsifinfo[count].ifname, lifrp->lifr_name,
744 sizeof(afsifinfo[count].ifname));
745 afsifinfo[count].ipaddr = ntohl(sin4_local->sin_addr.s_addr);
746 afsifinfo[count].mtu = mtu;
747 afsifinfo[count].netmask = lifrp->lifr_addrlen;
748 afsifinfo[count].flags = flags;
749 afsifinfo[count].metric = metric;
750 afsifinfo[count].dstaddr = ntohl(sin4_dst->sin_addr.s_addr);
752 /* Release global array write lock */
753 (void) rw_exit(&afsifinfo_lock);
757 } /* Bottom of loop: for each interface ... */
760 /* End of thread. Time to clean up */
762 kmem_free(lifcbuf, ifcount * sizeof(struct lifreq));
764 (void) ldi_close(lh, FREAD, cr);
766 (void) ldi_ident_release(li);
768 /* Schedule this to run again after afs_if_poll_interval seconds */
769 (void) timeout((void(*) (void *)) osi_StartNetIfPoller, NULL,
770 drv_usectohz((clock_t)afs_if_poll_interval * MICROSEC));
773 #endif /* AFS_SUN510_ENV */
776 shutdown_rxkernel(void)
781 osi_StopListener(void)
783 osi_FreeSocket(rx_socket);
786 #else /* AFS_SUN56_ENV */
788 #include "inet/common.h"
789 #include "sys/tiuser.h"
790 #include "sys/t_kuser.h"
791 #include "sys/ioctl.h"
792 #include "sys/stropts.h"
793 #include "sys/stream.h"
794 #include "sys/strsubr.h"
795 #include "sys/vnode.h"
796 #include "sys/stropts.h"
797 #include "sys/tihdr.h"
798 #include "sys/timod.h"
799 #include "sys/fcntl.h"
800 #include "sys/debug.h"
801 #include "inet/common.h"
803 #include "netinet/udp.h"
805 extern dev_t afs_udp_rdev;
815 /* rxi_NewSocket, rxi_FreeSocket and osi_NetSend are from the now defunct
819 dev_t afs_udp_rdev = (dev_t) 0;
821 /* Allocate a new socket at specified port in network byte order. */
823 rxk_NewSocketHost(afs_uint32 ahost, short aport)
826 struct t_bind *reqp, *rspp;
828 struct sockaddr_in *myaddrp;
832 AFS_STATCNT(osi_NewSocket);
833 afs_udp_rdev = makedevice(11 /*CLONE*/, ddi_name_to_major("udp"));
834 code = t_kopen(NULL, afs_udp_rdev, FREAD | FWRITE, &udp_tiptr, CRED());
836 return (osi_socket *)0;
839 code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&reqp);
841 t_kclose(udp_tiptr, 0);
843 code = t_kalloc(udp_tiptr, T_BIND, T_ADDR, (char **)&rspp);
845 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
846 t_kclose(udp_tiptr, 0);
847 return (osi_socket *)0;
850 reqp->addr.len = sizeof(struct sockaddr_in);
851 myaddrp = (struct sockaddr_in *)reqp->addr.buf;
852 myaddrp->sin_family = AF_INET;
853 myaddrp->sin_port = aport;
854 myaddrp->sin_addr.s_addr = ahost; /* byteswap? */
856 code = t_kbind(udp_tiptr, reqp, rspp);
858 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
859 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
860 t_kclose(udp_tiptr, 0);
861 return (osi_socket *)0;
863 if (memcmp(reqp->addr.buf, rspp->addr.buf, rspp->addr.len)) {
864 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
865 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
866 t_kclose(udp_tiptr, 0);
867 return (osi_socket *)0;
869 t_kfree(udp_tiptr, (char *)reqp, T_BIND);
870 t_kfree(udp_tiptr, (char *)rspp, T_BIND);
873 * Set the send and receive buffer sizes.
875 stp = udp_tiptr->fp->f_vnode->v_stream;
877 q->q_hiwat = rx_UdpBufSize;
878 q->q_next->q_hiwat = rx_UdpBufSize;
879 RD(q)->q_hiwat = rx_UdpBufSize;
881 return (osi_socket *)udp_tiptr;
885 rxk_NewSocket(short aport)
887 return rxk_NewSocketHost(htonl(INADDR_ANY), aport);
891 osi_FreeSocket(register osi_socket *asocket)
893 extern int rxk_ListenerPid;
894 TIUSER *udp_tiptr = (TIUSER *) asocket;
895 AFS_STATCNT(osi_FreeSocket);
897 if (rxk_ListenerPid) {
898 kill(rxk_ListenerPid, SIGUSR1);
899 afs_osi_Sleep(&rxk_ListenerPid);
906 osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
907 int nvecs, afs_int32 asize, int istack)
911 TIUSER *udp_tiptr = (TIUSER *) asocket;
912 struct t_kunitdata *udreq;
913 struct sockaddr_in sin;
918 * XXX We don't do any checking on the family since it's assumed to be
921 sin.sin_family = AF_INET;
922 sin.sin_addr.s_addr = addr->sin_addr.s_addr;
923 sin.sin_port = addr->sin_port;
926 * Get a buffer for the RX header
929 osi_Panic("osi_NetSend, nvecs=%d\n", nvecs);
931 while (!(bp = allocb(dvec[0].iov_len, BPRI_LO))) {
932 if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
937 /* Copy the data into the buffer */
938 memcpy((char *)bp->b_wptr, (char *)dvec[0].iov_base, dvec[0].iov_len);
939 bp->b_datap->db_type = M_DATA;
940 bp->b_wptr += dvec[0].iov_len;
943 * Append each element in the iovec to the buffer
945 for (i = 1; i < nvecs; i++) {
946 /* Get a buffer for the next chunk */
947 while (!(dbp = allocb(dvec[i].iov_len, BPRI_LO))) {
948 if (strwaitbuf(dvec[i].iov_len, BPRI_LO)) {
954 /* Copy the data into the buffer */
955 memcpy((char *)dbp->b_wptr, (char *)dvec[i].iov_base,
957 dbp->b_datap->db_type = M_DATA;
958 dbp->b_wptr += dvec[i].iov_len;
960 /* Append it to the message buffer */
965 * Allocate and format the unitdata structure.
967 code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
970 printf("osi_NetSend: t_kalloc failed %d\n", code);
973 udreq->addr.len = sizeof(struct sockaddr_in);
974 udreq->addr.maxlen = sizeof(struct sockaddr_in);
976 (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
978 udreq->opt.maxlen = 0;
979 memcpy(udreq->addr.buf, (char *)&sin, sizeof(struct sockaddr_in));
980 udreq->udata.udata_mp = bp;
981 udreq->udata.len = asize;
983 code = t_ksndudata(udp_tiptr, udreq, NULL);
985 printf("osi_NetSend: t_ksndudata failed %d\n", code);
988 t_kfree(udp_tiptr, (caddr_t) udreq, T_UNITDATA);
994 osi_NetReceive(osi_socket *asocket, struct sockaddr_in *addr,
995 struct iovec *dvec, int nvecs, int *alength)
998 TIUSER *udp_tiptr = (TIUSER *) asocket;
999 struct t_kunitdata *udreq;
1013 * Allocate the unitdata structure.
1015 code = t_kalloc(udp_tiptr, T_UNITDATA, T_UDATA, (char **)&udreq);
1017 printf("osi_NetReceive: t_kalloc failed %d\n", code);
1020 udreq->addr.len = sizeof(struct sockaddr_in);
1021 udreq->addr.maxlen = sizeof(struct sockaddr_in);
1023 (char *)kmem_alloc(sizeof(struct sockaddr_in), KM_SLEEP);
1025 udreq->opt.maxlen = 0;
1028 * Loop until we get an error or receive some data.
1032 * Wait until there is something to do
1034 code = t_kspoll(udp_tiptr, -1, READWAIT, &events);
1036 osi_Panic("osi_NetReceive, infinite t_kspoll timed out\n");
1039 * If there is a message then read it in
1042 code = t_krcvudata(udp_tiptr, udreq, &type, &error);
1046 * Block attempts to kill this thread
1048 if (code == EINTR && ISSIG(curthread, FORREAL)) {
1049 klwp_t *lwp = ttolwp(curthread);
1050 proc_t *p = ttoproc(curthread);
1051 int sig = lwp->lwp_cursig;
1053 if (sig == SIGKILL) {
1054 mutex_enter(&p->p_lock);
1055 p->p_flag &= ~SKILLED;
1056 mutex_exit(&p->p_lock);
1058 lwp->lwp_cursig = 0;
1059 if (lwp->lwp_curinfo) {
1060 kmem_free((caddr_t) lwp->lwp_curinfo,
1061 sizeof(*lwp->lwp_curinfo));
1062 lwp->lwp_curinfo = NULL;
1071 * Ignore non-data message types
1073 if (type != T_DATA) {
1078 * Save the source address
1080 memcpy((char *)addr, udreq->addr.buf, sizeof(struct sockaddr_in));
1083 * Copy out the message buffers, take care not to overflow
1086 dbp = udreq->udata.udata_mp;
1088 for (i = 0; dbp != NULL && length > 0 && i < nvecs; i++) {
1089 tlen = dvec[i].iov_len;
1090 tbase = dvec[i].iov_base;
1091 if (tlen > length) {
1094 while (dbp != NULL && tlen > 0) {
1095 blen = dbp->b_wptr - dbp->b_rptr;
1097 memcpy(tbase, (char *)dbp->b_rptr, tlen);
1099 dbp->b_rptr += tlen;
1102 memcpy(tbase, (char *)dbp->b_rptr, blen);
1110 *alength = *alength - length;
1114 t_kfree(udp_tiptr, (caddr_t) udreq, T_UNITDATA);
1120 osi_StopListener(void)
1122 osi_FreeSocket(rx_socket);
1127 shutdown_rxkernel(void)
1132 #endif /* AFS_SUN56_ENV */
1133 #endif /* AFS_SUN5_ENV */