From owner-freebsd-net@FreeBSD.ORG Sat Feb 10 21:17:55 2007 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1EDDD16A400 for ; Sat, 10 Feb 2007 21:17:55 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from out5.smtp.messagingengine.com (out5.smtp.messagingengine.com [66.111.4.29]) by mx1.freebsd.org (Postfix) with ESMTP id D8C9413C491 for ; Sat, 10 Feb 2007 21:17:54 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from out1.internal (unknown [10.202.2.149]) by out1.messagingengine.com (Postfix) with ESMTP id 28D911A9ACE for ; Sat, 10 Feb 2007 16:17:53 -0500 (EST) Received: from heartbeat2.messagingengine.com ([10.202.2.161]) by out1.internal (MEProxy); Sat, 10 Feb 2007 16:17:53 -0500 X-Sasl-enc: IUcyb5tWDtwrGwhCr2gJJoSbHGJVTZLKob5lY2BhObhn 1171142272 Received: from [192.168.123.18] (82-35-112-254.cable.ubr07.dals.blueyonder.co.uk [82.35.112.254]) by mail.messagingengine.com (Postfix) with ESMTP id 91BC71569C for ; Sat, 10 Feb 2007 16:17:52 -0500 (EST) Message-ID: <45CE3680.2010103@incunabulum.net> Date: Sat, 10 Feb 2007 21:17:52 +0000 From: Bruce M Simpson User-Agent: Thunderbird 1.5.0.9 (X11/20070125) MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: multipart/mixed; boundary="------------030408010207040301060400" Subject: [PATCH] Introduce M_PROMISC to lower part of Ethernet code X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Feb 2007 21:17:55 -0000 This is a multi-part message in MIME format. --------------030408010207040301060400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, Thunderbird keeps crashing whenever I draft these messages, which is frustrating. Can we discuss this change? I would like to get it in as we get the following wins: 1. Potentially cleaner code in ether_demux()/ether_input() 2. Ways of detecting and preventing L2/L3 forwarding loops 3. Being able to do more with promiscuous mode in general e.g. using it to emulate broken IFF_ALLMULTI with network cards which can't support multicast routing properly. Feedback eagerly looked forward to; this is not a complete change; this is strictly development quality at the moment. Regards, BMS --------------030408010207040301060400 Content-Type: text/x-patch; name="promisc2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="promisc2.diff" Index: net/if_ethersubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.222 diff -u -p -r1.222 if_ethersubr.c --- net/if_ethersubr.c 24 Dec 2006 08:52:13 -0000 1.222 +++ net/if_ethersubr.c 10 Feb 2007 20:59:39 -0000 @@ -582,6 +582,7 @@ ether_input(struct ifnet *ifp, struct mb if (IFP2AC(ifp)->ac_netgraph != NULL) { KASSERT(ng_ether_input_p != NULL, ("ng_ether_input_p is NULL")); + m->m_flags &= ~M_PROMISC; (*ng_ether_input_p)(ifp, &m); if (m == NULL) return; @@ -598,6 +599,7 @@ ether_input(struct ifnet *ifp, struct mb * at the src/sys/netgraph/ng_ether.c:ng_ether_rcv_upper() */ if (ifp->if_bridge) { + m->m_flags &= ~M_PROMISC; BRIDGE_INPUT(ifp, m); if (m == NULL) return; @@ -634,6 +636,14 @@ ether_demux(struct ifnet *ifp, struct mb if (rule) /* packet was already bridged */ goto post_stats; #endif + /* + * If the frame was received promiscuously, mark it as such. + */ + if ((ifp->if_flags & IFF_PROMISC) && + !ETHER_IS_MULTICAST(eh->ether_dhost) && + bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) { + m->m_flags |= M_PROMISC; + } if (!(ifp->if_bridge) && !((ether_type == ETHERTYPE_VLAN || m->m_flags & M_VLANTAG) && @@ -648,8 +658,10 @@ ether_demux(struct ifnet *ifp, struct mb * evaluation, to see if the carp ether_dhost values break any * of these checks! */ - if (ifp->if_carp && carp_forus(ifp->if_carp, eh->ether_dhost)) + if (ifp->if_carp && carp_forus(ifp->if_carp, eh->ether_dhost)) { + m->m_flags &= ~M_PROMISC; goto pre_stats; + } #endif /* * Discard packet if upper layers shouldn't see it because it @@ -662,14 +674,16 @@ ether_demux(struct ifnet *ifp, struct mb * give them a chance to consider it as well (e. g. in case * bridging is only active on a VLAN). They will drop it if * it's undesired. + * + * XXX: There is no way this check can be invoked if + * there are no VLANs attached to this parent interface, + * which is likely to cause recursion if we're acting + * as an IP forwarder... */ - if ((ifp->if_flags & IFF_PROMISC) != 0 - && !ETHER_IS_MULTICAST(eh->ether_dhost) - && bcmp(eh->ether_dhost, - IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0 - && (ifp->if_flags & IFF_PPROMISC) == 0) { - m_freem(m); - return; + if ((m->m_flags & M_PROMISC) && + (ifp->if_flags & IFF_PPROMISC) == 0) { + m_freem(m); + return; } } @@ -720,6 +734,7 @@ post_stats: * or drop the packet. */ KASSERT(vlan_input_p != NULL,("ether_input: VLAN not loaded!")); + m->m_flags &= ~M_PROMISC; (*vlan_input_p)(ifp, m); return; } @@ -732,6 +747,7 @@ post_stats: case ETHERTYPE_VLAN: if (ifp->if_vlantrunk != NULL) { KASSERT(vlan_input_p,("ether_input: VLAN not loaded!")); + m->m_flags &= ~M_PROMISC; (*vlan_input_p)(ifp, m); } else { ifp->if_noproto++; Index: sys/mbuf.h =================================================================== RCS file: /home/ncvs/src/sys/sys/mbuf.h,v retrieving revision 1.202 diff -u -p -r1.202 mbuf.h --- sys/mbuf.h 25 Jan 2007 01:05:23 -0000 1.202 +++ sys/mbuf.h 10 Feb 2007 20:59:40 -0000 @@ -182,6 +182,7 @@ struct mbuf { #define M_FIRSTFRAG 0x1000 /* packet is first fragment */ #define M_LASTFRAG 0x2000 /* packet is last fragment */ #define M_VLANTAG 0x10000 /* ether_vtag is valid */ +#define M_PROMISC 0x20000 /* packet was not for us */ /* * External buffer types: identify ext_buf type. @@ -203,7 +204,7 @@ struct mbuf { #define M_COPYFLAGS (M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\ M_PROTO3|M_PROTO4|M_PROTO5|M_SKIP_FIREWALL|\ M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG|\ - M_VLANTAG) + M_VLANTAG|M_PROMISC) /* * Flags to purge when crossing layers. --------------030408010207040301060400--