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
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.
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"