multicast packets from bpf

Andrew Thompson thompsa at FreeBSD.org
Tue Aug 28 14:29:27 PDT 2007


On Tue, Aug 28, 2007 at 09:22:10PM +0100, Bruce M. Simpson wrote:
> Andrew Thompson wrote:
> >I had originally started to put it there but realised that I need a
> >pointer to the ifnet to read if_broadcastaddr, I didnt think it was
> >worth changing the function parameters when the check can also just go
> >in bpfwrite. I dont mind moving it if its the more correct place to put
> >it.
> >  
> 
> It's already got a switch..case breakout for the DLTs and knows how to 
> grok the 802.11 header format which can have up to 6 (yes, 6) 802.3 
> style MAC addresses, all of which mean different things depending on 
> whether you are STA, AP, Mesh Portal, Mesh AP... :-)
> 
> So it seems like the right place. bpf_movein() is static and referenced 
> once within its translation unit, so it is a candidate for inlining; I 
> would change ifp-?if_mtu to ifp in the call.

The patch has been updated (attached).

> >Is the tapwrite patch still needed? The mbuf is passed to ether_input
> >which should do the right thing.
> >  
> 
> Good point. A casual reading suggests it *may* no longer be needed since 
> my pass over ether_input(), but seeing as we're due to branch and all, 
> I'll leave garbage collecting the 10 lines in tapwrite() to someone 
> else. :-)

I would leave it there for the moment.


Andrew
-------------- next part --------------
Index: bpf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf.c,v
retrieving revision 1.180
diff -u -p -r1.180 bpf.c
--- bpf.c	6 Aug 2007 14:26:00 -0000	1.180
+++ bpf.c	28 Aug 2007 21:22:59 -0000
@@ -102,7 +102,7 @@ static void	bpf_attachd(struct bpf_d *, 
 static void	bpf_detachd(struct bpf_d *);
 static void	bpf_freed(struct bpf_d *);
 static void	bpf_mcopy(const void *, void *, size_t);
-static int	bpf_movein(struct uio *, int, int, struct mbuf **,
+static int	bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **,
 		    struct sockaddr *, int *, struct bpf_insn *);
 static int	bpf_setif(struct bpf_d *, struct ifreq *);
 static void	bpf_timed_out(void *);
@@ -158,10 +158,11 @@ static struct filterops bpfread_filtops 
 	{ 1, NULL, filt_bpfdetach, filt_bpfread };
 
 static int
-bpf_movein(struct uio *uio, int linktype, int mtu, struct mbuf **mp,
+bpf_movein(struct uio *uio, int linktype, struct ifnet *ifp, struct mbuf **mp,
     struct sockaddr *sockp, int *hdrlen, struct bpf_insn *wfilter)
 {
 	const struct ieee80211_bpf_params *p;
+	struct ether_header *eh;
 	struct mbuf *m;
 	int error;
 	int len;
@@ -241,7 +242,7 @@ bpf_movein(struct uio *uio, int linktype
 
 	len = uio->uio_resid;
 
-	if (len - hlen > mtu)
+	if (len - hlen > ifp->if_mtu)
 		return (EMSGSIZE);
 
 	if ((unsigned)len > MCLBYTES)
@@ -273,6 +274,20 @@ bpf_movein(struct uio *uio, int linktype
 		goto bad;
 	}
 
+	/* Check for multicast destination */
+	switch (linktype) {
+	case DLT_EN10MB:
+		eh = mtod(m, struct ether_header *);
+		if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+			if (bcmp(ifp->if_broadcastaddr, eh->ether_dhost,
+			    ETHER_ADDR_LEN) == 0)
+				m->m_flags |= M_BCAST;
+			else
+				m->m_flags |= M_MCAST;
+		}
+		break;
+	}
+
 	/*
 	 * Make room for link header, and copy it to sockaddr
 	 */
@@ -615,7 +630,7 @@ bpfwrite(struct cdev *dev, struct uio *u
 	bzero(&dst, sizeof(dst));
 	m = NULL;
 	hlen = 0;
-	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp->if_mtu,
+	error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp,
 	    &m, &dst, &hlen, d->bd_wfilter);
 	if (error)
 		return (error);


More information about the freebsd-current mailing list