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: