Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Feb 2026 08:22:40 +0000
From:      Martin Mayer <martin.mayer@m2-it-solutions.de>
To:        Gleb Smirnoff <glebius@freebsd.org>
Cc:        Zhenlei Huang <zlei@freebsd.org>, "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>
Subject:   Re: promisc/netgraph question
Message-ID:  <FR2PPF447E0FD2F1C0AF06E177E455A49AEBC60A@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM>
In-Reply-To: <aY0LwFfMgooz17pW@cell.glebi.us>
References:  <FR2PPF447E0FD2F4AB3B97FDEBCB7FC5404BC9FA@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM> <FR2PPF447E0FD2FA1F4CFD7A4DF76B5DDD1BC9FA@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM> <20260130234931.073ec5df@nuclight.lan> <FR2PPF447E0FD2FF81BF6D4A7538B0D0894BC9CA@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM> <BFA9B02C-7B09-42D5-8DD4-381BA276B68A@FreeBSD.org> <aYDemGI4X7CeifE7@cell.glebi.us> <FR2PPF447E0FD2F9C187C52046BA74A61A1BC67A@FR2PPF447E0FD2F.DEUP281.PROD.OUTLOOK.COM> <aY0LwFfMgooz17pW@cell.glebi.us>

index | next in thread | previous in thread | raw e-mail

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





home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?FR2PPF447E0FD2F1C0AF06E177E455A49AEBC60A>