Subject: kern/3628: changes to eliminate dtom() in network code.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <koji@math.human.nagoya-u.ac.jp>
List: netbsd-bugs
Date: 05/16/1997 00:03:03
>Number:         3628
>Category:       kern
>Synopsis:       changes to eliminate dtom() in network code.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu May 15 08:05:00 1997
>Last-Modified:
>Originator:     Koji Imada - je4owb/2
>Organization:
Mathematics Group of Graduate School of Human
	Infomatics, Nagoya University, Japan.
>Release:        970513
>Environment:
	
System: NetBSD bimota 1.2E NetBSD 1.2E (BIMOTA) #30: Tue May 13 23:32:51 JST 1997 koji@ducati:/mnt2/NetBSD/work/src-ufs-mod/sys/arch/i386/compile/BIMOTA i386


>Description:
	Changes to eliminate dtom() in network codes. dtom() restricts 
	usage of mbuf cluster and this causes some performance loss.

	This pr includes kern/3480.
>How-To-Repeat:
	nothing.
>Fix:
	apply following patches in /usr/src.

Index: sys/netinet/ip_input.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netinet/ip_input.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 ip_input.c
--- ip_input.c	1997/04/23 22:09:59	1.1.1.3
+++ ip_input.c	1997/04/24 00:10:45
@@ -373,6 +373,7 @@
 	 * but it's not worth the time; just let them time out.)
 	 */
 	if (ip->ip_off & ~(IP_DF|IP_RF)) {
+#if 0 /* this is not necessary if dtom is not used */
 		if (m->m_flags & M_EXT) {		/* XXX */
 			if ((m = m_pullup(m, sizeof (struct ip))) == 0) {
 				ipstat.ips_toosmall++;
@@ -380,6 +381,7 @@
 			}
 			ip = mtod(m, struct ip *);
 		}
+#endif
 		/*
 		 * Look for queue of fragments
 		 * of this datagram.
@@ -425,6 +427,16 @@
 				ipstat.ips_rcvmemdrop++;
 				goto bad;
 			}
+#if 1 /* don't use dtom */
+			ipqe->ipqe_mff = mff;
+			ipqe->ipqe_m = m;
+			ipqe->ipqe_ip = ip;
+			m = ip_reass(ipqe, fp);
+			if (m == 0)
+				goto next;
+			ipstat.ips_reassembled++;
+			ip = mtod(m, struct ip *);
+#else 
 			ipqe->ipqe_mff = mff;
 			ipqe->ipqe_ip = ip;
 			ip = ip_reass(ipqe, fp);
@@ -432,6 +444,7 @@
 				goto next;
 			ipstat.ips_reassembled++;
 			m = dtom(ip);
+#endif
 		} else
 			if (fp)
 				ip_freef(fp);
@@ -455,12 +468,12 @@
  * reassembly of this datagram already exists, then it
  * is given as fp; otherwise have to make a chain.
  */
-struct ip *
+struct mbuf *
 ip_reass(ipqe, fp)
 	register struct ipqent *ipqe;
 	register struct ipq *fp;
 {
-	register struct mbuf *m = dtom(ipqe->ipqe_ip);
+	register struct mbuf *m = ipqe->ipqe_m;
 	register struct ipqent *nq, *p, *q;
 	struct ip *ip;
 	struct mbuf *t;
@@ -478,9 +491,16 @@
 	 * If first fragment to arrive, create a reassembly queue.
 	 */
 	if (fp == 0) {
+#if 1
+		MALLOC(fp, struct ipq *, sizeof (struct ipq),
+		    M_FTABLE, M_NOWAIT);
+		if (fp == NULL)
+			goto dropfrag;
+#else
 		if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
 			goto dropfrag;
 		fp = mtod(t, struct ipq *);
+#endif
 		LIST_INSERT_HEAD(&ipq, fp, ipq_q);
 		fp->ipq_ttl = IPFRAGTTL;
 		fp->ipq_p = ipqe->ipqe_ip->ip_p;
@@ -511,7 +531,7 @@
 		if (i > 0) {
 			if (i >= ipqe->ipqe_ip->ip_len)
 				goto dropfrag;
-			m_adj(dtom(ipqe->ipqe_ip), i);
+			m_adj(ipqe->ipqe_m, i);
 			ipqe->ipqe_ip->ip_off += i;
 			ipqe->ipqe_ip->ip_len -= i;
 		}
@@ -528,11 +548,11 @@
 		if (i < q->ipqe_ip->ip_len) {
 			q->ipqe_ip->ip_len -= i;
 			q->ipqe_ip->ip_off += i;
-			m_adj(dtom(q->ipqe_ip), i);
+			m_adj(q->ipqe_m, i);
 			break;
 		}
 		nq = q->ipqe_q.le_next;
-		m_freem(dtom(q->ipqe_ip));
+		m_freem(q->ipqe_m);
 		LIST_REMOVE(q, ipqe_q);
 		FREE(q, M_IPQ);
 	}
@@ -568,14 +588,14 @@
 		ip_freef(fp);
 		return (0);
 	}
