#include <afsconfig.h>
#include "afs/param.h"
-RCSID("$Header$");
-#ifdef AFS_FBSD40_ENV
#include <sys/malloc.h>
#include "rx/rx_kcommon.h"
#ifdef RXK_LISTENER_ENV
-int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
- int nvecs, int *alength)
+int
+osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr,
+ struct iovec *dvec, int nvecs, int *alength)
{
- struct socket *asocket = (struct socket *)so;
struct uio u;
int i;
struct iovec iov[RX_MAXIOVECS];
int code;
int haveGlock = ISAFS_GLOCK();
- /*AFS_STATCNT(osi_NetReceive);*/
+
+ memset(&u, 0, sizeof(u));
+ memset(&iov, 0, sizeof(iov));
+
+ /*AFS_STATCNT(osi_NetReceive); */
if (nvecs > RX_MAXIOVECS)
- osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
+ osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs);
- for (i = 0 ; i < nvecs ; i++)
- iov[i] = dvec[i];
+ for (i = 0; i < nvecs; i++)
+ iov[i] = dvec[i];
u.uio_iov = &iov[0];
u.uio_iovcnt = nvecs;
u.uio_resid = *alength;
u.uio_segflg = UIO_SYSSPACE;
u.uio_rw = UIO_READ;
- u.uio_procp = NULL;
+ u.uio_td = NULL;
if (haveGlock)
- AFS_GUNLOCK();
+ AFS_GUNLOCK();
code = soreceive(asocket, &sa, &u, NULL, NULL, NULL);
if (haveGlock)
- AFS_GLOCK();
+ AFS_GLOCK();
if (code) {
#if KNET_DEBUG
- if (code == EINVAL)
+ if (code == EINVAL)
Debugger("afs NetReceive busted");
- else
+ else
printf("y");
#else
return code;
if (sa) {
if (sa->sa_family == AF_INET) {
if (addr)
- *addr = *(struct sockaddr_in *) sa;
+ *addr = *(struct sockaddr_in *)sa;
} else
printf("Unknown socket family %d in NetReceive\n", sa->sa_family);
- FREE(sa, M_SONAME);
+ free(sa, M_SONAME);
}
return code;
}
extern int rxk_ListenerPid;
-void osi_StopListener(void)
+void
+osi_StopListener(void)
{
+ struct sockaddr_in taddr;
+ struct iovec dvec;
struct proc *p;
-
+ char c;
+ c = '\0';
+
+ /*
+ * Have to drop global lock to safely do this.
+ * soclose() is currently protected by Giant,
+ * but pfind and psignal are MPSAFE.
+ */
+ int haveGlock = ISAFS_GLOCK();
+ if (haveGlock)
+ AFS_GUNLOCK();
+ soshutdown(rx_socket, SHUT_RDWR);
+ p = pfind(rxk_ListenerPid);
+ if (p) {
+ afs_warn("osi_StopListener: rxk_ListenerPid %u\n", rxk_ListenerPid);
+ kern_psignal(p, SIGUSR1);
+ PROC_UNLOCK(p);
+ } else
+ afs_warn("osi_StopListener: rxk_Listener not found (pid %u)\n",
+ rxk_ListenerPid);
+
+ /* Avoid destroying socket until osi_NetReceive has
+ * had a chance to clean up. Otherwise we can't restart. */
+ bzero(&taddr, sizeof(taddr));
+ taddr.sin_len = sizeof(struct sockaddr_in);
+ taddr.sin_family = AF_INET;
+ taddr.sin_port = rx_port;
+ taddr.sin_addr.s_addr = htonl(0x7f000001); /* no place like localhost */
+ bzero(&dvec, sizeof(dvec));
+ dvec.iov_base = &c;
+ dvec.iov_len = 1;
+ /* afs_osi_Sleep requires the GLOCK */
+ AFS_GLOCK();
+ while(rxk_ListenerPid) {
+ afs_warn("waiting for rxk_ListenerPid to die\n");
+ osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0);
+ afs_osi_Sleep(&rxk_ListenerPid);
+ }
+ AFS_GUNLOCK();
+ /* in theory, we are now the only people doing anything with rx_socket */
soclose(rx_socket);
- p = pfind(rxk_ListenerPid);
- if (p)
- psignal(p, SIGUSR1);
+
+ if (haveGlock)
+ AFS_GLOCK();
}
int
-osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
- struct iovec *dvec, int nvecs, afs_int32 alength, int istack)
+osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
+ int nvecs, afs_int32 alength, int istack)
{
- register afs_int32 code;
+ afs_int32 code;
int i;
struct iovec iov[RX_MAXIOVECS];
struct uio u;
int haveGlock = ISAFS_GLOCK();
+ memset(&u, 0, sizeof(u));
+ memset(&iov, 0, sizeof(iov));
+
AFS_STATCNT(osi_NetSend);
if (nvecs > RX_MAXIOVECS)
- osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
+ osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs);
- for (i = 0 ; i < nvecs ; i++)
- iov[i] = dvec[i];
+ for (i = 0; i < nvecs; i++)
+ iov[i] = dvec[i];
u.uio_iov = &iov[0];
u.uio_iovcnt = nvecs;
u.uio_resid = alength;
u.uio_segflg = UIO_SYSSPACE;
u.uio_rw = UIO_WRITE;
- u.uio_procp = NULL;
+ u.uio_td = NULL;
addr->sin_len = sizeof(struct sockaddr_in);
if (haveGlock)
- AFS_GUNLOCK();
+ AFS_GUNLOCK();
#if KNET_DEBUG
printf("+");
#endif
- code = sosend(asocket, (struct sockaddr *) addr, &u, NULL, NULL, 0, curproc);
+ code =
+ sosend(asocket, (struct sockaddr *)addr, &u, NULL, NULL, 0,
+ curthread);
#if KNET_DEBUG
if (code) {
- if (code == EINVAL)
+ if (code == EINVAL)
Debugger("afs NetSend busted");
- else
+ else
printf("z");
}
#endif
if (haveGlock)
- AFS_GLOCK();
+ AFS_GLOCK();
return code;
}
#else
/* This code *almost* works :( */
static struct protosw parent_proto; /* udp proto switch */
-static void rxk_input (struct mbuf *am, int iphlen);
-static void rxk_fasttimo (void);
+static void rxk_input(struct mbuf *am, int iphlen);
+static void rxk_fasttimo(void);
/* start intercepting basic calls */
-rxk_init() {
- register struct protosw *tpro, *last;
- if (rxk_initDone) return 0;
+rxk_init()
+{
+ struct protosw *tpro, *last;
+ if (rxk_initDone)
+ return 0;
last = inetdomain.dom_protoswNPROTOSW;
for (tpro = inetdomain.dom_protosw; tpro < last; tpro++)
- if (tpro->pr_protocol == IPPROTO_UDP) {
-#if 0 /* not exported */
- /* force UDP checksumming on for AFS */
- extern int udpcksum;
- udpcksum = 1;
-#endif
- memcpy(&parent_proto, tpro, sizeof(parent_proto));
- tpro->pr_input = rxk_input;
- tpro->pr_fasttimo = rxk_fasttimo;
- /*
- * don't bother with pr_drain and pr_ctlinput
- * until we have something to do
- */
- rxk_initDone = 1;
- return 0;
- }
+ if (tpro->pr_protocol == IPPROTO_UDP) {
+ memcpy(&parent_proto, tpro, sizeof(parent_proto));
+ tpro->pr_input = rxk_input;
+ tpro->pr_fasttimo = rxk_fasttimo;
+ /*
+ * don't bother with pr_drain and pr_ctlinput
+ * until we have something to do
+ */
+ rxk_initDone = 1;
+ return 0;
+ }
osi_Panic("inet:no udp");
}
-static void rxk_input (struct mbuf *am, int iphlen)
+static void
+rxk_input(struct mbuf *am, int iphlen)
{
- void (*tproc)();
- register unsigned short *tsp;
+ void (*tproc) ();
+ unsigned short *tsp;
int hdr;
struct udphdr *tu;
- register struct ip *ti;
+ struct ip *ti;
struct udpiphdr *tvu;
- register int i;
+ int i;
char *phandle;
afs_int32 code;
struct sockaddr_in taddr;
NETPRI;
/* make sure we have base ip and udp headers in first mbuf */
- if (iphlen > sizeof (struct ip)) {
- ip_stripoptions(am, NULL);
- iphlen = sizeof (struct ip);
+ if (iphlen > sizeof(struct ip)) {
+ ip_stripoptions(am, NULL);
+ iphlen = sizeof(struct ip);
}
if (am->m_len < sizeof(struct udpiphdr)) {
- am = m_pullup(am, sizeof(struct udpiphdr));
- if (!am) {
+ am = m_pullup(am, sizeof(struct udpiphdr));
+ if (!am) {
USERPRI;
return;
- }
+ }
}
ti = mtod(am, struct ip *);
/* skip basic ip hdr */
- tu = (struct udphdr *)(((char *)ti) + sizeof(struct ip));
-
+ tu = (struct udphdr *)(((char *)ti) + sizeof(struct ip));
+
/* now read the port out */
port = tu->uh_dport;
if (port) {
- for(tsp=rxk_ports, i=0; i<MAXRXPORTS;i++) {
+ for (tsp = rxk_ports, i = 0; i < MAXRXPORTS; i++) {
if (*tsp++ == port) {
/* checksum the packet */
/*
* If not enough data to reflect UDP length, drop.
*/
tvu = (struct udpiphdr *)ti;
- tlen = ntohs((u_short)tvu->ui_ulen);
+ tlen = ntohs((u_short) tvu->ui_ulen);
if ((int)ti->ip_len != tlen) {
if (tlen > (int)ti->ip_len) {
m_free(am);
m_adj(am, tlen - (int)ti->ip_len);
}
/* deliver packet to rx */
- taddr.sin_family = AF_INET; /* compute source address */
+ taddr.sin_family = AF_INET; /* compute source address */
taddr.sin_port = tu->uh_sport;
taddr.sin_addr.s_addr = ti->ip_src.s_addr;
taddr.sin_len = sizeof(taddr);
- tvu = (struct udpiphdr *) ti; /* virtual udp structure, for cksum */
+ tvu = (struct udpiphdr *)ti; /* virtual udp structure, for cksum */
/* handle the checksum. Note that this code damages the actual ip
- header (replacing it with the virtual one, which is the same size),
- so we must ensure we get everything out we need, first */
- if ( tu->uh_sum != 0) {
- /* if the checksum is there, always check it. It's crazy not
- * to, unless you can really be sure that your
- * underlying network (and interfaces and drivers and
- * DMA hardware, etc!) is error-free. First, fill
- * in entire virtual ip header. */
- memset(tvu->ui_i.ih_x1, 0, 9);
- tvu->ui_len = tvu->ui_ulen;
- tlen = ntohs((unsigned short)(tvu->ui_ulen));
- if (in_cksum(am, sizeof(struct ip) + tlen)) {
- /* checksum, including cksum field, doesn't come out 0, so
- this packet is bad */
- m_freem(am);
- USERPRI;
- return;
- }
- }
+ * header (replacing it with the virtual one, which is the same size),
+ * so we must ensure we get everything out we need, first */
+ if (tu->uh_sum != 0) {
+ /* if the checksum is there, always check it. It's crazy not
+ * to, unless you can really be sure that your
+ * underlying network (and interfaces and drivers and
+ * DMA hardware, etc!) is error-free. First, fill
+ * in entire virtual ip header. */
+ memset(tvu->ui_i.ih_x1, 0, 9);
+ tvu->ui_len = tvu->ui_ulen;
+ tlen = ntohs((unsigned short)(tvu->ui_ulen));
+ if (in_cksum(am, sizeof(struct ip) + tlen)) {
+ /* checksum, including cksum field, doesn't come out 0, so
+ * this packet is bad */
+ m_freem(am);
+ USERPRI;
+ return;
+ }
+ }
/*
* 28 is IP (20) + UDP (8) header. ulen includes
*/
data_len = ntohs(tu->uh_ulen);
data_len -= 8;
- AFS_RXGLOCK();
- if (!(*rxk_GetPacketProc)(&phandle, data_len)) {
- if (rx_mb_to_packet(am, m_freem, 28, data_len, phandle)) {
- /* XXX should just increment counter here.. */
- printf("rx: truncated UDP packet\n");
- rxi_FreePacket(phandle);
- }
- else
- (*rxk_PacketArrivalProc)(phandle, &taddr,
- rxk_portRocks[i], data_len);
- }else m_freem(am);
- AFS_RXGUNLOCK();
+ if (!(*rxk_GetPacketProc) (&phandle, data_len)) {
+ if (rx_mb_to_packet(am, m_freem, 28, data_len, phandle)) {
+ /* XXX should just increment counter here.. */
+ printf("rx: truncated UDP packet\n");
+ rxi_FreePacket(phandle);
+ } else
+ (*rxk_PacketArrivalProc) (phandle, &taddr,
+ rxk_portRocks[i], data_len);
+ } else
+ m_freem(am);
USERPRI;
return;
- }
}
}
+ }
/* if we get here, try to deliver packet to udp */
- if (tproc = parent_proto.pr_input) (*tproc)(am,iphlen);
+ if (tproc = parent_proto.pr_input)
+ (*tproc) (am, iphlen);
USERPRI;
return;
}
* Called about 5 times per second (at unknown priority?). Must go to
* splnet or obtain global lock before touching anything significant.
*/
-static void rxk_fasttimo (void)
+static void
+rxk_fasttimo(void)
{
- void (*tproc)();
+ void (*tproc) ();
struct clock temp;
/* do rx fasttimo processing here */
rxevent_RaiseEvents(&temp);
- if (tproc = parent_proto.pr_fasttimo) (*tproc)();
+ if (tproc = parent_proto.pr_fasttimo)
+ (*tproc) ();
}
/* rx_NetSend - send asize bytes at adata from asocket to host at addr.
/* set lock on sockbuf sb; can't call sblock since we're at interrupt level
* sometimes */
-static trysblock(sb)
-register struct sockbuf *sb; {
+static
+trysblock(sb)
+ struct sockbuf *sb;
+{
AFS_STATCNT(trysblock);
- if (sb->sb_flags & SB_LOCK){
- return -1; /* can't lock socket */
+ if (sb->sb_flags & SB_LOCK) {
+ return -1; /* can't lock socket */
}
sb->sb_flags |= SB_LOCK;
return 0;
/* We only have to do all the mbuf management ourselves if we can be called at
interrupt time. in RXK_LISTENER_ENV, we can just call sosend() */
-int
-osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
- struct iovec *dvec, int nvec, afs_int32 asize, int istack)
+int
+osi_NetSend(osi_socket asocket, struct sockaddr_in *addr, struct iovec *dvec,
+ int nvec, afs_int32 asize, int istack)
{
- register struct mbuf *tm, *um;
- register afs_int32 code;
+ struct mbuf *tm, *um;
+ afs_int32 code;
int s;
struct mbuf *top = 0;
- register struct mbuf *m, **mp;
+ struct mbuf *m, **mp;
int len;
char *tdata;
caddr_t tpa;
- int i,tl,rlen;
+ int i, tl, rlen;
int mlen;
int haveGlock;
#if KNET_DEBUG
- static int before=0;
+ static int before = 0;
#endif
AFS_STATCNT(osi_NetSend);
* reuse the buffers after sending, so we lost out on that trick anyway */
s = splnet();
if (trysblock(&asocket->so_snd)) {
- splx(s);
- return 1;
+ splx(s);
+ return 1;
}
mp = ⊤
i = 0;
tl = dvec[i].iov_len;
while (1) {
mlen = MLEN;
- if (top == 0) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (!m) {
- sbunlock(&asocket->so_snd);
- splx(s);
- return 1;
- }
- mlen = MHLEN;
- m->m_pkthdr.len = 0;
- m->m_pkthdr.rcvif = NULL;
- } else
- MGET(m, M_DONTWAIT, MT_DATA);
+ if (top == 0) {
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (!m) {
+ sbunlock(&asocket->so_snd);
+ splx(s);
+ return 1;
+ }
+ mlen = MHLEN;
+ m->m_pkthdr.len = 0;
+ m->m_pkthdr.rcvif = NULL;
+ } else
+ MGET(m, M_DONTWAIT, MT_DATA);
if (!m) {
/* can't get an mbuf, give up */
- if (top) m_freem(top); /* free mbuf list we're building */
- sbunlock(&asocket->so_snd);
+ if (top)
+ m_freem(top); /* free mbuf list we're building */
+ sbunlock(&asocket->so_snd);
splx(s);
return 1;
}
*/
if (asize >= 4 * MLEN) { /* try to get cluster mbuf */
/* different algorithms for getting cluster mbuf */
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0)
- goto nopages;
- mlen = MCLBYTES;
+ MCLGET(m, M_DONTWAIT);
+ if ((m->m_flags & M_EXT) == 0)
+ goto nopages;
+ mlen = MCLBYTES;
/* now compute usable size */
- len = MIN(mlen, asize);
+ len = MIN(mlen, asize);
/* Should I look at MAPPED_MBUFS??? */
} else {
-nopages:
- len = MIN(mlen, asize);
+ nopages:
+ len = MIN(mlen, asize);
}
m->m_len = 0;
- *mp = m; /* XXXX */
- top->m_pkthdr.len += len;
+ *mp = m; /* XXXX */
+ top->m_pkthdr.len += len;
tpa = mtod(m, caddr_t);
while (len) {
- rlen = MIN(len, tl);
- memcpy(tpa, tdata, rlen);
- asize -= rlen;
- len -= rlen;
- tpa += rlen;
- m->m_len += rlen;
- tdata += rlen;
- tl -= rlen;
- if (tl <= 0) {
- i++;
- if (i > nvec) {
- /* shouldn't come here! */
- asize = 0; /* so we make progress toward completion */
- break;
+ rlen = MIN(len, tl);
+ memcpy(tpa, tdata, rlen);
+ asize -= rlen;
+ len -= rlen;
+ tpa += rlen;
+ m->m_len += rlen;
+ tdata += rlen;
+ tl -= rlen;
+ if (tl <= 0) {
+ i++;
+ if (i > nvec) {
+ /* shouldn't come here! */
+ asize = 0; /* so we make progress toward completion */
+ break;
+ }
+ tdata = dvec[i].iov_base;
+ tl = dvec[i].iov_len;
}
- tdata = dvec[i].iov_base;
- tl = dvec[i].iov_len;
- }
}
*mp = m;
mp = &m->m_next;
if (asize <= 0)
- break;
+ break;
}
tm = top;
/* setup mbuf corresponding to destination address */
um = m_get(M_DONTWAIT, MT_SONAME);
if (!um) {
- if (top) m_freem(top); /* free mbuf chain */
- sbunlock(&asocket->so_snd);
+ if (top)
+ m_freem(top); /* free mbuf chain */
+ sbunlock(&asocket->so_snd);
splx(s);
return 1;
}
/* note that udp_usrreq frees funny mbuf. We hold onto data, but mbuf
* around it is gone. */
/* haveGlock = ISAFS_GLOCK();
- if (haveGlock) {
- AFS_GUNLOCK();
- } */
+ * if (haveGlock) {
+ * AFS_GUNLOCK();
+ * } */
/* SOCKET_LOCK(asocket); */
/* code = (*asocket->so_proto->pr_usrreq)(asocket, PRU_SEND, tm, um, 0); */
#if KNET_DEBUG
- if (before) Debugger("afs NetSend before");
+ if (before)
+ Debugger("afs NetSend before");
#endif
- code = (*asocket->so_proto->pr_usrreqs->pru_send)(asocket, 0, tm,
- (struct sockaddr *) addr,
- um, &proc0);
+ code =
+ (*asocket->so_proto->pr_usrreqs->pru_send) (asocket, 0, tm,
+ (struct sockaddr *)
+ addr, um, &proc0);
/* SOCKET_UNLOCK(asocket); */
/* if (haveGlock) {
- AFS_GLOCK();
- } */
+ * AFS_GLOCK();
+ * } */
sbunlock(&asocket->so_snd);
splx(s);
#if KNET_DEBUG
if (code) {
- if (code == EINVAL)
- Debugger("afs NetSend busted");
- else
- printf("z");
+ if (code == EINVAL)
+ Debugger("afs NetSend busted");
+ else
+ printf("z");
}
#endif
return code;
}
#endif
-
-#endif /* AFS_FBSD40_ENV */