git: 4690891af632 - main - ng_bridge: do not move hosts from learnMac=0 hooks

From: Devin Teske <dteske_at_FreeBSD.org>
Date: Wed, 02 Sep 2026 01:45:36 UTC
The branch main has been updated by dteske:

URL: https://cgit.FreeBSD.org/src/commit/?id=4690891af6320e358e4a2beb3054cd37d065d8d2

commit 4690891af6320e358e4a2beb3054cd37d065d8d2
Author:     Devin Teske <dteske@FreeBSD.org>
AuthorDate: 2026-09-02 01:43:21 +0000
Commit:     Devin Teske <dteske@FreeBSD.org>
CommitDate: 2026-09-02 01:43:21 +0000

    ng_bridge: do not move hosts from learnMac=0 hooks
    
    ng_bridge(4) says the node does not learn MAC addresses on uplink
    hooks. However, learnMac was only checked when inserting a new
    host. A host already known on a link hook was still moved if a
    packet with that source address arrived on an uplink hook.
    
    The nature of this is that inbound unicast to that host then
    never arrives (the destination is known on the incoming hook).
    Unknown unicast after timeout is still sent only to uplink, so
    the host is not re-learned. The interface stays up and outbound
    may still work. This can last minutes or weeks until reboot or
    NGM_BRIDGE_MOVE_HOST.
    
    Connecting ng_ether(4) lower to an uplink hook is enough: the
    host's own transmit can appear on the uplink and the table entry
    moves.
    
    Use the same learnMac test for data-path move as for insert.
    NGM_BRIDGE_MOVE_HOST from userland is unchanged.
    
    MFC after:      1 week
    Reviewed by:    jlduran
    Differential Revision:  https://reviews.freebsd.org/D58902
---
 share/man/man4/ng_bridge.4 | 18 +++++++++++++-----
 sys/netgraph/ng_bridge.c   |  8 ++++++--
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/share/man/man4/ng_bridge.4 b/share/man/man4/ng_bridge.4
index 998c428cbad0..bc5b03ed0f00 100644
--- a/share/man/man4/ng_bridge.4
+++ b/share/man/man4/ng_bridge.4
@@ -32,7 +32,7 @@
 .\"
 .\" Author: Archie Cobbs <archie@FreeBSD.org>
 .\"
-.Dd April 8, 2024
+.Dd August 31, 2026
 .Dt NG_BRIDGE 4
 .Os
 .Sh NAME
@@ -91,12 +91,20 @@ hook of an
 .Xr ng_ether 4
 node to the bridge node.
 .Pp
-Instead of naming a hook
-.Ar linkX
-the hook might be also named
-.Ar uplinkX .
+The prefix
+.Dq uplink
+is special: a hook named
+.Ar uplinkX
+is marked as an uplink hook and behaves differently from
+.Ar linkX .
 The node does not learn MAC addresses on uplink hooks, which keeps
 the internal address table small.
+A host already known on a
+.Ar linkX
+hook is not moved when a packet with that source address
+arrives on an uplink hook; use
+.Dv NGM_BRIDGE_MOVE_HOST
+to place a host on an uplink hook explicitly.
 This way it is desirable to connect the
 .Ar lower
 hook of an
diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c
index 70bc581f8570..7b84ed1f5420 100644
--- a/sys/netgraph/ng_bridge.c
+++ b/sys/netgraph/ng_bridge.c
@@ -858,8 +858,12 @@ ng_bridge_rcvdata(hook_p hook, item_p item)
 		if (__predict_false(host->staleness > 0))
 			host->staleness = 0;
 
-	if ((host == NULL && ctx.incoming->learnMac) ||
-	    (host != NULL && host->link != ctx.incoming)) {
+	/*
+	 * learnMac is 0 on uplink: neither insert a new host nor
+	 * move an existing one from packets received there.
+	 */
+	if (ctx.incoming->learnMac &&
+	    (host == NULL || host->link != ctx.incoming)) {
 		struct ng_mesg *msg;
 		struct ng_bridge_move_host *mh;
 		int error = 0;