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>