optimize boot program
[unix-history] / usr / src / sys / netns / spp_usrreq.c
index 67ebb58..d742236 100644 (file)
@@ -1,41 +1,35 @@
 /*
 /*
- * Copyright (c) 1984, 1985, 1986, 1987 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1984, 1985, 1986, 1987, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of California at Berkeley. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
+ * %sccs.include.redist.c%
  *
  *
- *      @(#)spp_usrreq.c       7.6 (Berkeley) %G%
+ *     @(#)spp_usrreq.c        8.1 (Berkeley) %G%
  */
 
  */
 
-#include "param.h"
-#include "systm.h"
-#include "dir.h"
-#include "user.h"
-#include "mbuf.h"
-#include "protosw.h"
-#include "socket.h"
-#include "socketvar.h"
-#include "errno.h"
-
-#include "../net/if.h"
-#include "../net/route.h"
-#include "../netinet/tcp_fsm.h"
-
-#include "ns.h"
-#include "ns_pcb.h"
-#include "idp.h"
-#include "idp_var.h"
-#include "ns_error.h"
-#include "sp.h"
-#include "spidp.h"
-#include "spp_timer.h"
-#include "spp_var.h"
-#include "spp_debug.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/tcp_fsm.h>
+
+#include <netns/ns.h>
+#include <netns/ns_pcb.h>
+#include <netns/idp.h>
+#include <netns/idp_var.h>
+#include <netns/ns_error.h>
+#include <netns/sp.h>
+#include <netns/spidp.h>
+#include <netns/spp_timer.h>
+#include <netns/spp_var.h>
+#include <netns/spp_debug.h>
 
 /*
  * SP protocol implementation.
 
 /*
  * SP protocol implementation.
@@ -50,12 +44,12 @@ int traceallspps = 0;
 extern int sppconsdebug;
 int spp_hardnosed;
 int spp_use_delack = 0;
 extern int sppconsdebug;
 int spp_hardnosed;
 int spp_use_delack = 0;
+u_short spp_newchecks[50];
 
 /*ARGSUSED*/
 
 /*ARGSUSED*/
-spp_input(m, nsp, ifp)
+spp_input(m, nsp)
        register struct mbuf *m;
        register struct nspcb *nsp;
        register struct mbuf *m;
        register struct nspcb *nsp;
-       struct ifnet *ifp;
 {
        register struct sppcb *cb;
        register struct spidp *si = mtod(m, struct spidp *);
 {
        register struct sppcb *cb;
        register struct spidp *si = mtod(m, struct spidp *);
@@ -91,8 +85,8 @@ spp_input(m, nsp, ifp)
        }
        if (so->so_options & SO_ACCEPTCONN) {
                struct sppcb *ocb = cb;
        }
        if (so->so_options & SO_ACCEPTCONN) {
                struct sppcb *ocb = cb;
-               struct socket *oso = so;
-               so = sonewconn(so);
+
+               so = sonewconn(so, 0);
                if (so == 0) {
                        goto drop;
                }
                if (so == 0) {
                        goto drop;
                }
@@ -113,10 +107,7 @@ spp_input(m, nsp, ifp)
                cb = nstosppcb(nsp);
                cb->s_mtu = ocb->s_mtu;         /* preserve sockopts */
                cb->s_flags = ocb->s_flags;     /* preserve sockopts */
                cb = nstosppcb(nsp);
                cb->s_mtu = ocb->s_mtu;         /* preserve sockopts */
                cb->s_flags = ocb->s_flags;     /* preserve sockopts */
-               if (so->so_snd.sb_hiwat != oso->so_snd.sb_hiwat) /*XXX*/
-                       sbreserve(&so->so_snd, oso->so_snd.sb_hiwat);
-               if (so->so_rcv.sb_hiwat != oso->so_rcv.sb_hiwat) /*XXX*/
-                       sbreserve(&so->so_rcv, oso->so_rcv.sb_hiwat);
+               cb->s_flags2 = ocb->s_flags2;   /* preserve sockopts */
                cb->s_state = TCPS_LISTEN;
        }
 
                cb->s_state = TCPS_LISTEN;
        }
 
