From owner-freebsd-current@FreeBSD.ORG Tue Aug 28 04:00:27 2007 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E77CD16A469 for ; Tue, 28 Aug 2007 04:00:27 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from heff.fud.org.nz (203-109-251-39.static.bliink.ihug.co.nz [203.109.251.39]) by mx1.freebsd.org (Postfix) with ESMTP id 725DD13C458 for ; Tue, 28 Aug 2007 04:00:27 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: by heff.fud.org.nz (Postfix, from userid 1001) id 09EF61CC58; Tue, 28 Aug 2007 16:00:26 +1200 (NZST) Date: Tue, 28 Aug 2007 16:00:26 +1200 From: Andrew Thompson To: FreeBSD Current Message-ID: <20070828040026.GB42201@heff.fud.org.nz> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="QTprm0S8XgL7H0Dt" Content-Disposition: inline User-Agent: Mutt/1.5.13 (2006-08-11) Cc: Subject: multicast packets from bpf X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Aug 2007 04:00:28 -0000 --QTprm0S8XgL7H0Dt Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, At the moment packets injected via bpf do not get the M_BCAST or M_MCAST flags set. One consequence of this is that it messes up broadcasting from if_bridge which assumes these flags are correct, using dhcpd on a bridge interface is one way to trigger it. Attached is a patch (bpf_mcast.diff) that fixes this up. There is some concern about having bpf inspecting the protocol headers but i seems unavoidable in order to determine if its multicast. tap(4) was also thought to have this problem but it turned out not to since it passes the frames to ether_input. The other way is for the bridge to recheck for multicast destinations for locally generated packets (bridge_bpfmcast.diff), but this is less desirable. Andrew --QTprm0S8XgL7H0Dt Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bpf_mcast.diff" 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 01:34:27 -0000 @@ -599,6 +599,7 @@ bpfwrite(struct cdev *dev, struct uio *u struct ifnet *ifp; struct mbuf *m, *mc; struct sockaddr dst; + struct ether_header *eh; int error, hlen; if (d->bd_bif == NULL) @@ -620,6 +621,20 @@ bpfwrite(struct cdev *dev, struct uio *u if (error) return (error); + /* Check for multicast destination */ + switch (d->bd_bif->bif_dlt) { + 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; + } + if (d->bd_hdrcmplt) dst.sa_family = pseudo_AF_HDRCMPLT; --QTprm0S8XgL7H0Dt Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="bridge_bpfmcast.diff" Index: if_bridge.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_bridge.c,v retrieving revision 1.102 diff -u -p -r1.102 if_bridge.c --- if_bridge.c 1 Aug 2007 00:33:52 -0000 1.102 +++ if_bridge.c 14 Aug 2007 02:11:16 -0000 @@ -1852,9 +1852,16 @@ bridge_start(struct ifnet *ifp) dst_if = NULL; BRIDGE_LOCK(sc); - if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { + if (ETHER_IS_MULTICAST(eh->ether_dhost)) + /* + * XXX bpf injected packets do not have M_MCAST or + * M_BCAST set, bridge_broadcast() makes assumptions + * based on this. + */ + if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) + m->m_flags |= M_MCAST; + else dst_if = bridge_rtlookup(sc, eh->ether_dhost, 1); - } if (dst_if == NULL) bridge_broadcast(sc, ifp, m, 0); --QTprm0S8XgL7H0Dt--