-	m = dtom(q->ipqe_ip);
+	m = q->ipqe_m;
 	t = m->m_next;
 	m->m_next = 0;
 	m_cat(m, t);
 	nq = q->ipqe_q.le_next;
 	FREE(q, M_IPQ);
 	for (q = nq; q != NULL; q = nq) {
-		t = dtom(q->ipqe_ip);
+		t = q->ipqe_m;
 		nq = q->ipqe_q.le_next;
 		FREE(q, M_IPQ);
 		m_cat(m, t);
@@ -591,17 +611,21 @@
 	ip->ip_src = fp->ipq_src;
 	ip->ip_dst = fp->ipq_dst;
 	LIST_REMOVE(fp, ipq_q);
+#if 1
+	FREE(fp, M_FTABLE);
+#else
 	(void) m_free(dtom(fp));
+#endif
 	m->m_len += (ip->ip_hl << 2);
 	m->m_data -= (ip->ip_hl << 2);
 	/* some debugging cruft by sklower, below, will go away soon */
 	if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
 		register int plen = 0;
-		for (t = m; m; m = m->m_next)
-			plen += m->m_len;
-		t->m_pkthdr.len = plen;
+		for (t = m; t; t = t->m_next)
+			plen += t->m_len;
+		m->m_pkthdr.len = plen;
 	}
-	return (ip);
+	return (m);
 
 dropfrag:
 	ipstat.ips_fragdropped++;
@@ -622,12 +646,16 @@
 
 	for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
 		p = q->ipqe_q.le_next;
-		m_freem(dtom(q->ipqe_ip));
+		m_freem(q->ipqe_m);
 		LIST_REMOVE(q, ipqe_q);
 		FREE(q, M_IPQ);
 	}
 	LIST_REMOVE(fp, ipq_q);
+#if 1
+	FREE(fp, M_FTABLE);
+#else
 	(void) m_free(dtom(fp));
+#endif
 }
 
 /*
Index: sys/netinet/ip_var.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netinet/ip_var.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 ip_var.h
--- ip_var.h	1997/04/01 07:17:27	1.1.1.2
+++ ip_var.h	1997/04/12 01:14:17
@@ -66,15 +66,11 @@
 		struct ip	*_ip;
 		struct tcpiphdr *_tcp;
 	} _ipqe_u1;
-	union {
-		u_int8_t	_mff;	/* for IP fragmentation */
-		struct mbuf	*_m;	/* XXX for TCP; see above */
-	} _ipqe_u2;
+	struct mbuf	*ipqe_m;	/* mbuf contains packet */
+	u_int8_t	ipqe_mff;	/* for IP fragmentation */
 };
 #define	ipqe_ip		_ipqe_u1._ip
 #define	ipqe_tcp	_ipqe_u1._tcp
