Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jul 2014 10:49:47 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r268209 - head/sys/dev/usb/net
Message-ID:  <201407031049.s63Anl9t081449@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu Jul  3 10:49:46 2014
New Revision: 268209
URL: http://svnweb.freebsd.org/changeset/base/268209

Log:
  - Disable hardware checksumming until it is properly tested.
  - Don't discard frames if the dropped or error flag is set.
  - Don't remove the last 4-bytes of every packet.
  - Add extra range check for data position offset when receiving data.
  
  MFC after:	1 day
  PR:		191432

Modified:
  head/sys/dev/usb/net/if_axge.c

Modified: head/sys/dev/usb/net/if_axge.c
==============================================================================
--- head/sys/dev/usb/net/if_axge.c	Thu Jul  3 08:07:37 2014	(r268208)
+++ head/sys/dev/usb/net/if_axge.c	Thu Jul  3 10:49:46 2014	(r268209)
@@ -123,8 +123,8 @@ static int	axge_attach_post_sub(struct u
 static int	axge_ifmedia_upd(struct ifnet *);
 static void	axge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 static int	axge_ioctl(struct ifnet *, u_long, caddr_t);
-static int	axge_rx_frame(struct usb_ether *, struct usb_page_cache *, int);
-static int	axge_rxeof(struct usb_ether *, struct usb_page_cache *,
+static void	axge_rx_frame(struct usb_ether *, struct usb_page_cache *, int);
+static void	axge_rxeof(struct usb_ether *, struct usb_page_cache *,
 		    unsigned int, unsigned int, uint32_t);
 static void	axge_csum_cfg(struct usb_ether *);
 
@@ -605,8 +605,7 @@ axge_bulk_read_callback(struct usb_xfer 
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
 		pc = usbd_xfer_get_frame(xfer, 0);
-		if (axge_rx_frame(ue, pc, actlen) != 0)
-			goto tr_setup;
+		axge_rx_frame(ue, pc, actlen);
 
 		/* FALLTHROUGH */
 	case USB_ST_SETUP:
@@ -926,12 +925,11 @@ axge_ioctl(struct ifnet *ifp, u_long cmd
 	return (error);
 }
 
-static int
+static void
 axge_rx_frame(struct usb_ether *ue, struct usb_page_cache *pc, int actlen)
 {
-	int error;
-	int pos;
-	int pkt_cnt;
+	uint32_t pos;
+	uint32_t pkt_cnt;
 	uint32_t rxhdr;
 	uint32_t pkt_hdr;
 	uint32_t hdr_off;
@@ -939,10 +937,9 @@ axge_rx_frame(struct usb_ether *ue, stru
 
 	/* verify we have enough data */
 	if (actlen < (int)sizeof(rxhdr))
-		return (EINVAL);
+		return;
 
 	pos = 0;
-	error = 0;
 
 	usbd_copy_out(pc, actlen - sizeof(rxhdr), &rxhdr, sizeof(rxhdr));
 	rxhdr = le32toh(rxhdr);
@@ -950,35 +947,36 @@ axge_rx_frame(struct usb_ether *ue, stru
 	pkt_cnt = (uint16_t)rxhdr;
 	hdr_off = (uint16_t)(rxhdr >> 16);
 
-	while (pkt_cnt > 0) {
+	while (pkt_cnt--) {
 		/* verify the header offset */
 		if ((int)(hdr_off + sizeof(pkt_hdr)) > actlen) {
-			error = EINVAL;
+			DPRINTF("End of packet headers\n");
+			break;
+		}
+		if ((int)pos >= actlen) {
+			DPRINTF("Data position reached end\n");
 			break;
 		}
 		usbd_copy_out(pc, hdr_off, &pkt_hdr, sizeof(pkt_hdr));
 
 		pkt_hdr = le32toh(pkt_hdr);
 		pktlen = (pkt_hdr >> 16) & 0x1fff;
-		if ((pkt_hdr & AXGE_RXHDR_CRC_ERR) ||
-		    (pkt_hdr & AXGE_RXHDR_DROP_ERR))
+		if (pkt_hdr & (AXGE_RXHDR_CRC_ERR | AXGE_RXHDR_DROP_ERR)) {
+			DPRINTF("Dropped a packet\n");
 			ue->ue_ifp->if_ierrors++;
-		/* verify the data payload */
-		if (pktlen < 6 || (int)(pos + 2 + pktlen - 6) > actlen) {
-			error = EINVAL;
-			break;
 		}
-		axge_rxeof(ue, pc, pos + 2, pktlen - 6, pkt_hdr);
+		if (pktlen >= 2 && (int)(pos + pktlen) <= actlen) {
+			axge_rxeof(ue, pc, pos + 2, pktlen - 2, pkt_hdr);
+		} else {
+			DPRINTF("Invalid packet pos=%d len=%d\n",
+			    (int)pos, (int)pktlen);
+		}
 		pos += (pktlen + 7) & ~7;
 		hdr_off += sizeof(pkt_hdr);
-		pkt_cnt--;
 	}
-	if (error != 0)
-		ue->ue_ifp->if_ierrors++;
-	return (error);
 }
 
-static int
+static void
 axge_rxeof(struct usb_ether *ue, struct usb_page_cache *pc,
     unsigned int offset, unsigned int len, uint32_t pkt_hdr)
 {
@@ -988,37 +986,34 @@ axge_rxeof(struct usb_ether *ue, struct 
 	ifp = ue->ue_ifp;
 	if (len < ETHER_HDR_LEN || len > MCLBYTES - ETHER_ALIGN) {
 		ifp->if_ierrors++;
-		return (EINVAL);
+		return;
 	}
 
 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
 	if (m == NULL) {
 		ifp->if_iqdrops++;
-		return (ENOMEM);
+		return;
 	}
-	m->m_len = m->m_pkthdr.len = MCLBYTES;
+	m->m_pkthdr.rcvif = ifp;
+	m->m_len = m->m_pkthdr.len = len + ETHER_ALIGN;
 	m_adj(m, ETHER_ALIGN);
 
 	usbd_copy_out(pc, offset, mtod(m, uint8_t *), len);
 
 	ifp->if_ipackets++;
-	m->m_pkthdr.rcvif = ifp;
-	m->m_pkthdr.len = m->m_len = len;
-
+#if 0
 	if ((pkt_hdr & (AXGE_RXHDR_L4CSUM_ERR | AXGE_RXHDR_L3CSUM_ERR)) == 0) {
-		m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | CSUM_IP_VALID;
 		if ((pkt_hdr & AXGE_RXHDR_L4_TYPE_MASK) ==
 		    AXGE_RXHDR_L4_TYPE_TCP ||
 		    (pkt_hdr & AXGE_RXHDR_L4_TYPE_MASK) ==
 		    AXGE_RXHDR_L4_TYPE_UDP) {
 			m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
-			    CSUM_PSEUDO_HDR;
+			    CSUM_PSEUDO_HDR | CSUM_IP_CHECKED | CSUM_IP_VALID;
 			m->m_pkthdr.csum_data = 0xffff;
 		}
 	}
-
+#endif
 	_IF_ENQUEUE(&ue->ue_rxq, m);
-	return (0);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407031049.s63Anl9t081449>