From: Sepherosa Ziehau Date: Sun, 5 Apr 2009 03:38:23 +0000 (+0800) Subject: ether_input: Defer promiscous packet discarding until vlan is processed X-Git-Tag: v2.3.1~152^2~82 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/469c71d1f6bd6a094b41492eeaefd40b69892068 ether_input: Defer promiscous packet discarding until vlan is processed This is the one of the precondition to make vlan/bridge work: preventing packets from being dropped prematurely by vlan's parent interface. --- diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 26b14be..5a18bc4 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1091,7 +1091,7 @@ void ether_demux_oncpu(struct ifnet *ifp, struct mbuf *m) { struct ether_header *eh; - int isr, redispatch; + int isr, redispatch, discard = 0; u_short ether_type; struct ip_fw *rule = NULL; #ifdef NETATALK @@ -1144,20 +1144,20 @@ ether_demux_oncpu(struct ifnet *ifp, struct mbuf *m) #endif /* - * Discard packet if upper layers shouldn't see it because - * it was unicast to a different Ethernet address. If the - * driver is working properly, then this situation can only - * happen when the interface is in promiscuous mode. + * We got a packet which was unicast to a different Ethernet + * address. If the driver is working properly, then this + * situation can only happen when the interface is in + * promiscuous mode. We defer the packet discarding until the + * vlan processing is done, so that vlan/bridge or vlan/netgraph + * could work. */ if (((ifp->if_flags & (IFF_PROMISC | IFF_PPROMISC)) == IFF_PROMISC) && !ETHER_IS_MULTICAST(eh->ether_dhost) && - bcmp(eh->ether_dhost, IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN)) { - m_freem(m); - return; - } + bcmp(eh->ether_dhost, IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN)) + discard = 1; post_stats: - if (IPFW_LOADED && ether_ipfw != 0) { + if (IPFW_LOADED && ether_ipfw != 0 && !discard) { struct ether_header save_eh = *eh; /* XXX old crufty stuff, needs to be removed */ @@ -1191,6 +1191,16 @@ post_stats: } /* + * If we have been asked to discard this packet + * (e.g. not for us), drop it before entering + * the upper layer. + */ + if (discard) { + m_freem(m); + return; + } + + /* * Clear protocol specific flags, * before entering the upper layer. */