-#define	ipqe_mff	_ipqe_u2._mff
-#define	ipqe_m		_ipqe_u2._m
 
 /*
  * Ip reassembly queue structure.  Each fragment
@@ -172,7 +168,7 @@
 int	 ip_optcopy __P((struct ip *, struct ip *));
 int	 ip_output __P((struct mbuf *, ...));
 int	 ip_pcbopts __P((struct mbuf **, struct mbuf *));
-struct ip *
+struct mbuf *
 	 ip_reass __P((struct ipqent *, struct ipq *));
 struct in_ifaddr *
 	 ip_rtaddr __P((struct in_addr));
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netinet/tcp_subr.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 tcp_subr.c
--- tcp_subr.c	1997/04/01 07:17:32	1.1.1.2
+++ tcp_subr.c	1997/04/19 07:01:46
@@ -97,15 +97,13 @@
 	struct tcpcb *tp;
 {
 	register struct inpcb *inp = tp->t_inpcb;
-	register struct mbuf *m;
 	register struct tcpiphdr *n;
 
 	if ((n = tp->t_template) == 0) {
-		m = m_get(M_DONTWAIT, MT_HEADER);
-		if (m == NULL)
+		MALLOC(n, struct tcpiphdr *, sizeof (struct tcpiphdr),
+		    M_MBUF, M_NOWAIT);
+		if (n == NULL)
 			return (0);
-		m->m_len = sizeof (struct tcpiphdr);
-		n = mtod(m, struct tcpiphdr *);
 	}
 	bzero(n->ti_x1, sizeof n->ti_x1);
 	n->ti_pr = IPPROTO_TCP;
@@ -352,7 +350,7 @@
 		FREE(qe, M_IPQ);
 	}
 	if (tp->t_template)
-		(void) m_free(dtom(tp->t_template));
+		FREE(tp->t_template, M_MBUF);
 	free(tp, M_PCB);
 	inp->inp_ppcb = 0;
 	soisdisconnected(so);
Index: sys/netccitt/hd_debug.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netccitt/hd_debug.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 hd_debug.c
--- hd_debug.c	1997/04/01 07:16:57	1.1.1.2
+++ hd_debug.c	1997/04/18 19:19:24
@@ -70,17 +70,18 @@
 #endif
 
 void
-hd_trace(hdp, direction, frame)
+hd_trace(hdp, direction, m)
 	struct hdcb    *hdp;
 	int direction;
-	register struct Hdlc_frame *frame;
+	struct mbuf *m;
 {
 	register char  *s;
 	register int    nr, pf, ns, i;
+	register struct Hdlc_frame *frame = mtod(m, struct Hdlc_frame *);
 	struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
 
 #ifdef HDLCDEBUG
-	hd_savetrace(hdp, direction, frame);
+	hd_savetrace(hdp, direction, m);
 #endif
 	if (hdp->hd_xcp->xc_ltrace) {
 		if (direction == RX)
@@ -139,10 +140,9 @@
 
 		case IFRAME:
 			{
-				register struct mbuf *m;
 				register int    len = 0;
 
-				for (m = dtom(frame); m; m = m->m_next)
+				for (; m; m = m->m_next)
 					len += m->m_len;
 				len -= HDHEADERLN;
 				printf("IFRAME : N(R)=%d, PF=%d, N(S)=%d, DATA(%d)=",
@@ -165,13 +165,13 @@
 
 #ifdef HDLCDEBUG
 static void
-hd_savetrace(hdp, dir, frame)
+hd_savetrace(hdp, dir, m)
 	struct hdcb    *hdp;
 	int dir;
-	struct Hdlc_frame *frame;
+	struct mbuf *m;
 {
 	register struct hdlctrace *htp;
-	register struct mbuf *m;
+	register struct Hdlc_frame *frame = mtod(m, struct Hdlc_frame *);
 
 	if (freezetrace)
 		return;
@@ -179,7 +179,6 @@
 	lasttracelogged = (lasttracelogged + 1) % NTRACE;
 	if (m = htp->ht_frame)
 		m_freem(m);
-	m = dtom(frame);
 	htp->ht_frame = m_copy(m, 0, m->m_len);
 	htp->ht_hdp = hdp;
 	htp->ht_dir = dir;
@@ -207,8 +206,7 @@
 			continue;
 		printf("%d/%d	", htp->ht_time.tv_sec & 0xff,
 		       htp->ht_time.tv_usec / 10000);
-		hd_trace(htp->ht_hdp, htp->ht_dir,
-			 mtod(htp->ht_frame, struct Hdlc_frame *));
+		hd_trace(htp->ht_hdp, htp->ht_dir, htp->ht_frame);
 		m_freem(htp->ht_frame);
 		htp->ht_frame = 0;
 	}
Index: sys/netccitt/hd_input.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netccitt/hd_input.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 hd_input.c
--- hd_input.c	1997/04/01 07:16:58	1.1.1.2
+++ hd_input.c	1997/04/18 19:19:37
@@ -134,7 +134,7 @@
 	frame = mtod(fbuf, struct Hdlc_frame *);
 	pf = ((struct Hdlc_iframe *) frame)->pf;
 
-	hd_trace(hdp, RX, frame);
+	hd_trace(hdp, RX, fbuf);
 	if (frame->address != ADDRESS_A && frame->address != ADDRESS_B)
 		return (queued);
 
Index: sys/netccitt/hd_output.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netccitt/hd_output.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 hd_output.c
--- hd_output.c	1997/04/01 07:16:59	1.1.1.2
+++ hd_output.c	1997/04/18 19:19:46
@@ -197,7 +197,7 @@
 	}
 	hdp->hd_vs = (hdp->hd_vs + 1) % MODULUS;
 
-	hd_trace(hdp, TX, (struct Hdlc_frame *) iframe);
+	hd_trace(hdp, TX, buf);
 
 	/* Write buffer on device. */
 	m = hdp->hd_dontcopy ? buf : m_copy(buf, 0, (int) M_COPYALL);