@@ -148,6 +139,7 @@ spp_input(m, nsp, ifp)
                        goto drop;
                am->m_len = sizeof (struct sockaddr_ns);
                sns = mtod(am, struct sockaddr_ns *);
                        goto drop;
                am->m_len = sizeof (struct sockaddr_ns);
                sns = mtod(am, struct sockaddr_ns *);
+               sns->sns_len = sizeof(*sns);
                sns->sns_family = AF_NS;
                sns->sns_addr = si->si_sna;
                laddr = nsp->nsp_laddr;
                sns->sns_family = AF_NS;
                sns->sns_addr = si->si_sna;
                laddr = nsp->nsp_laddr;
@@ -231,7 +223,8 @@ spp_input(m, nsp, ifp)
                spp_trace(SA_INPUT, (u_char)ostate, cb, &spp_savesi, 0);
 
        m->m_len -= sizeof (struct idp);
                spp_trace(SA_INPUT, (u_char)ostate, cb, &spp_savesi, 0);
 
        m->m_len -= sizeof (struct idp);
-       m->m_off += sizeof (struct idp);
+       m->m_pkthdr.len -= sizeof (struct idp);
+       m->m_data += sizeof (struct idp);
 
        if (spp_reass(cb, si)) {
                (void) m_freem(m);
 
        if (spp_reass(cb, si)) {
                (void) m_freem(m);
@@ -379,8 +372,8 @@ register struct spidp *si;
         */
        incr = CUNIT;
        if (cb->s_cwnd > cb->s_ssthresh)
         */
        incr = CUNIT;
        if (cb->s_cwnd > cb->s_ssthresh)
-               incr = MAX(incr * incr / cb->s_cwnd, 1);
-       cb->s_cwnd = MIN(cb->s_cwnd + incr, cb->s_cwmx);
+               incr = max(incr * incr / cb->s_cwnd, 1);
+       cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx);
        /*
         * Trim Acked data from output queue.
         */
        /*
         * Trim Acked data from output queue.
         */
@@ -390,8 +383,7 @@ register struct spidp *si;
                else
                        break;
        }
                else
                        break;
        }
-       if ((so->so_snd.sb_flags & SB_WAIT) || so->so_snd.sb_sel)
-                sowwakeup(so);
+       sowwakeup(so);
        cb->s_rack = si->si_ack;
 update_window:
        if (SSEQ_LT(cb->s_snxt, cb->s_rack))
        cb->s_rack = si->si_ack;
 update_window:
        if (SSEQ_LT(cb->s_snxt, cb->s_rack))
@@ -502,12 +494,51 @@ present:
                        remque(q->si_next);
                        wakeup = 1;
                        sppstat.spps_rcvpack++;
                        remque(q->si_next);
                        wakeup = 1;
                        sppstat.spps_rcvpack++;
+#ifdef SF_NEWCALL
+                       if (cb->s_flags2 & SF_NEWCALL) {
+                               struct sphdr *sp = mtod(m, struct sphdr *);
+                               u_char dt = sp->sp_dt;
+                               spp_newchecks[4]++;
+                               if (dt != cb->s_rhdr.sp_dt) {
+                                       struct mbuf *mm =
+                                          m_getclr(M_DONTWAIT, MT_CONTROL);
+                                       spp_newchecks[0]++;
+                                       if (mm != NULL) {
+                                               u_short *s =
+                                                       mtod(mm, u_short *);
+                                               cb->s_rhdr.sp_dt = dt;
+                                               mm->m_len = 5; /*XXX*/
+                                               s[0] = 5;
+                                               s[1] = 1;
+                                               *(u_char *)(&s[2]) = dt;
+                                               sbappend(&so->so_rcv, mm);
+                                       }
+                               }
+                               if (sp->sp_cc & SP_OB) {
+                                       MCHTYPE(m, MT_OOBDATA);
+                                       spp_newchecks[1]++;
+                                       so->so_oobmark = 0;
+                                       so->so_state &= ~SS_RCVATMARK;
+                               }
+                               if (packetp == 0) {
+                                       m->m_data += SPINC;
+                                       m->m_len -= SPINC;
+                                       m->m_pkthdr.len -= SPINC;
+                               }
+                               if ((sp->sp_cc & SP_EM) || packetp) {
+                                       sbappendrecord(&so->so_rcv, m);
+                                       spp_newchecks[9]++;
+                               } else
+                                       sbappend(&so->so_rcv, m);
+                       } else
+#endif
                        if (packetp) {
                                sbappendrecord(&so->so_rcv, m);
                        } else {
                                cb->s_rhdr = *mtod(m, struct sphdr *);
                        if (packetp) {
                                sbappendrecord(&so->so_rcv, m);
                        } else {
                                cb->s_rhdr = *mtod(m, struct sphdr *);
-                               m->m_off += SPINC;
+                               m->m_data += SPINC;
                                m->m_len -= SPINC;
                                m->m_len -= SPINC;
+                               m->m_pkthdr.len -= SPINC;
                                sbappend(&so->so_rcv, m);
                        }
                  } else
                                sbappend(&so->so_rcv, m);
                        }
                  } else
