Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Mar 2000 08:54:33 -0500 (EST)
From:      Robert Watson <robert@cyrus.watson.org>
To:        Kurakin Roman <rik@cronyx.ru>
Cc:        freebsd-net@FreeBSD.ORG
Subject:   Re: Patch to introduce bpfdetach(), Re: BPF question (FreeBSD 40)
Message-ID:  <Pine.NEB.3.96L.1000320075500.11447A-100000@fledge.watson.org>
In-Reply-To: <38D61561.EADEDB6A@cronyx.ru>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 20 Mar 2000, Kurakin Roman wrote:

> Robert Watson wrote:
> 
> > On Sat, 18 Mar 2000, Kurakin Roman wrote:
> >
> > >     I have question about using bpf in my KLD module driver. At attach I
> > > call
> > > bpfattach function. What should I call at detach?
> > > Could some one describe to me how bpf is work (function calls, not bpf
> > > as pf :)).
> >
> > I noticed the same behavior a few weeks ago when using tcpdump in wi0 and
> > ejecting the card.  This occurs if there are open bpf descriptors for the
> > device, and ifdetach is called (freeing the ifnet structure), at the
> > bp_bif pointer is not set to NULL.
> 
> So, the problems would be if bpf was opened while we tried to detach
> driver?  If so, I have another solution. Driver should return EBUSY, if
> bpf is open at the moment we try to detach driver. User should close all
> references to the device before its unloading.  But I don't know what
> would be if I try to open bpf after I removed my driver from the kernel. 
> At this moment I can only give some ideas. I never worked with bpf as
> user :(

BPF provides a file-like interface to packet streams.  You open the first
available /dev/bpfX, and then use some ioctl calls to indicate:

- What interface to attach to (identified in an ifreq)
- Buffer size
- Promiscuous or not
- What packets you're interested in

So the problem isn't so much the bpf open, as much as whether there is
currently a bpf device actively monitoring the interface on which
ifdetach() is called.  Once if_detach is called, the interface is no
longer available for bpf to attach to, so if the ioctl is called to
connect to the detached interface, ENXIO will be returned.  I.e., the
device has literally ceased to be configured (it doesn't turn up in
ifconfig -a, ifconfig returns ENXIO, etc). 

The problem is those open BPF sessions, because the BPF descriptor for the
session maintains a pointer to the ifnet structure describing the
interface in the kernel.  This structure is not refcounted, and one of the
actions performed in if_detach() is to free that structure.  The two
obvious fixes are: 1) locate all references and remove them, and 2) add
refcounting.

I chose (1) as it appears to be more consistent.  It doesn't make sense to
be sniffing an interface that isn't there, especially if you don't know if
it's coming back.  It makes more sense to notify the userland application
that it no longer exists, so the application can do something different,
rather than being stuck blocked in a read() or select().  (2) would
involve more work to implement, and doesn't necessarily add any benefit.
In particular, if you did do this, you'd probably want to reconnect the
sniffing application to the interface if it was recreated--however, most
drivers re-malloc their interface structure in each pass, so you'd still
need to rewrite pointers to interface structures.

I suspect that bpfdetach(ifp) is the most consistent way to do this.  When
the interface is attached, it is registered with bpf.  When it is
detached, it is unregistered, and listeners are notified.

  Robert N M Watson 

robert@fledge.watson.org              http://www.watson.org/~robert/
PGP key fingerprint: AF B5 5F FF A6 4A 79 37  ED 5F 55 E9 58 04 6A B1
TIS Labs at Network Associates, Safeport Network Services



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1000320075500.11447A-100000>