Index: sys/netccitt/hd_subr.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netccitt/hd_subr.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 hd_subr.c
--- hd_subr.c	1997/04/01 07:17:00	1.1.1.2
+++ hd_subr.c	1997/04/18 19:19:51
@@ -321,7 +321,7 @@
 	} else
 		uframe->pf = pf;
 
-	hd_trace(hdp, TX, frame);
+	hd_trace(hdp, TX, buf);
 	buf->m_pkthdr.len = buf->m_len;
 	(*hdp->hd_output) (buf, hdp, NULL);
 }
Index: sys/netccitt/hd_var.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netccitt/hd_var.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 hd_var.h
--- hd_var.h	1997/03/31 08:57:02	1.1.1.1
+++ hd_var.h	1997/04/18 19:20:09
@@ -113,7 +113,7 @@
 
 
 /* hd_debug.c */
-void hd_trace __P((struct hdcb *, int , struct Hdlc_frame *));
+void hd_trace __P((struct hdcb *, int , struct mbuf *));
 int hd_dumptrace __P((struct hdcb *));
 
 /* hd_input.c */
Index: sys/netiso/clnp_frag.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netiso/clnp_frag.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 clnp_frag.c
--- clnp_frag.c	1997/04/01 07:17:42	1.1.1.2
+++ clnp_frag.c	1997/04/19 07:15:40
@@ -414,7 +414,6 @@
 {
 	register struct clnp_fragl *cfh;
 	register struct clnp_fixed *clnp;
-	struct mbuf    *m0;
 
 	clnp = mtod(m, struct clnp_fixed *);
 
@@ -422,11 +421,11 @@
 	 * Allocate new clnp fragl structure to act as header of all
 	 * fragments for this datagram.
 	 */
-	MGET(m0, M_DONTWAIT, MT_FTABLE);
-	if (m0 == NULL) {
+	MALLOC(cfh, struct clnp_fragl *, sizeof (struct clnp_fragl),
+	   M_FTABLE, M_NOWAIT);
+	if (cfh == NULL) {
 		return (0);
 	}
-	cfh = mtod(m0, struct clnp_fragl *);
 
 	/*
 	 * Duplicate the header of this fragment, and save in cfh. Free m0
@@ -434,7 +433,7 @@
 	 */
 	cfh->cfl_orighdr = m_copy(m, 0, (int) clnp->cnf_hdr_len);
 	if (cfh->cfl_orighdr == NULL) {
-		m_freem(m0);
+		FREE(cfh, M_FTABLE);
 		return (0);
 	}
 	/* Fill in rest of fragl structure */
@@ -855,7 +854,7 @@
 		}
 
 		/* free cfh */
-		m_freem(dtom(cfh));
+		FREE(cfh, M_FTABLE);
 
 		return (hdr);
 	}
Index: sys/netiso/clnp_timer.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netiso/clnp_timer.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 clnp_timer.c
--- clnp_timer.c	1997/03/31 08:57:08	1.1.1.1
+++ clnp_timer.c	1997/04/19 05:33:33
@@ -126,7 +126,7 @@
 	}
 
 	/* free the fragment header */
-	m_freem(dtom(cfh));
+	FREE(cfh, M_FTABLE);
 
 	return (next);
 }
Index: sys/netiso/cltp_usrreq.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netiso/cltp_usrreq.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 cltp_usrreq.c
--- cltp_usrreq.c	1997/04/01 07:17:48	1.1.1.2
+++ cltp_usrreq.c	1997/04/19 06:59:00
@@ -90,6 +90,7 @@
 	u_int           cons_channel;
 	register struct isopcb *isop;
 	register struct mbuf *m = m0;