@@ -648,9 +679,12 @@ spp_output(cb, m0)
        register struct spidp *si = (struct spidp *) 0;
        register struct sockbuf *sb = &so->so_snd;
        int len = 0, win, rcv_win;
        register struct spidp *si = (struct spidp *) 0;
        register struct sockbuf *sb = &so->so_snd;
        int len = 0, win, rcv_win;
-       short span, off;
+       short span, off, recordp = 0;
        u_short alo;
        u_short alo;
-       int error = 0, idle, sendalot;
+       int error = 0, sendalot;
+#ifdef notdef
+       int idle;
+#endif
        struct mbuf *mprev;
        extern int idpcksum;
 
        struct mbuf *mprev;
        extern int idpcksum;
 
@@ -663,6 +697,8 @@ spp_output(cb, m0)
                for (m = m0; m ; m = m->m_next) {
                        mprev = m;
                        len += m->m_len;
                for (m = m0; m ; m = m->m_next) {
                        mprev = m;
                        len += m->m_len;
+                       if (m->m_flags & M_EOR)
+                               recordp = 1;
                }
                datalen = (cb->s_flags & SF_HO) ?
                                len - sizeof (struct sphdr) : len;
                }
                datalen = (cb->s_flags & SF_HO) ?
                                len - sizeof (struct sphdr) : len;
