Date: Mon, 5 May 2014 17:30:05 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265371 - head/sys/dev/usb/net Message-ID: <201405051730.s45HU5cV006016@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Mon May 5 17:30:05 2014 New Revision: 265371 URL: http://svnweb.freebsd.org/changeset/base/265371 Log: Fill in csum_data only for UDP or TCP packets. This fixes a bug where SCTP were reported to have always a correct checksum if they don't contain any ethernet padding. MFC after: 3 days Modified: head/sys/dev/usb/net/if_smsc.c Modified: head/sys/dev/usb/net/if_smsc.c ============================================================================== --- head/sys/dev/usb/net/if_smsc.c Mon May 5 17:06:40 2014 (r265370) +++ head/sys/dev/usb/net/if_smsc.c Mon May 5 17:30:05 2014 (r265371) @@ -86,6 +86,9 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/if_var.h> +#include <netinet/in.h> +#include <netinet/ip.h> + #include "opt_platform.h" #ifdef FDT @@ -1025,25 +1028,32 @@ smsc_bulk_read_callback(struct usb_xfer * * Ignore H/W csum for non-IPv4 packets. */ - if (be16toh(eh->ether_type) == ETHERTYPE_IP && pktlen > ETHER_MIN_LEN) { - - /* Indicate the UDP/TCP csum has been calculated */ - m->m_pkthdr.csum_flags |= CSUM_DATA_VALID; - - /* Copy the TCP/UDP checksum from the last 2 bytes - * of the transfer and put in the csum_data field. - */ - usbd_copy_out(pc, (off + pktlen), - &m->m_pkthdr.csum_data, 2); - - /* The data is copied in network order, but the - * csum algorithm in the kernel expects it to be - * in host network order. - */ - m->m_pkthdr.csum_data = ntohs(m->m_pkthdr.csum_data); - - smsc_dbg_printf(sc, "RX checksum offloaded (0x%04x)\n", - m->m_pkthdr.csum_data); + if ((be16toh(eh->ether_type) == ETHERTYPE_IP) && + (pktlen > ETHER_MIN_LEN)) { + struct ip *ip; + + ip = (struct ip *)(eh + 1); + if ((ip->ip_v == IPVERSION) && + ((ip->ip_p == IPPROTO_TCP) || + (ip->ip_p == IPPROTO_UDP))) { + /* Indicate the UDP/TCP csum has been calculated */ + m->m_pkthdr.csum_flags |= CSUM_DATA_VALID; + + /* Copy the TCP/UDP checksum from the last 2 bytes + * of the transfer and put in the csum_data field. + */ + usbd_copy_out(pc, (off + pktlen), + &m->m_pkthdr.csum_data, 2); + + /* The data is copied in network order, but the + * csum algorithm in the kernel expects it to be + * in host network order. + */ + m->m_pkthdr.csum_data = ntohs(m->m_pkthdr.csum_data); + + smsc_dbg_printf(sc, "RX checksum offloaded (0x%04x)\n", + m->m_pkthdr.csum_data); + } } /* Need to adjust the offset as well or we'll be off
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405051730.s45HU5cV006016>