Re: TCP/IP with virtual device dsn0 experience?

Oliver Jowett (oliver@sa-search.massey.ac.nz)
Fri, 28 Feb 1997 20:03:41 +1300 (NZDT)


On Fri, 28 Feb 1997, Nathan Bryant wrote:

> > > Has this behaviour of SOCK_PACKET changed since circa 1.3.70? If so,
> > > dosnet.c could be modified to work with new kernels. (Of course, if
> > > somebody's already done this I may be flapping my jaw needlessly. :)
> >
> > Its changed a bit in that you can bind() them and pass protocol id hints
> > when you want (eg for PPP)
>
> Okay I started reading some kernel code in 2.0.29 and I came across this
> section, which appears to be identical in 2.1.27, btw.
>
> >From net/core/dev.c, about line 650, in net_bh():
>
> /*
> * We got a packet ID. Now loop over the "known protocols"
> * list. There are two lists. The ptype_all list of taps (normally empty)
> * and the main protocol list which is hashed perfectly for normal protocols.
> */
>
> pt_prev = NULL;
> for (ptype = ptype_all; ptype!=NULL; ptype=ptype->next)
> {
> if(pt_prev)
> {
> struct sk_buff *skb2=skb_clone(skb, GFP_ATOMIC);
> if(skb2)
> pt_prev->func(skb2,skb->dev, pt_prev);
> }
> pt_prev=ptype;
> }
>
> Either this is a bug or my brain isn't functioning properly. (The latter
> is a distinct possibility as it's almost midnight. :)
>
> The problem I see is with the pt_prev variable. Why is it even there? It
> looks like this loop will never process the last entry in the ptype_all
> list.

Check further down, after the second loop:

if(pt_prev)
pt_prev->func(skb, skb->dev, pt_prev);

I believe the use of pt_prev is to avoid doing a skb_clone unnecessarily
in the case where there's only one function waiting for that packet.

On the subject of this bit of code: I posted a patch to linux-kernel way
back in the 2.0.14-ish days to fix a problem where _all_ packets are
forwarded to ETH_P_ALL sockets bound to a specific device. It made it into
one of Alan's accumulated patches, but then seems to have disappeared. It
bites (at least) diald, since diald binds to the proxy SLIP device to
avoid processing every packet that comes through the machine, but ends up
getting all the traffic anyway. Try tcpdump on a machine running diald on
a busy ethernet - diald sucks lots of CPU all of a sudden as promisc mode
goes on.

I don't have the patch to hand, but essentially all that is needed is to
insert the same check for binding to devices that is used in the
protocol-specific loop, into the ptype_all loop above.

Oliver

--
"The flames are all long gone / But the pain lingers on..."