The following reply was made to PR kern/152853; it has been noted by GNATS.

From: Petr Lampa <la...@fit.vutbr.cz>
To: bug-follo...@freebsd.org, mandr...@bit0.com
Cc: j...@freebsd.org
Subject: Re: kern/152853: [em] tftpd (and likely other udp traffic) fails
 over em(4) unless rxcsum/txcsum disabled
Date: Tue, 18 Jan 2011 16:15:12 +0100

 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 
 Some folowup for kern/152853 with a patch.
 
 It seems that the current version of if_em.c (both CURRENT and STABLE8)
 with txcsum/rxcsum cannot send any UDP packet shorter then TCP header size. 
 The reason is suspicious m_pullup(m_head, poff + sizeof(struct tcphdr)) in 
 common packet em_xmit handling. I've moved this m_pullupi() call to required 
 branches further down and this fixed the issue (UDP ack from tftpd daemon 
 now ok). The code however needs some audit, repeated m_pullups are strange.
 
 Sincerely,
 Petr Lampa
 
 *** if_em.c.old        2011-01-18 15:52:21.000000000 +0100
 --- if_em.c    2011-01-18 15:58:11.000000000 +0100
 ***************
 *** 1820,1831 ****
                }
                ip = (struct ip *)(mtod(m_head, char *) + ip_off);
                poff = ip_off + (ip->ip_hl << 2);
 -              m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 -              if (m_head == NULL) {
 -                      *m_headp = NULL;
 -                      return (ENOBUFS);
 -              }
                if (do_tso) {
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        /*
                         * TSO workaround:
 --- 1820,1831 ----
                }
                ip = (struct ip *)(mtod(m_head, char *) + ip_off);
                poff = ip_off + (ip->ip_hl << 2);
                if (do_tso) {
 +                      m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 +                      if (m_head == NULL) {
 +                              *m_headp = NULL;
 +                              return (ENOBUFS);
 +                      }
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        /*
                         * TSO workaround:
 ***************
 *** 1849,1854 ****
 --- 1849,1859 ----
                        tp->th_sum = in_pseudo(ip->ip_src.s_addr,
                            ip->ip_dst.s_addr, htons(IPPROTO_TCP));
                } else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
 +                      m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 +                      if (m_head == NULL) {
 +                              *m_headp = NULL;
 +                              return (ENOBUFS);
 +                      }
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        m_head = m_pullup(m_head, poff + (tp->th_off << 2));
                        if (m_head == NULL) {
 
 -- 
 Computer Centre                             E-mail: la...@fit.vutbr.cz
 Faculty of Information Technology           Web: http://www.fit.vutbr.cz/
 Brno University of Technology               Fax:  +420 54114-1270
 Bozetechova 2, 612 66 Brno, Czech Republic  Phone: +420 54114-1225
 
 --y0ulUmNC+osPPQO6
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="if_em.patch"
 
 *** if_em.c.old        2011-01-18 15:52:21.000000000 +0100
 --- if_em.c    2011-01-18 15:58:11.000000000 +0100
 ***************
 *** 1820,1831 ****
                }
                ip = (struct ip *)(mtod(m_head, char *) + ip_off);
                poff = ip_off + (ip->ip_hl << 2);
 -              m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 -              if (m_head == NULL) {
 -                      *m_headp = NULL;
 -                      return (ENOBUFS);
 -              }
                if (do_tso) {
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        /*
                         * TSO workaround:
 --- 1820,1831 ----
                }
                ip = (struct ip *)(mtod(m_head, char *) + ip_off);
                poff = ip_off + (ip->ip_hl << 2);
                if (do_tso) {
 +                      m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 +                      if (m_head == NULL) {
 +                              *m_headp = NULL;
 +                              return (ENOBUFS);
 +                      }
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        /*
                         * TSO workaround:
 ***************
 *** 1849,1854 ****
 --- 1849,1859 ----
                        tp->th_sum = in_pseudo(ip->ip_src.s_addr,
                            ip->ip_dst.s_addr, htons(IPPROTO_TCP));
                } else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
 +                      m_head = m_pullup(m_head, poff + sizeof(struct tcphdr));
 +                      if (m_head == NULL) {
 +                              *m_headp = NULL;
 +                              return (ENOBUFS);
 +                      }
                        tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
                        m_head = m_pullup(m_head, poff + (tp->th_off << 2));
                        if (m_head == NULL) {
 
 --y0ulUmNC+osPPQO6--
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to