FBSD: Handle malloc/free changes in FBSD 12
[openafs.git] / src / rx / FBSD / rx_knet.c
index 4fe2ba6..cae6cac 100644 (file)
 #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];
@@ -28,13 +26,17 @@ int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
     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;
@@ -42,19 +44,19 @@ int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
     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;
@@ -64,41 +66,86 @@ int osi_NetReceive(osi_socket so, struct sockaddr_in *addr, struct iovec *dvec,
     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;
@@ -106,70 +153,70 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
     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;
@@ -181,28 +228,28 @@ static void rxk_input (struct mbuf *am, int iphlen)
     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 */
                /*
@@ -210,7 +257,7 @@ static void rxk_input (struct mbuf *am, int iphlen)
                 * 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);
@@ -220,31 +267,31 @@ static void rxk_input (struct mbuf *am, int iphlen)
                    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
@@ -253,26 +300,25 @@ static void rxk_input (struct mbuf *am, int iphlen)
                 */
                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;
 }
@@ -283,14 +329,16 @@ static void rxk_input (struct mbuf *am, int iphlen)
  * 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.
@@ -311,11 +359,13 @@ static void rxk_fasttimo (void)
 
 /* 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;
@@ -323,23 +373,23 @@ register struct sockbuf *sb; {
 
 /* 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);
@@ -349,8 +399,8 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
  * 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 = &top;
     i = 0;
@@ -358,22 +408,23 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
     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;
        }
@@ -389,46 +440,46 @@ osi_NetSend(osi_socket asocket, struct sockaddr_in *addr,
         */
        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;
 
@@ -437,8 +488,9 @@ nopages:
     /* 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;
     }
@@ -447,33 +499,33 @@ nopages:
     /* 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 */