+	struct mbuf *m_src = 0;
 	register u_char *up = mtod(m, u_char *);
 	register struct sockaddr_iso *src;
 	int             len, hdrlen = *up + 1, dlen = 0;
@@ -115,11 +116,11 @@
 			if (src->siso_len < sizeof(*src))
 				src->siso_len = sizeof(*src);
 			else if (src->siso_len > sizeof(*src)) {
-				MGET(m, M_DONTWAIT, MT_SONAME);
-				if (m == 0)
+				MGET(m_src, M_DONTWAIT, MT_SONAME);
+				if (m_src == 0)
 					goto bad;
-				m->m_len = src->siso_len;
-				src = mtod(m, struct sockaddr_iso *);
+				m_src->m_len = src->siso_len;
+				src = mtod(m_src, struct sockaddr_iso *);
 				bcopy((caddr_t) srcsa, (caddr_t) src, srcsa->sa_len);
 			}
 			bcopy((caddr_t) up + 2, TSEL(src), up[1]);
@@ -167,7 +168,7 @@
 	m0 = 0;
 bad:
 	if (src != satosiso(srcsa))
-		m_freem(dtom(src));
+		m_freem(m_src);
 	if (m0)
 		m_freem(m0);
 }
Index: sys/netiso/iso_pcb.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netiso/iso_pcb.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 iso_pcb.c
--- iso_pcb.c	1997/04/01 07:18:02	1.1.1.2
+++ iso_pcb.c	1997/04/19 06:56:24
@@ -222,6 +222,7 @@
 	} else {
 		if ((nam = m_copy(nam, 0, (int) M_COPYALL)) == 0)
 			return ENOBUFS;
+		isop->isop_mladdr = nam;
 		isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
 	}
 	bcopy((caddr_t) siso, (caddr_t) isop->isop_laddr, siso->siso_len);
@@ -376,6 +377,7 @@
 			if (m == 0)
 				return ENOBUFS;
 			m->m_len = totlen;
+			isop->isop_mladdr = m;
 			isop->isop_laddr = siso = mtod(m, struct sockaddr_iso *);
 		}
 		siso->siso_nlen = ia->ia_addr.siso_nlen;
@@ -408,6 +410,7 @@
 			struct mbuf    *m = m_get(M_DONTWAIT, MT_SONAME);
 			if (m == 0)
 				return ENOBUFS;
+			isop->isop_mfaddr = m;
 			isop->isop_faddr = mtod(m, struct sockaddr_iso *);
 		}
 	}
@@ -460,7 +463,7 @@
 		ovbcopy(otsel, TSEL(siso), siso->siso_tlen);
 	}
 	if (isop->isop_faddr && isop->isop_faddr != &isop->isop_sfaddr)
-		m_freem(dtom(isop->isop_faddr));
+		m_freem(isop->isop_mfaddr);
 	isop->isop_faddr = 0;
 	if (isop->isop_socket->so_state & SS_NOFDREF)
 		iso_pcbdetach(isop);
@@ -560,7 +563,7 @@
 	}
 #endif
 	if (isop->isop_laddr && (isop->isop_laddr != &isop->isop_sladdr))
-		m_freem(dtom(isop->isop_laddr));
+		m_freem(isop->isop_mladdr);
 	free((caddr_t) isop, M_PCB);
 }
 
Index: sys/netiso/iso_pcb.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netiso/iso_pcb.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 iso_pcb.h
--- iso_pcb.h	1997/04/01 07:18:03	1.1.1.2
+++ iso_pcb.h	1997/04/19 06:56:07
@@ -88,6 +88,8 @@
 	int             isop_x25crud_len;	/* x25 call request ud */
 	char            isop_x25crud[MAXX25CRUDLEN];
 	struct ifaddr  *isop_ifa;	/* ESIS interface assoc w/sock */
+	struct mbuf    *isop_mladdr;	/* dynamically allocated laddr */
+	struct mbuf    *isop_mfaddr;	/* dynamically allocated faddr */
 	struct sockaddr_iso isop_sladdr,	/* preallocated laddr */
 	                isop_sfaddr;	/* preallocated faddr */
 };
Index: sys/netns/spidp.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netns/spidp.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 spidp.h
--- spidp.h	1997/03/31 08:57:17	1.1.1.1
+++ spidp.h	1997/04/18 07:14:14
@@ -43,9 +43,11 @@
 	struct idp	si_i;
 	struct sphdr 	si_s;
 };
