lkml.org 
[lkml]   [1996]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectSOCK_PACKET bug with ETH_P_ALL?
I run 3 diald processes on a Linux box sitting on a pretty busy ethernet. 
I recently noticed that each of these dialds was using 1-3% cpu time, even
when the proxies were idle. Turning on promisc mode on eth0 pushed that
through the roof. 'strace'ing a diald produced results along the line of:

select(100, [1 2 4], NULL, NULL, {0, 990000}) = 1 (in [2], left {0, 710000})
recvfrom(2, "\377\377\377\377\377\377\252\0\4"..., 4096, 0,
{sun_family=AF_UNIX, sun_path="eth0"}, [16]) = 142
time(NULL) = 842498155
time(NULL) = 842498155
select(100, [1 2 4], NULL, NULL, {0, 710000}) = 1 (in [2], left {0, 520000})
recvfrom(2, "\377\377\377\377\377\377\252\0\4"..., 4096, 0,
{sun_family=AF_UNIX, sun_path="eth0"}, [16]) = 111
time(NULL) = 842498155
time(NULL) = 842498155
select(100, [1 2 4], NULL, NULL, {0, 520000}) = 1 (in [2], left {0, 190000})
recvfrom(2, "\377\377\377\377\377\377\0\200\243"..., 4096, 0,
{sun_family=AF_UNIX, sun_path="eth0"}, [16]) = 110
time(NULL) = 842498155
time(NULL) = 842498155

(etc)

It looks like the snoop device is still receiving packets from eth0,
despite the fact that descriptor 2, a SOCK_PACKET socket, has successfully
called bind() to bind to the slip proxy.

Looking in net/core/dev.c, it looks like net_bh is forwarding packets that
it shouldn't - it forwards packets to a packet-capture function with
protocol ETH_P_ALL regardless of the value of ptype->dev.

I changed this to check the device, and the dialds magically went to 0%
cpu :) ... a patch is attached (against 2.0.14, but I didn't see any
changes to this bit of code in 15-18). I did a grep for ETH_P_ALL and the
kernel code doesn't seem to use it, so hopefully this doesn't break
anything else.

Is it worth moving the ptype_all list for sniffers bound to a specific
device into the device struct? The current setup means that such a sniffer
will cause a check of the entire ptype_all list for every packet received
on _any_ device - which could become a problem with eg. multiple dialds
(large ptype_all list) and a busy ethernet.

Oliver.
(oliver@sa-search.massey.ac.nz, in case sendmail decides to mangle it)
--- linux/net/core/dev.c.old Thu Sep 12 15:18:37 1996
+++ linux/net/core/dev.c Thu Sep 12 15:28:13 1996
@@ -654,13 +654,17 @@
pt_prev = NULL;
for (ptype = ptype_all; ptype!=NULL; ptype=ptype->next)
{
- if(pt_prev)
+ /* Make sure we only pass on packets for the right device */
+ if (!ptype->dev || ptype->dev==skb->dev)
{
- struct sk_buff *skb2=skb_clone(skb, GFP_ATOMIC);
- if(skb2)
- pt_prev->func(skb2,skb->dev, pt_prev);
- }
- pt_prev=ptype;
+ 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;
+ }
}

for (ptype = ptype_base[ntohs(type)&15]; ptype != NULL; ptype = ptype->next)
\
 
 \ /
  Last update: 2005-03-22 13:37    [W:0.053 / U:1.472 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site