@@ -675,14 +711,22 @@ spp_output(cb, m0)
 
                                cb->s_cc &= ~SP_EM;
                                while (len > mtu) {
 
                                cb->s_cc &= ~SP_EM;
                                while (len > mtu) {
-                                       m = m_copy(m0, 0, mtu);
-                                       if (m == NULL) {
-                                               error = ENOBUFS;
-                                               goto bad_copy;
+                                       /*
+                                        * Here we are only being called
+                                        * from usrreq(), so it is OK to
+                                        * block.
+                                        */
+                                       m = m_copym(m0, 0, mtu, M_WAIT);
+                                       if (cb->s_flags & SF_NEWCALL) {
+                                           struct mbuf *mm = m;
+                                           spp_newchecks[7]++;
+                                           while (mm) {
+                                               mm->m_flags &= ~M_EOR;
+                                               mm = mm->m_next;
+                                           }
                                        }
                                        error = spp_output(cb, m);
                                        if (error) {
                                        }
                                        error = spp_output(cb, m);
                                        if (error) {
-                                       bad_copy:
                                                cb->s_cc |= oldEM;
                                                m_freem(m0);
                                                return(error);
                                                cb->s_cc |= oldEM;
                                                m_freem(m0);
                                                return(error);
@@ -699,7 +743,7 @@ spp_output(cb, m0)
                 */
                if (len & 1) {
                        m = mprev;
                 */
                if (len & 1) {
                        m = mprev;
-                       if (m->m_len + m->m_off < MMAXOFF)
+                       if (M_TRAILINGSPACE(m) >= 1)
                                m->m_len++;
                        else {
                                struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
                                m->m_len++;
                        else {
                                struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
@@ -709,11 +753,11 @@ spp_output(cb, m0)
                                        return (ENOBUFS);
                                }
                                m1->m_len = 1;
                                        return (ENOBUFS);
                                }
                                m1->m_len = 1;
-                               m1->m_off = MMAXOFF - 1;
+                               *(mtod(m1, u_char *)) = 0;
                                m->m_next = m1;
                        }
                }
                                m->m_next = m1;
                        }
                }
-               m = m_get(M_DONTWAIT, MT_HEADER);
+               m = m_gethdr(M_DONTWAIT, MT_HEADER);
                if (m == 0) {
                        m_freem(m0);
                        return (ENOBUFS);
                if (m == 0) {
                        m_freem(m0);
                        return (ENOBUFS);
@@ -721,9 +765,8 @@ spp_output(cb, m0)
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
-                * Long align so prepended ip headers will work on Gould.
                 */
                 */
-               m->m_off = MMAXOFF - sizeof (struct spidp) - 2;
+               MH_ALIGN(m, sizeof (struct spidp));
                m->m_len = sizeof (struct spidp);
                m->m_next = m0;
                si = mtod(m, struct spidp *);
                m->m_len = sizeof (struct spidp);
                m->m_next = m0;
                si = mtod(m, struct spidp *);
@@ -743,10 +786,14 @@ spp_output(cb, m0)
                        si->si_dt = sh->sp_dt;
                        si->si_cc |= sh->sp_cc & SP_EM;
                        m0->m_len -= sizeof (*sh);
                        si->si_dt = sh->sp_dt;
                        si->si_cc |= sh->sp_cc & SP_EM;
                        m0->m_len -= sizeof (*sh);
-                       m0->m_off += sizeof (*sh);
+                       m0->m_data += sizeof (*sh);
                        len -= sizeof (*sh);
                }
                len += sizeof(*si);
                        len -= sizeof (*sh);
                }
                len += sizeof(*si);
+               if ((cb->s_flags2 & SF_NEWCALL) && recordp) {
+                       si->si_cc  |= SP_EM;
+                       spp_newchecks[8]++;
+               }
                if (cb->s_oobflags & SF_SOOB) {
                        /*
                         * Per jqj@cornell:
                if (cb->s_oobflags & SF_SOOB) {
                        /*
                         * Per jqj@cornell:
@@ -762,17 +809,20 @@ spp_output(cb, m0)
                        }
                }
                si->si_len = htons((u_short)len);
                        }
                }
                si->si_len = htons((u_short)len);
+               m->m_pkthdr.len = ((len - 1) | 1) + 1;
                /*
                 * queue stuff up for output
                 */
                sbappendrecord(sb, m);
                cb->s_seq++;
        }
                /*
                 * queue stuff up for output
                 */
                sbappendrecord(sb, m);
                cb->s_seq++;
        }
+#ifdef notdef
        idle = (cb->s_smax == (cb->s_rack - 1));
        idle = (cb->s_smax == (cb->s_rack - 1));
+#endif
 again:
        sendalot = 0;
        off = cb->s_snxt - cb->s_rack;
 again:
        sendalot = 0;
        off = cb->s_snxt - cb->s_rack;
-       win = MIN(cb->s_swnd, (cb->s_cwnd/CUNIT));
+       win = min(cb->s_swnd, (cb->s_cwnd/CUNIT));
 
        /*
         * If in persist timeout with window of 0, send a probe.
 
        /*
         * If in persist timeout with window of 0, send a probe.
@@ -787,7 +837,7 @@ again:
                }
        }
        span = cb->s_seq - cb->s_rack;
                }
        }
        span = cb->s_seq - cb->s_rack;
-       len = MIN(span, win) - off;
+       len = min(span, win) - off;
 
        if (len < 0) {
                /*
 
        if (len < 0) {
                /*
@@ -907,7 +957,6 @@ send:
                if (m == NULL) {
                        return (ENOBUFS);
                }
                if (m == NULL) {
                        return (ENOBUFS);
                }
-               m0 = m;
                si = mtod(m, struct spidp *);
                if (SSEQ_LT(si->si_seq, cb->s_smax))
                        sppstat.spps_sndrexmitpack++;
                si = mtod(m, struct spidp *);
                if (SSEQ_LT(si->si_seq, cb->s_smax))
                        sppstat.spps_sndrexmitpack++;
@@ -921,19 +970,16 @@ send:
                        sppstat.spps_sndprobe++;
                if (cb->s_flags & SF_ACKNOW)
                        sppstat.spps_sndacks++;
                        sppstat.spps_sndprobe++;
                if (cb->s_flags & SF_ACKNOW)
                        sppstat.spps_sndacks++;
-               m = m_get(M_DONTWAIT, MT_HEADER);
-               if (m == 0) {
+               m = m_gethdr(M_DONTWAIT, MT_HEADER);
+               if (m == 0)
                        return (ENOBUFS);
                        return (ENOBUFS);
-               }
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
                /*
                 * Fill in mbuf with extended SP header
                 * and addresses and length put into network format.
-                * Allign beginning of packet to long to prepend
-                * ifp's on loopback, or NSIP encaspulation for fussy cpu's.
                 */
                 */
-               m->m_off = MMAXOFF - sizeof (struct spidp) - 2;
+               MH_ALIGN(m, sizeof (struct spidp));
                m->m_len = sizeof (*si);
                m->m_len = sizeof (*si);
-               m->m_next = 0;
+               m->m_pkthdr.len = sizeof (*si);
                si = mtod(m, struct spidp *);
                si->si_i = *cb->s_idp;
                si->si_s = cb->s_shdr;
                si = mtod(m, struct spidp *);
                si->si_i = *cb->s_idp;
                si->si_s = cb->s_shdr;
@@ -1004,7 +1050,7 @@ send:
                        len = ntohs(si->si_len);
                        if (len & 1)
                                len++;
                        len = ntohs(si->si_len);
                        if (len & 1)
                                len++;
-                       si->si_sum = ns_cksum(dtom(si), len);
+                       si->si_sum = ns_cksum(m, len);
                } else
                        si->si_sum = 0xffff;
 
                } else
                        si->si_sum = 0xffff;
 
