Skip to content

Commit da2dbdc

Browse files
committed
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
1 parent 14ec281 commit da2dbdc

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

sys/net/if_bridge.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,25 +1329,6 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
13291329
return (EINVAL);
13301330
}
13311331

1332-
/*
1333-
* If member_ifaddrs is disabled, do not allow an interface with
1334-
* assigned IP addresses to be added to a bridge.
1335-
*/
1336-
if (!V_member_ifaddrs) {
1337-
struct ifaddr *ifa;
1338-
1339-
CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) {
1340-
#ifdef INET
1341-
if (ifa->ifa_addr->sa_family == AF_INET)
1342-
return (EINVAL);
1343-
#endif
1344-
#ifdef INET6
1345-
if (ifa->ifa_addr->sa_family == AF_INET6)
1346-
return (EINVAL);
1347-
#endif
1348-
}
1349-
}
1350-
13511332
#ifdef INET6
13521333
/*
13531334
* Two valid inet6 addresses with link-local scope must not be
@@ -1386,6 +1367,26 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
13861367
}
13871368
}
13881369
#endif
1370+
1371+
/*
1372+
* If member_ifaddrs is disabled, do not allow an interface with
1373+
* assigned IP addresses to be added to a bridge.
1374+
*/
1375+
if (!V_member_ifaddrs) {
1376+
struct ifaddr *ifa;
1377+
1378+
CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) {
1379+
#ifdef INET
1380+
if (ifa->ifa_addr->sa_family == AF_INET)
1381+
return (EINVAL);
1382+
#endif
1383+
#ifdef INET6
1384+
if (ifa->ifa_addr->sa_family == AF_INET6)
1385+
return (EINVAL);
1386+
#endif
1387+
}
1388+
}
1389+
13891390
/* Allow the first Ethernet member to define the MTU */
13901391
if (CK_LIST_EMPTY(&sc->sc_iflist))
13911392
sc->sc_ifp->if_mtu = ifs->if_mtu;

0 commit comments

Comments
 (0)