Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 21 Apr 2007 03:36:19 +0400
From:      Yar Tikhiy <yar@comp.chem.msu.su>
To:        Alan Garfield <alan@fromorbit.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: rtentry and rtrequest
Message-ID:  <20070420233619.GC52136@comp.chem.msu.su>
In-Reply-To: <1177077805.4063.7.camel@hiro.auspc.com.au>
References:  <20070418120622.GF40826@comp.chem.msu.su> <1176947814.4175.39.camel@hiro.auspc.com.au> <20070419073525.GA60301@comp.chem.msu.su> <1176972863.4177.7.camel@hiro.auspc.com.au> <20070419093847.GC60301@comp.chem.msu.su> <1176976273.4177.17.camel@hiro.auspc.com.au> <20070419113842.GE60301@comp.chem.msu.su> <1176990600.4177.26.camel@hiro.auspc.com.au> <20070419175331.GA5999@comp.chem.msu.su> <1177077805.4063.7.camel@hiro.auspc.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Apr 21, 2007 at 12:03:25AM +1000, Alan Garfield wrote:
> On Thu, 2007-04-19 at 21:53 +0400, Yar Tikhiy wrote:
> 
> > 1. Ping the Linux side with packets close to the MTU in size (ping
> > -s), use different data patterns (ping -p), see with tcpdump -X if
> > the data gets damaged.
> 
> Yeah I figured out. I wasn't handling mbuf chains properly so a bit of
> the packet wasn't being put into the buffer. Fixed that now....
> 
> BUT!
> 
> Now I get this after I log in and try to output anything more than a few
> characters (eg. ls -la) :-
> 
> ----
> Disconnecting: Corrupted MAC on input.
> ----

That looks like data corruption happening when TCP segments and/or
IP packets become relatively large, i.e., approach or reach the mtu
limit.

> I'm sure it's something to do with how I'm doing the output. Does this
> look sane?

Well, there's certain space for improvement, but now I fail to find a
bug that would result in corrupted data.

Would you mind testing the link with ping using packets of size
equal to, just below, and slightly above the mtu, and with different
data patterns?  See -s and -p options to ping.  You can observe the
patterns in echo replies with tcpdump -X.  The data patterns in
echo requests and echo replies should be exactly the same.  If they
aren't, the character of corruption can hint you at the bug.

> ----
> static void
> jnet_start_locked(struct ifnet* ifp)
> {
>         /* {{{ */
>         struct jnet_softc *sc = ifp->if_softc;
>         struct mbuf *m0, *m;
>         int i, total_len;
> 
>         //device_printf(sc->dev, "jnet_start_locked() called.\n");
> 
>         JNET_ASSERT_LOCKED(sc);
>         
> outputloop:
>         
>         if ((&ifp->if_snd)->ifq_len == TX_QUEUE_SIZE ||
>                         (&ifp->if_snd)->ifq_drv_len == TX_QUEUE_SIZE) {
>         
>                 /* No room left. Set OACTIVE to tell everyone */
>                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
>                 return;         
>         }
>                         
>         IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
>                         
>         if (m == 0) {
>                 
>                 /* 
>                  * Space is still available in buffers so allow
>                  * new packets to be added
>                  */     
>                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
>                 return;
>         }
>                 
>         m0 = m; 
> 
>         /* set address counter to zero, then read the entire fifo */
>         bus_space_write_1(sc->iot[PRS1_IO_OFFSET],
> sc->ioh[PRS1_IO_OFFSET], PRS1_STATUS_OFFSET, 0x00);
>                 
>         /* Output the IP_CHAR to tell SP the buffer is an IP packet */
>         bus_space_write_1(sc->iot[PRS1_IO_OFFSET],
> sc->ioh[PRS1_IO_OFFSET], PRS1_DATA_OFFSET, IP_CHAR);
> 
>         total_len = 0;
> 
>         // Loop over mbuf chain and output data to PRS1 DATA register -
> Packet max length should
>         // already be worked out by the upper layers
>         while (m0) {
>         
>                 if(m0->m_len) {
>                         total_len += m0->m_len;
> 
>                         /* Output ethernet frame to prs buffer */
>                         bus_space_write_multi_1(sc->iot[PRS1_IO_OFFSET],
> sc->ioh[PRS1_IO_OFFSET],
>                                         PRS1_DATA_OFFSET, mtod(m0,
> unsigned char *), m0->m_len);
> 
>                 }
>                 m0 = m0->m_next;
>         }
> 
>         device_printf(sc->dev, "len: %i padding: %i total: %i\n",
>                         total_len, FRAME_SIZE - total_len, total_len +
> (FRAME_SIZE - total_len));
> 
>         /* Added padding to fill what's left of the buffer */
>         for (i = total_len; i < FRAME_SIZE; i++) {
>                 bus_space_write_1(sc->iot[PRS1_IO_OFFSET],
> sc->ioh[PRS1_IO_OFFSET], PRS1_DATA_OFFSET, 0x00);
>         }
> 
>         m0 = m;
> 
>         BPF_MTAP(ifp, m0);
> 
>         m_freem(m0);
> 
>         /* Loop to top to possibly buffer more packets */
>         goto outputloop;
> }
> ----
> 
> 
> 
> > Nevertheless, it can be a reference driver working with real hardware
> > for other folks to study.
> 
> It's simple enough once I figured out where the pitfalls are. :)
> 
> -A.

-- 
Yar



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