@@ -1097,25 +1143,21 @@ spp_ctloutput(req, so, level, name, value)
                        mask = SF_HO;
                get_flags:
                        m->m_len = sizeof(short);
                        mask = SF_HO;
                get_flags:
                        m->m_len = sizeof(short);
-                       m->m_off = MMAXOFF - sizeof(short);
                        *mtod(m, short *) = cb->s_flags & mask;
                        break;
 
                case SO_MTU:
                        m->m_len = sizeof(u_short);
                        *mtod(m, short *) = cb->s_flags & mask;
                        break;
 
                case SO_MTU:
                        m->m_len = sizeof(u_short);
-                       m->m_off = MMAXOFF - sizeof(short);
                        *mtod(m, short *) = cb->s_mtu;
                        break;
 
                case SO_LAST_HEADER:
                        m->m_len = sizeof(struct sphdr);
                        *mtod(m, short *) = cb->s_mtu;
                        break;
 
                case SO_LAST_HEADER:
                        m->m_len = sizeof(struct sphdr);
-                       m->m_off = MMAXOFF - sizeof(struct sphdr);
                        *mtod(m, struct sphdr *) = cb->s_rhdr;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct spidp);
                        *mtod(m, struct sphdr *) = cb->s_rhdr;
                        break;
 
                case SO_DEFAULT_HEADERS:
                        m->m_len = sizeof(struct spidp);
-                       m->m_off = MMAXOFF - sizeof(struct sphdr);
                        *mtod(m, struct sphdr *) = cb->s_shdr;
                        break;
 
                        *mtod(m, struct sphdr *) = cb->s_shdr;
                        break;
 
@@ -1153,6 +1195,19 @@ spp_ctloutput(req, so, level, name, value)
                        cb->s_mtu = *(mtod(*value, u_short *));
                        break;
 
                        cb->s_mtu = *(mtod(*value, u_short *));
                        break;
 
