RE: [PATCH] net: asix: fix bad header length bug

From: David Laight
Date: Thu Feb 06 2014 - 10:29:24 EST


From: Igor Gnatenko
> On Thu, 2014-02-06 at 13:56 +0100, Emil Goode wrote:
> > The AX88772B occasionally send rx packets that cross urb boundaries
> > and the remaining partial packet is sent with no header.
> > When the buffer with a partial packet is of less number of octets
> > than the value of hard_header_len the buffer is discarded by the
> > usbnet module. This is causing dropped packages and error messages
> > in dmesg.
> >
> > This can be reproduced by using ping with a packet size
> > between 1965-1976.
> >
> > The bug has been reported here:
> >
> > https://bugzilla.kernel.org/show_bug.cgi?id=29082
> >
> > Signed-off-by: Emil Goode <emilgoode@xxxxxxxxx>
> Reported-and-tested-by: Igor Gnatenko <i.gnatenko.brain@xxxxxxxxx>
> > ---
> > drivers/net/usb/asix_devices.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
> > index 9765a7d..120bb29 100644
> > --- a/drivers/net/usb/asix_devices.c
> > +++ b/drivers/net/usb/asix_devices.c
> > @@ -455,6 +455,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
> > dev->net->ethtool_ops = &ax88772_ethtool_ops;
> > dev->net->needed_headroom = 4; /* cf asix_tx_fixup() */
> > dev->net->needed_tailroom = 4; /* cf asix_tx_fixup() */
> > + dev->net->hard_header_len = 0; /* Partial packets have no header */

That is the wrong place for the fix.

It should only be done when rx_urb_size is set to a multiple of the usb
packet size.
That is only done for some of the supported devices.

In fact, if the rx_urb_size is a multiple of the usb frame size (or 1k)
then maybe the usbnet code should assume that the driver is capable
of processing ethernet frames that cross usb packet boundaries and
not delete short packets at all - regardless of the hard_header_len.

David

¢éì®&Þ~º&¶¬–+-±éÝ¥Šw®žË±Êâmébžìdz¹Þ)í…æèw*jg¬±¨¶‰šŽŠÝj/êäz¹ÞŠà2ŠÞ¨è­Ú&¢)ß«a¶Úþø®G«éh®æj:+v‰¨Šwè†Ù>Wš±êÞiÛaxPjØm¶Ÿÿà -»+ƒùdš_