Re: promisc/netgraph question
Martin Mayer <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.net |
|---|---|
| Message-ID | <FR2PPF447E0FD2F1C0AF06E177E455A49AEBC60A@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM> |
Hello Gleb,
thanks for the patch. I did a quick check and it does not work as expected.
If my understanding is correct (correct me if I'm wrong), the problem is not that M_PROMISC needs to be restored in the same routine.
The problem seems to be that ether_input_internal() is not executed till the end if netgraph (or bridge) claims the frame.
All destination address checks are performed at the end of ether_input_internal() and are skipped if netgraph claims a frame.
Because M_PROMISC is always set to 0 before the frame is being passed to netgraph, and netgraph passes the mbuf to ether_demux(), there is never a chance for M_PROMISC to survive in the chain even if destination address checks were performed and M_PROMISC was set accordingly - it is always unset.
As M_PROMISC together with M_PPROMISC are the only indicators for ether_demux() to drop a frame, this never happens.
Maybe I understand something wrong...?
I think it may be worth thinking about re-ordering the checks or moving them to ether_demux().
--------------------------------------------------
I also did a dirty test with the following. Of course this can't be a solution but it adds an (incomplete) check to ether_demux() and mitigates the issue.
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 9c157bf3d..4cfddafd6 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -890,6 +890,10 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
return;
}
+ if (!ETHER_IS_MULTICAST(eh->ether_dhost) &&
+ memcmp(IF_LLADDR(ifp), eh->ether_dhost, ETHER_ADDR_LEN) != 0)
+ m->m_flags |= M_PROMISC;
+
/*
* Pass promiscuously received frames to the upper layer if the user
* requested this by setting IFF_PPROMISC. Otherwise, drop them.
--------------------------------------------------
Just for information how I did the network tests:
sysctl net.inet.ip.forwarding=1
ngctl mkpeer em0: tee lower left && \
ngctl name em0:lower tee1 && \
ngctl connect em0: tee1: upper right
ngctl msg em0: setpromisc 1
--------------------------------------------------
Regards,
Martin