+#ifdef SF_NEWCALL
+               case SO_NEWCALL:
+                       ok = mtod(*value, int *);
+                       if (*ok) {
+                               cb->s_flags2 |= SF_NEWCALL;
+                               spp_newchecks[5]++;
+                       } else {
+                               cb->s_flags2 &= ~SF_NEWCALL;
+                               spp_newchecks[6]++;
+                       }
+                       break;
+#endif
+
                case SO_DEFAULT_HEADERS:
                        {
                                register struct sphdr *sp
                case SO_DEFAULT_HEADERS:
                        {
                                register struct sphdr *sp
@@ -1173,10 +1228,10 @@ spp_ctloutput(req, so, level, name, value)
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-spp_usrreq(so, req, m, nam, rights)
+spp_usrreq(so, req, m, nam, controlp)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam, *rights;
+       struct mbuf *m, *nam, *controlp;
 {
        struct nspcb *nsp = sotonspcb(so);
        register struct sppcb *cb;
 {
        struct nspcb *nsp = sotonspcb(so);
        register struct sppcb *cb;
@@ -1187,11 +1242,7 @@ spp_usrreq(so, req, m, nam, rights)
 
        if (req == PRU_CONTROL)
                 return (ns_control(so, (int)m, (caddr_t)nam,
 
        if (req == PRU_CONTROL)
                 return (ns_control(so, (int)m, (caddr_t)nam,
-                       (struct ifnet *)rights));
-       if (rights && rights->m_len) {
-               error = EINVAL;
-               goto release;
-       }
+                       (struct ifnet *)controlp));
        if (nsp == NULL) {
                if (req != PRU_ATTACH) {
                        error = EINVAL;
        if (nsp == NULL) {
                if (req != PRU_ATTACH) {
                        error = EINVAL;
@@ -1212,9 +1263,11 @@ spp_usrreq(so, req, m, nam, rights)
                error = ns_pcballoc(so, &nspcb);
                if (error)
                        break;
                error = ns_pcballoc(so, &nspcb);
                if (error)
                        break;
-               error = soreserve(so, 3072, 3072);
-               if (error)
-                       break;
+               if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+                       error = soreserve(so, (u_long) 3072, (u_long) 3072);
+                       if (error)
+                               break;
+               }
                nsp = sotonspcb(so);
 
                mm = m_getclr(M_DONTWAIT, MT_PCB);
                nsp = sotonspcb(so);
 
                mm = m_getclr(M_DONTWAIT, MT_PCB);
@@ -1227,7 +1280,7 @@ spp_usrreq(so, req, m, nam, rights)
                cb = mtod(mm, struct sppcb *);
                mm = m_getclr(M_DONTWAIT, MT_HEADER);
                if (mm == NULL) {
                cb = mtod(mm, struct sppcb *);
                mm = m_getclr(M_DONTWAIT, MT_HEADER);
                if (mm == NULL) {
-                       m_free(dtom(m));
+                       (void) m_free(dtom(m));
                        error = ENOBUFS;
                        break;
                }
                        error = ENOBUFS;
                        break;
                }
@@ -1240,7 +1293,7 @@ spp_usrreq(so, req, m, nam, rights)
                cb->s_mtu = 576 - sizeof (struct spidp);
                cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
                cb->s_ssthresh = cb->s_cwnd;
                cb->s_mtu = 576 - sizeof (struct spidp);
                cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu;
                cb->s_ssthresh = cb->s_cwnd;
-               cb->s_cwmx = sb->sb_mbmax * CUNIT /
+               cb->s_cwmx = sbspace(sb) * CUNIT /
                                (2 * sizeof (struct spidp));
                /* Above is recomputed when connecting to account
                   for changed buffering or mtu's */
                                (2 * sizeof (struct spidp));
                /* Above is recomputed when connecting to account
                   for changed buffering or mtu's */
@@ -1380,6 +1433,16 @@ spp_usrreq(so, req, m, nam, rights)
                cb->s_oobflags |= SF_SOOB;
                /* fall into */
        case PRU_SEND:
                cb->s_oobflags |= SF_SOOB;
                /* fall into */
        case PRU_SEND:
+               if (controlp) {
+                       u_short *p = mtod(controlp, u_short *);
+                       spp_newchecks[2]++;
+                       if ((p[0] == 5) && p[1] == 1) { /* XXXX, for testing */
+                               cb->s_shdr.sp_dt = *(u_char *)(&p[2]);
+                               spp_newchecks[3]++;
+                       }
+                       m_freem(controlp);
+               }
+               controlp = NULL;
                error = spp_output(cb, m);
                m = NULL;
                break;
                error = spp_output(cb, m);
                m = NULL;
                break;
@@ -1409,18 +1472,20 @@ spp_usrreq(so, req, m, nam, rights)
        if (cb && (so->so_options & SO_DEBUG || traceallspps))
                spp_trace(SA_USER, (u_char)ostate, cb, (struct spidp *)0, req);
 release:
        if (cb && (so->so_options & SO_DEBUG || traceallspps))
                spp_trace(SA_USER, (u_char)ostate, cb, (struct spidp *)0, req);
 release:
+       if (controlp != NULL)
+               m_freem(controlp);
        if (m != NULL)
                m_freem(m);
        splx(s);
        return (error);
 }
 
        if (m != NULL)
                m_freem(m);
        splx(s);
        return (error);
 }
 
-spp_usrreq_sp(so, req, m, nam, rights)
+spp_usrreq_sp(so, req, m, nam, controlp)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam, *rights;
+       struct mbuf *m, *nam, *controlp;
 {
 {
-       int error = spp_usrreq(so, req, m, nam, rights);
+       int error = spp_usrreq(so, req, m, nam, controlp);
 
        if (req == PRU_ATTACH && error == 0) {
                struct nspcb *nsp = sotonspcb(so);
 
        if (req == PRU_ATTACH && error == 0) {
                struct nspcb *nsp = sotonspcb(so);
@@ -1452,8 +1517,8 @@ spp_template(cb)
        cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu;
        cb->s_ssthresh = cb->s_cwnd; /* Try to expand fast to full complement
                                        of large packets */
        cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu;
        cb->s_ssthresh = cb->s_cwnd; /* Try to expand fast to full complement
                                        of large packets */
-       cb->s_cwmx = (sb->sb_mbmax * CUNIT) / (2 * sizeof(struct spidp));
-       cb->s_cwmx = MAX(cb->s_cwmx, cb->s_cwnd);
+       cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spidp));
+       cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd);
                /* But allow for lots of little packets as well */
 }
 
                /* But allow for lots of little packets as well */
 }
 
@@ -1590,7 +1655,8 @@ spp_slowtimo()
                        if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
                                (void) spp_usrreq(cb->s_nspcb->nsp_socket,
                                    PRU_SLOWTIMO, (struct mbuf *)0,
                        if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
                                (void) spp_usrreq(cb->s_nspcb->nsp_socket,
                                    PRU_SLOWTIMO, (struct mbuf *)0,
-                                   (struct mbuf *)i, (struct mbuf *)0);
+                                   (struct mbuf *)i, (struct mbuf *)0,
+                                   (struct mbuf *)0);
                                if (ipnxt->nsp_prev != ip)
                                        goto tpgone;
                        }
                                if (ipnxt->nsp_prev != ip)
                                        goto tpgone;
                        }
@@ -1664,7 +1730,7 @@ spp_timers(cb, timer)
                 * See very long discussion in tcp_timer.c about congestion
                 * window and sstrhesh
                 */
                 * See very long discussion in tcp_timer.c about congestion
                 * window and sstrhesh
                 */
-               win = MIN(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
+               win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2;
                if (win < 2)
                        win = 2;
                cb->s_cwnd = CUNIT;
                if (win < 2)
                        win = 2;
                cb->s_cwnd = CUNIT;
@@ -1709,4 +1775,4 @@ spp_timers(cb, timer)
 #ifndef lint
 int SppcbSize = sizeof (struct sppcb);
 int NspcbSize = sizeof (struct nspcb);
 #ifndef lint
 int SppcbSize = sizeof (struct sppcb);
 int NspcbSize = sizeof (struct nspcb);
-#endif lint
+#endif /* lint */