Subject: kern/3480: Deletion of dtom in ip_input.c
To: None <gnats-bugs@gnats.netbsd.org>
From: None <koji@math.human.nagoya-u.ac.jp>
List: netbsd-bugs
Date: 04/12/1997 18:09:21
>Number:         3480
>Category:       kern
>Synopsis:       changes to eliminate dtom in ip reassembly code in ip_input.c
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 12 02:20:01 1997
>Last-Modified:
>Originator:     Koji Imada - je4owb/2
>Organization:
Mathematics Group of Graduate School of Human
	Infomatics, Nagoya University, Japan. 
>Release:        970409
>Environment:
	
System: NetBSD ducati 1.2D NetBSD 1.2D (DUCATI) #1: Sat Apr 12 11:35:25 JST 1997 koji@ducati:/mnt2/NetBSD/work/src-ipv6/sys/arch/i386/compile/DUCATI i386


>Description:
	changes to eliminate dtom in ip reassembly code in
	ip_input.c. struct ipqent is modified to always keep pointer
	to mbuf. And struct ipq is allocated with MALLOC not
	m_get. These modification eliminates dtom in ip_input.c.
>How-To-Repeat:
	
>Fix:
	Apply following patches.

Index: sys/netinet//ip_input.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/netinet/ip_input.c,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 ip_input.c
*** ip_input.c	1997/04/01 07:17:24	1.1.1.2
--- ip_input.c	1997/04/12 01:31:07
***************
*** 373,378 ****
--- 373,379 ----
  	 * 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,385 ****
--- 381,387 ----
  			}
  			ip = mtod(m, struct ip *);
  		}
+ #endif
  		/*
  		 * Look for queue of fragments
  		 * of this datagram.
***************
*** 425,430 ****
--- 427,442 ----
  				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,437 ****
--- 444,450 ----
  				goto next;
  			ipstat.ips_reassembled++;
  			m = dtom(ip);
+ #endif
  		} else
  			if (fp)
  				ip_freef(fp);
***************
*** 455,466 ****
   * reassembly of this datagram already exists, then it
   * is given as fp; otherwise have to make a chain.
   */
! struct ip *
  ip_reass(ipqe, fp)
  	register struct ipqent *ipqe;
  	register struct ipq *fp;
  {
! 	register struct mbuf *m = dtom(ipqe->ipqe_ip);
  	register struct ipqent *nq, *p, *q;
  	struct ip *ip;
  	struct mbuf *t;
--- 468,479 ----
   * reassembly of this datagram already exists, then it
   * is given as fp; otherwise have to make a chain.
   */
! struct mbuf *
  ip_reass(ipqe, fp)
  	register struct ipqent *ipqe;
  	register struct ipq *fp;
  {
! 	register struct mbuf *m = ipqe->ipqe_m;
  	register struct ipqent *nq, *p, *q;
  	struct ip *ip;
  	struct mbuf *t;
***************
*** 478,486 ****
--- 491,506 ----
  	 * 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,517 ****
  		if (i > 0) {
  			if (i >= ipqe->ipqe_ip->ip_len)
  				goto dropfrag;
! 			m_adj(dtom(ipqe->ipqe_ip), i);
  			ipqe->ipqe_ip->ip_off += i;
  			ipqe->ipqe_ip->ip_len -= i;
  		}
--- 531,537 ----
  		if (i > 0) {
  			if (i >= ipqe->ipqe_ip->ip_len)
  				goto dropfrag;
! 			m_adj(ipqe->ipqe_m, i);
  			ipqe->ipqe_ip->ip_off += i;
  			ipqe->ipqe_ip->ip_len -= i;
  		}
***************
*** 528,538 ****
  		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);
  			break;
  		}
  		nq = q->ipqe_q.le_next;
! 		m_freem(dtom(q->ipqe_ip));
  		LIST_REMOVE(q, ipqe_q);
  		FREE(q, M_IPQ);
  	}
--- 548,558 ----
  		if (i < q->ipqe_ip->ip_len) {
  			q->ipqe_ip->ip_len -= i;
  			q->ipqe_ip->ip_off += i;
! 			m_adj(q->ipqe_m, i);
  			break;
  		}
  		nq = q->ipqe_q.le_next;
! 		m_freem(q->ipqe_m);
  		LIST_REMOVE(q, ipqe_q);
  		FREE(q, M_IPQ);
  	}
***************
*** 568,581 ****
  		ip_freef(fp);
  		return (0);
  	}
! 	m = dtom(q->ipqe_ip);
  	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);
  		nq = q->ipqe_q.le_next;
  		FREE(q, M_IPQ);
  		m_cat(m, t);
--- 588,601 ----
  		ip_freef(fp);
  		return (0);
  	}
! 	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 = q->ipqe_m;
  		nq = q->ipqe_q.le_next;
  		FREE(q, M_IPQ);
  		m_cat(m, t);
***************
*** 591,607 ****
  	ip->ip_src = fp->ipq_src;
  	ip->ip_dst = fp->ipq_dst;
  	LIST_REMOVE(fp, ipq_q);
  	(void) m_free(dtom(fp));
  	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;
  	}
! 	return (ip);
  
  dropfrag:
  	ipstat.ips_fragdropped++;
--- 611,631 ----
  	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; t; t = t->m_next)
! 			plen += t->m_len;
! 		m->m_pkthdr.len = plen;
  	}
! 	return (m);
  
  dropfrag:
  	ipstat.ips_fragdropped++;
***************
*** 622,633 ****
  
  	for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
  		p = q->ipqe_q.le_next;
! 		m_freem(dtom(q->ipqe_ip));
  		LIST_REMOVE(q, ipqe_q);
  		FREE(q, M_IPQ);
  	}
  	LIST_REMOVE(fp, ipq_q);
  	(void) m_free(dtom(fp));
  }
  
  /*
--- 646,661 ----
  
  	for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
  		p = q->ipqe_q.le_next;
! 		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 -c -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,80 ****
  		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;
  };
  #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
--- 66,76 ----
  		struct ip	*_ip;
  		struct tcpiphdr *_tcp;
  	} _ipqe_u1;
! 	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
  
  /*
   * Ip reassembly queue structure.  Each fragment
***************
*** 172,178 ****
  int	 ip_optcopy __P((struct ip *, struct ip *));
  int	 ip_output __P((struct mbuf *, ...));
  int	 ip_pcbopts __P((struct mbuf **, struct mbuf *));
! struct ip *
  	 ip_reass __P((struct ipqent *, struct ipq *));
  struct in_ifaddr *
  	 ip_rtaddr __P((struct in_addr));
--- 168,174 ----
  int	 ip_optcopy __P((struct ip *, struct ip *));
  int	 ip_output __P((struct mbuf *, ...));
  int	 ip_pcbopts __P((struct mbuf **, struct mbuf *));
! struct mbuf *
  	 ip_reass __P((struct ipqent *, struct ipq *));
  struct in_ifaddr *
  	 ip_rtaddr __P((struct in_addr));

>Audit-Trail:
>Unformatted: