Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jun 2025 09:22:23 GMT
From:      Lexi Winter <ivy@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 59f18f852c7e - stable/14 - bridge: check allow_llz_overlap before member_ifaddrs
Message-ID:  <202506010922.5519MNVE049181@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by ivy:

URL: https://cgit.FreeBSD.org/src/commit/?id=59f18f852c7e665e609341f87c862e83966eec67

commit 59f18f852c7e665e609341f87c862e83966eec67
Author:     Lexi Winter <ivy@FreeBSD.org>
AuthorDate: 2025-05-23 18:08:14 +0000
Commit:     Lexi Winter <ivy@FreeBSD.org>
CommitDate: 2025-06-01 09:14:52 +0000

    bridge: check allow_llz_overlap before member_ifaddrs
    
    When adding a new interface to a bridge and allow_llz_overlap=0, which
    is the default value, if_bridge checks if the interface has IPv6 link
    local addresses assigned, and if it does, it calls in6_ifdetach() to
    remove all IPv6 addresses from the interface.
    
    This means it was possible to do this:
    
            % ifconfig bridge1 create inet6 -ifdisabled auto_linklocal up
            % ifconfig epair20 create inet6 -ifdisabled auto_linklocal up
            % ifconfig bridge1 addm epair20a
    
    ... with the result that the link-local address on epair20a would be
    removed, then the interface would be added to the bridge.
    
    If member_ifaddrs=0, which is also the default value, this no longer
    works:
    
            % ifconfig bridge1 addm epair20a
            ifconfig: BRDGADD epair20a: Invalid argument
    
    This is because the member_ifaddrs check runs before allow_llz_overlap
    does its thing, and returns EINVAL since the new interface has IP
    addresses on it.
    
    To restore the previous behaviour, reverse the order of these two
    checks, so the IPv6 addresses are removed before we check whether
    the interface has IPv6 addresses.
    
    MFC after:      1 week
    Reviewed by:    kevans, kp
    Approved by:    kevans (mentor)
    Differential Revision:  https://reviews.freebsd.org/D50477
    
    (cherry picked from commit da2dbdc297c948d5923812e3d3b777b790d3bf43)
---
 sys/net/if_bridge.c | 39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index b4e4c5fb2f4c..7246d5a8e7c3 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1289,25 +1289,6 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 		return (EINVAL);
 	}
 
-	/*
-	 * If member_ifaddrs is disabled, do not allow an interface with
-	 * assigned IP addresses to be added to a bridge.
-	 */
-	if (!V_member_ifaddrs) {
-		struct ifaddr *ifa;
-
-		CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) {
-#ifdef INET
-			if (ifa->ifa_addr->sa_family == AF_INET)
-				return (EINVAL);
-#endif
-#ifdef INET6
-			if (ifa->ifa_addr->sa_family == AF_INET6)
-				return (EINVAL);
-#endif
-		}
-	}
-
 #ifdef INET6
 	/*
 	 * Two valid inet6 addresses with link-local scope must not be
@@ -1346,6 +1327,26 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
 		}
 	}
 #endif
+
+	/*
+	 * If member_ifaddrs is disabled, do not allow an interface with
+	 * assigned IP addresses to be added to a bridge.
+	 */
+	if (!V_member_ifaddrs) {
+		struct ifaddr *ifa;
+
+		CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) {
+#ifdef INET
+			if (ifa->ifa_addr->sa_family == AF_INET)
+				return (EINVAL);
+#endif
+#ifdef INET6
+			if (ifa->ifa_addr->sa_family == AF_INET6)
+				return (EINVAL);
+#endif
+		}
+	}
+
 	/* Allow the first Ethernet member to define the MTU */
 	if (CK_LIST_EMPTY(&sc->sc_iflist))
 		sc->sc_ifp->if_mtu = ifs->if_mtu;



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