Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Apr 2007 11:35:25 +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:  <20070419073525.GA60301@comp.chem.msu.su>
In-Reply-To: <1176947814.4175.39.camel@hiro.auspc.com.au>
References:  <1176861009.4426.21.camel@hiro.auspc.com.au> <20070418120622.GF40826@comp.chem.msu.su> <1176947814.4175.39.camel@hiro.auspc.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Apr 19, 2007 at 11:56:54AM +1000, Alan Garfield wrote:
> On Wed, 2007-04-18 at 16:06 +0400, Yar Tikhiy wrote:
> >  
> > > I just want an idea of the structures involved, and what I need to
> > > implement to intercept and injecting a fake MAC so my buffer driver can
> > > communicate with the other side without ARP errors.
> > 
> > Could you tell more details on the problem you are trying to solve
> > now.  Sorry, but I fail to see what errors you get, and why.  Doesn't
> > the Service Processor on the other side of that little Ethernet
> > link behave as a conventional IP host?
> 
> Well it sort of does and it sort of doesn't unfortunately. It's MAC
> addresses are faked in the driver on both sides, and any ARP requests
> are caught and a fake response is generated. It's a wee bit ugly.

I wonder if this hack can be avoided...  The other side could
just respond to our ARP requests.

> >From the GPL Linux driver
> ----
> 
> int jnet_tx(struct sk_buff *skb, struct net_device *dev)
> {
> 
> [...]
> 
>     if(htons(eth->h_proto) == ETH_P_ARP &&
>         arp->ar_op == ARPOP_REQUEST) {
>         //send fake response.
>         jnet_arpResponse(dev);
>         netif_wake_queue(jnet_devs);
>         priv->fifoFull = FALSE;
>         dev_kfree_skb(skb);         // Free the SKB for arps too.
>     } else {
>         //so send the data
> 
>         [...]
>     }
> }       
> 
> ----
> 
> void jnet_arpResponse( struct net_device *dev )
> {
> 
> [...]
> 
>     //Fill in all the blanks.
>     memcpy(&ethArp.eth.h_dest, localMac, sizeof(localMac));
>     memcpy(&ethArp.eth.h_source, remoteMac, sizeof(remoteMac));
>     ethArp.eth.h_proto = ETH_P_ARP;
> 
>     ethArp.arp.ar_hrd = htons(ARPHRD_ETHER);
>     ethArp.arp.ar_pro = htons(ETH_P_IP);
>     ethArp.arp.ar_hln = sizeof(localMac);
>     ethArp.arp.ar_pln = sizeof(uint32_t);
>     ethArp.arp.ar_op = htons(ARPOP_REPLY);
> 
>     memcpy(&ethArp.ar_sha, remoteMac, sizeof(remoteMac));
>     memcpy(&ethArp.ar_sip, &priv->myConfigIpSettings.platIp,
> sizeof(uint32_t));
> 
>     memcpy(&ethArp.ar_tha, localMac, sizeof(localMac));
>     memcpy(&ethArp.ar_tip, &priv->myConfigIpSettings.spIp,
> sizeof(uint32_t));
> 
> [...]
> 
> }
> 
> ----
> 
> The problem I'm really seeing is I'm getting no mbuf's in my
> jnet_start(). It always returns zero.
> 
> ----
> 
> static void
> jnet_start_locked(struct ifnet* ifp)
> {
>         // {{{ 
>         struct jnet_softc *sc = ifp->if_softc;
> 
>         struct mbuf *m0, *m;
> 
>         device_printf(sc->dev, "jnet_start_locked() called.\n");
> 
>         JNET_ASSERT_LOCKED(sc);
>         
> outputloop:
> 
>         // Check if there are buffered packets and an we're idle which 
>         // shouldn't happen at this point
>         if (sc->txb_inuse && (sc->tx_busy == 0)) {
>                 device_printf(sc->dev, "packets buffered, but tx
> idle.\n");
>                 jnet_tx(sc);
>         }
> 
>         // Check if there is room to put another packet in the buffer.
>         if (sc->txb_inuse == sc->txb_cnt) {
> 
>                 device_printf(sc->dev, "No room left in tx buffer.\n");
> 
>                 // 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) {
> 
>                 device_printf(sc->dev, "m == 0.\n");
> 
>                 // If buffers aren't filled we can still accept
>                 // more packets. So reset OACTIVE
>                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
>                 return;
>         }
> 
>         // Copy mbuf to PRS
>         m0 = m;
>         
>         //set address counter to zero, then read the entire fifo
>         //bus_space_write_1(sc->iot[JNET_IOREGS], sc->ioh[JNET_IOREGS],
> JNET_STS_OFFSET, 0x00);
>         
> 
>         device_printf(sc->dev, "mbuf len: %i.\n", m0->m_len);
> 
> 	// Output to PRS buffer
> 	[...]        
> 
>         sc->txb_inuse++;
> 
>         m_freem(m0);
> 
>         // Loop to top to possibly buffer more packets
>         goto outputloop;
> 
> 
>         // }}}
> }
> 
> ----
> 
> ... and I get these ARP errors.
> 
> ----
> jnet0: <JNet Ethernet System Interface> port 0xa8,0xae-0xaf irq 19 on
> acpi0
> jnet0: Ethernet address: 00:09:3d:00:00:03
> jnet0: jnet_start_locked() called.
> jnet0: m == 0.
> jnet0: RTM_ADD. 
> arplookup 169.254.101.2 failed: could not allocate llinfo
> arpresolve: can't allocate route for 169.254.101.2
> ----
> 
> ... whenever I try and send anything.

Did you set the maximum lengths for the output queue and the driver
queue in the attach function?

-- 
Yar



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