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