+LIST_HEAD(siqhead, spidp_q);
 struct spidp_q {
-	struct spidp_q	*si_next;
-	struct spidp_q	*si_prev;
+	LIST_ENTRY(spidp_q) si_q;
+	struct spidp *si_spidp;
+	struct mbuf *si_m;
 };
 #define SI(x)	((struct spidp *)x)
 #define si_sum	si_i.idp_sum
Index: sys/netns/spp_usrreq.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netns/spp_usrreq.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 spp_usrreq.c
--- spp_usrreq.c	1997/04/01 07:18:45	1.1.1.2
+++ spp_usrreq.c	1997/04/18 09:47:07
@@ -268,7 +268,7 @@
 	m->m_pkthdr.len -= sizeof (struct idp);
 	m->m_data += sizeof (struct idp);
 
-	if (spp_reass(cb, si)) {
+	if (spp_reass(cb, si, m)) {
 		(void) m_freem(m);
 	}
 	if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT)))
@@ -282,7 +282,7 @@
 	si->si_seq = ntohs(si->si_seq);
 	si->si_ack = ntohs(si->si_ack);
 	si->si_alo = ntohs(si->si_alo);
-	ns_error(dtom(si), NS_ERR_NOSOCK, 0);
+	ns_error(m, NS_ERR_NOSOCK, 0);
 	if (cb->s_nspcb->nsp_socket->so_options & SO_DEBUG || traceallspps)
 		spp_trace(SA_DROP, (u_char)ostate, cb, &spp_savesi, 0);
 	return;
@@ -303,11 +303,12 @@
  * packets up, and suppresses duplicates.
  */
 int
-spp_reass(cb, si)
+spp_reass(cb, si, m0)
 register struct sppcb *cb;
 register struct spidp *si;
+register struct mbuf *m0;
 {
-	register struct spidp_q *q;
+	register struct spidp_q *p, *q, *si_q;
 	register struct mbuf *m;
 	register struct socket *so = cb->s_nspcb->nsp_socket;
 	char packetp = cb->s_flags & SF_HI;
@@ -460,18 +461,18 @@
 			sppstat.spps_rcvpackafterwin++;
 		if (si->si_cc & SP_OB) {
 			if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) {
-				ns_error(dtom(si), NS_ERR_FULLUP, 0);
+				ns_error(m0, NS_ERR_FULLUP, 0);
 				return (0);
 			} /* else queue this packet; */
 		} else {
 			/*register struct socket *so = cb->s_nspcb->nsp_socket;
 			if (so->so_state && SS_NOFDREF) {
-				ns_error(dtom(si), NS_ERR_NOSOCK, 0);
+				ns_error(m0, NS_ERR_NOSOCK, 0);
 				(void)spp_close(cb);
 			} else
 				       would crash system*/
 			spp_istat.notyet++;
-			ns_error(dtom(si), NS_ERR_FULLUP, 0);
+			ns_error(m0, NS_ERR_FULLUP, 0);
 			return (0);
 		}
 	}
@@ -496,17 +497,31 @@
 	 * Loop through all packets queued up to insert in
 	 * appropriate sequence.
 	 */
