NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/53664 (nfs client broken on netbsd-8)
The following reply was made to PR kern/53664; it has been noted by GNATS.
From: Martin Husemann <martin%duskware.de@localhost>
To: Hisashi T Fujinaka <htodd%twofifty.com@localhost>
Cc: maxv%NetBSD.org@localhost, gnats-bugs%netbsd.org@localhost, htodd%i8u.org@localhost
Subject: Re: kern/53664 (nfs client broken on netbsd-8)
Date: Sat, 13 Oct 2018 18:56:14 +0200
--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Sat, Oct 13, 2018 at 03:00:01PM +0000, Hisashi T Fujinaka wrote:
> The following reply was made to PR kern/53664; it has been noted by GNATS.
> For that reason, I would think that Martin's idea, a proposed patch for
> -8, would be a better test.
Here is one that catches up to -current for that file
Martin
--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch
Index: ip_reass.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_reass.c,v
retrieving revision 1.11.8.6
diff -c -u -p -r1.11.8.6 ip_reass.c
--- ip_reass.c 9 Oct 2018 09:44:31 -0000 1.11.8.6
+++ ip_reass.c 13 Oct 2018 16:54:01 -0000
@@ -80,6 +80,8 @@ typedef struct ipfr_qent {
struct ip * ipqe_ip;
struct mbuf * ipqe_m;
bool ipqe_mff;
+ uint16_t ipqe_off;
+ uint16_t ipqe_len;
} ipfr_qent_t;
TAILQ_HEAD(ipfr_qent_head, ipfr_qent);
@@ -215,7 +217,7 @@ ip_nmbclusters_changed(void)
struct mbuf *
ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t *fp, const u_int hash)
{
- struct ip *ip = ipqe->ipqe_ip, *qip;
+ struct ip *ip = ipqe->ipqe_ip;
const int hlen = ip->ip_hl << 2;
struct mbuf *m = ipqe->ipqe_m, *t;
int ipsecflags = m->m_flags & (M_DECRYPTED|M_AUTHIPHDR);
@@ -230,16 +232,6 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t
m->m_data += hlen;
m->m_len -= hlen;
-#ifdef notyet
- /* Make sure fragment limit is up-to-date. */
- CHECK_NMBCLUSTER_PARAMS();
-
- /* If we have too many fragments, drop the older half. */
- if (ip_nfrags >= ip_maxfrags) {
- ip_reass_drophalf(void);
- }
-#endif
-
/*
* We are about to add a fragment; increment frag count.
*/
@@ -255,9 +247,9 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t
* never accept fragments b) if maxfrag is -1, accept
* all fragments without limitation.
*/
- if (ip_maxfragpackets < 0)
- ;
- else if (ip_nfragpackets >= ip_maxfragpackets) {
+ if (ip_maxfragpackets < 0) {
+ /* no limit */
+ } else if (ip_nfragpackets >= ip_maxfragpackets) {
goto dropfrag;
}
fp = malloc(sizeof(ipfr_queue_t), M_FTABLE, M_NOWAIT);
@@ -285,7 +277,7 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t
* Find a segment which begins after this one does.
*/
TAILQ_FOREACH(q, &fp->ipq_fragq, ipqe_q) {
- if (ntohs(q->ipqe_ip->ip_off) > ntohs(ip->ip_off))
+ if (q->ipqe_off > ipqe->ipqe_off)
break;
}
if (q != NULL) {
@@ -295,39 +287,45 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t
}
/*
- * If there is a preceding segment, it may provide some of our
- * data already. If so, drop the data from the incoming segment.
- * If it provides all of our data, drop us.
+ * Look at the preceding segment.
+ *
+ * If it provides some of our data already, in part or entirely, trim
+ * us or drop us.
+ *
+ * If a preceding segment exists, and was marked as the last segment,
+ * drop us.
*/
if (p != NULL) {
- i = ntohs(p->ipqe_ip->ip_off) + ntohs(p->ipqe_ip->ip_len) -
- ntohs(ip->ip_off);
+ i = p->ipqe_off + p->ipqe_len - ipqe->ipqe_off;
if (i > 0) {
- if (i >= ntohs(ip->ip_len)) {
+ if (i >= ipqe->ipqe_len) {
goto dropfrag;
}
m_adj(ipqe->ipqe_m, i);
- ip->ip_off = htons(ntohs(ip->ip_off) + i);
- ip->ip_len = htons(ntohs(ip->ip_len) - i);
+ ipqe->ipqe_off = ipqe->ipqe_off + i;
+ ipqe->ipqe_len = ipqe->ipqe_len - i;
}
}
+ if (p != NULL && !p->ipqe_mff) {
+ goto dropfrag;
+ }
/*
- * While we overlap succeeding segments trim them or, if they are
- * completely covered, dequeue them.
+ * Look at the segments that follow.
+ *
+ * If we cover them, in part or entirely, trim them or dequeue them.
+ *
+ * If a following segment exists, and we are marked as the last
+ * segment, drop us.
*/
while (q != NULL) {
- size_t end;
-
- qip = q->ipqe_ip;
- end = ntohs(ip->ip_off) + ntohs(ip->ip_len);
- if (end <= ntohs(qip->ip_off)) {
+ i = ipqe->ipqe_off + ipqe->ipqe_len - q->ipqe_off;
+ if (i <= 0) {
break;
}
- i = end - ntohs(qip->ip_off);
- if (i < ntohs(qip->ip_len)) {
- qip->ip_len = htons(ntohs(qip->ip_len) - i);
- qip->ip_off = htons(ntohs(qip->ip_off) + i);
+ if (i < q->ipqe_len) {
+ q->ipqe_off = q->ipqe_off + i;
+ q->ipqe_len = q->ipqe_len - i;
m_adj(q->ipqe_m, i);
break;
}
@@ -339,6 +337,9 @@ ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t
ip_nfrags--;
q = nq;
}
+ if (q != NULL && !ipqe->ipqe_mff) {
+ goto dropfrag;
+ }
insert:
/*
@@ -351,12 +352,11 @@ insert:
}
next = 0;
TAILQ_FOREACH(q, &fp->ipq_fragq, ipqe_q) {
- qip = q->ipqe_ip;
- if (ntohs(qip->ip_off) != next) {
+ if (q->ipqe_off != next) {
mutex_exit(&ipfr_lock);
return NULL;
}
- next += ntohs(qip->ip_len);
+ next += q->ipqe_len;
}
p = TAILQ_LAST(&fp->ipq_fragq, ipfr_qent_head);
if (p->ipqe_mff) {
@@ -402,6 +402,7 @@ insert:
* header visible.
*/
ip->ip_len = htons((ip->ip_hl << 2) + next);
+ ip->ip_off = htons(0);
ip->ip_src = fp->ipq_src;
ip->ip_dst = fp->ipq_dst;
free(fp, M_FTABLE);
@@ -651,13 +652,6 @@ ip_reass_packet(struct mbuf **m0, struct
return EINVAL;
}
- /*
- * Adjust total IP length to not reflect header and convert
- * offset of this to bytes. XXX: clobbers struct ip.
- */
- ip->ip_len = htons(flen);
- ip->ip_off = htons(off);
-
/* Look for queue of fragments of this datagram. */
mutex_enter(&ipfr_lock);
hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
@@ -702,6 +696,8 @@ ip_reass_packet(struct mbuf **m0, struct
ipqe->ipqe_mff = mff;
ipqe->ipqe_m = m;
ipqe->ipqe_ip = ip;
+ ipqe->ipqe_off = off;
+ ipqe->ipqe_len = flen;
*m0 = ip_reass(ipqe, fp, hash);
if (*m0) {
--sdtB3X0nJg68CQEu--
Home |
Main Index |
Thread Index |
Old Index