-	for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
-		if (si->si_seq == SI(q)->si_seq) {
+	for (p = NULL, q = cb->s_q.lh_first; q != NULL;
+	    p = q, q = q->si_q.le_next) {
+		if (si->si_seq == q->si_spidp->si_seq) {
 			sppstat.spps_rcvduppack++;
 			return (1);
 		}
-		if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) {
+		if (SSEQ_LT(si->si_seq, q->si_spidp->si_seq)) {
 			sppstat.spps_rcvoopack++;
 			break;
 		}
 	}
-	insque(si, q->si_prev);
+
+	MALLOC(si_q, struct spidp_q *, sizeof (struct spidp_q),
+	    M_IPQ/* XXX M_SPIDPQ */, M_NOWAIT);
+	if (si_q == NULL) {
+		sppstat.spps_rcvshort ++;	/* XXX rcvmemdrop... */
+		return (1);
+	}
+	si_q->si_spidp = si;
+	si_q->si_m = m0;
+	if (p == NULL) {
+		LIST_INSERT_HEAD(&cb->s_q, si_q, si_q);
+	} else {
+		LIST_INSERT_AFTER(p, si_q, si_q);
+	}
 	/*
 	 * If this packet is urgent, inform process
 	 */
@@ -522,19 +537,20 @@
 	 * number, and present all acknowledged data to user;
 	 * If in packet interface mode, show packet headers.
 	 */
-	for (q = cb->s_q.si_next; q!=&cb->s_q; q = q->si_next) {
-		  if (SI(q)->si_seq == cb->s_ack) {
+	for (q = cb->s_q.lh_first; q != NULL; q = p) {
+		  if (q->si_spidp->si_seq == cb->s_ack) {
 			cb->s_ack++;
-			m = dtom(q);
-			if (SI(q)->si_cc & SP_OB) {
+			m = q->si_m;
+			if (q->si_spidp->si_cc & SP_OB) {
 				cb->s_oobflags &= ~SF_IOOB;
 				if (so->so_rcv.sb_cc)
 					so->so_oobmark = so->so_rcv.sb_cc;
 				else
 					so->so_state |= SS_RCVATMARK;
 			}
-			q = q->si_prev;
-			remque(q->si_next);
+			p = q->si_q.le_next;
+			LIST_REMOVE(q, si_q);
+			FREE(q, M_IPQ /* XXX, M_SPIDPQ */);
 			wakeup = 1;
 			sppstat.spps_rcvpack++;
 #ifdef SF_NEWCALL
@@ -743,7 +759,7 @@
 {
 	register struct sppcb *cb = NULL;
 	struct socket *so;
-	register struct mbuf *m;
+	register struct mbuf *m = NULL;
 	register struct spidp *si = (struct spidp *) 0;
 	register struct sockbuf *sb;
 	int len = 0, win, rcv_win;
@@ -1026,7 +1042,11 @@
 		 * must make a copy of this packet for
 		 * idp_output to monkey with
 		 */
+#if 0
 		m = m_copy(dtom(si), 0, (int)M_COPYALL);
+#else
+		m = m_copy(m, 0, (int)M_COPYALL);
+#endif
 		if (m == NULL) {
 			return (ENOBUFS);
 		}
@@ -1360,7 +1380,7 @@
 		cb->s_state = TCPS_LISTEN;
 		cb->s_smax = -1;
 		cb->s_swl1 = -1;
-		cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q;
+		LIST_INIT(&cb->s_q);
 		cb->s_nspcb = nsp;
 		cb->s_mtu = 576 - sizeof (struct spidp);
 		cb->s_cwnd = sbspace(&so->so_snd) * CUNIT / cb->s_mtu;
@@ -1583,16 +1603,16 @@
 spp_close(cb)
 	register struct sppcb *cb;
 {
-	register struct spidp_q *s;
+	register struct spidp_q *s, *n;
 	struct nspcb *nsp = cb->s_nspcb;
 	struct socket *so = nsp->nsp_socket;
 	register struct mbuf *m;
 
-	s = cb->s_q.si_next;
-	while (s != &(cb->s_q)) {
-		s = s->si_next;
-		m = dtom(s->si_prev);
-		remque(s->si_prev);
+	for (s = cb->s_q.lh_first; s != NULL; s = n) {
+		n = s->si_q.le_next;
+		m = s->si_m;
+		LIST_REMOVE(s, si_q);
+		FREE(s, M_IPQ /* XXX M_SPIDPQ */);
 		m_freem(m);
 	}
 	free(cb->s_idp, M_PCB);
Index: sys/netns/spp_var.h
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netns/spp_var.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 spp_var.h
--- spp_var.h	1997/04/01 07:18:46	1.1.1.2
+++ spp_var.h	1997/04/18 07:14:24
@@ -39,7 +39,7 @@
  * Sp control block, one per connection
  */
 struct sppcb {
-	struct	spidp_q	s_q;		/* queue for out-of-order receipt */
+	struct	siqhead	s_q;		/* queue for out-of-order receipt */
 	struct	nspcb	*s_nspcb;	/* backpointer to internet pcb */
 	u_char	s_state;
 	u_char	s_flags;
@@ -202,7 +202,7 @@
 /* spp_usrreq.c */
 void spp_init __P((void));
 void spp_input __P((struct mbuf *, ...));
-int spp_reass __P((struct sppcb *, struct spidp *));
+int spp_reass __P((struct sppcb *, struct spidp *, struct mbuf *));
 void *spp_ctlinput __P((int, struct sockaddr *, void *));
 void spp_quench __P((struct nspcb *));
 int spp_fixmtu __P((struct nspcb *));

>Audit-Trail:
>Unformatted: