wgengine/router: refactor udm-pro into broader ubnt support
Fixes #14453 Signed-off-by: Jason Barnett <J@sonBarnett.com>
This commit is contained in:
parent
e3bcb2ec83
commit
17b881538a
@ -9,7 +9,6 @@
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"tailscale.com/types/lazy"
|
"tailscale.com/types/lazy"
|
||||||
"tailscale.com/util/lineiter"
|
"tailscale.com/util/lineiter"
|
||||||
@ -31,7 +30,7 @@
|
|||||||
WDMyCloud = Distro("wdmycloud")
|
WDMyCloud = Distro("wdmycloud")
|
||||||
Unraid = Distro("unraid")
|
Unraid = Distro("unraid")
|
||||||
Alpine = Distro("alpine")
|
Alpine = Distro("alpine")
|
||||||
UDMPro = Distro("udmpro")
|
UBNT = Distro("ubnt") // Ubiquiti Networks
|
||||||
)
|
)
|
||||||
|
|
||||||
var distro lazy.SyncValue[Distro]
|
var distro lazy.SyncValue[Distro]
|
||||||
@ -77,9 +76,12 @@ func linuxDistro() Distro {
|
|||||||
case have("/usr/local/bin/freenas-debug"):
|
case have("/usr/local/bin/freenas-debug"):
|
||||||
// TrueNAS Scale runs on debian
|
// TrueNAS Scale runs on debian
|
||||||
return TrueNAS
|
return TrueNAS
|
||||||
case isUDMPro():
|
case have("/usr/bin/ubnt-device-info"):
|
||||||
// UDM-Pro runs on debian
|
// UBNT runs on Debian-based systems. This MUST be checked before Debian.
|
||||||
return UDMPro
|
//
|
||||||
|
// Currently supported product families:
|
||||||
|
// - UDM (UniFi Dream Machine, UDM-Pro)
|
||||||
|
return UBNT
|
||||||
case have("/etc/debian_version"):
|
case have("/etc/debian_version"):
|
||||||
return Debian
|
return Debian
|
||||||
case have("/etc/arch-release"):
|
case have("/etc/arch-release"):
|
||||||
@ -152,44 +154,3 @@ func DSMVersion() int {
|
|||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUDMPro checks a couple of files known to exist on a UDM-Pro and returns
|
|
||||||
// true if the expected content exists in the files.
|
|
||||||
func isUDMPro() bool {
|
|
||||||
// This is a performance guardrail against trying to load both
|
|
||||||
// /etc/board.info and /sys/firmware/devicetree/base/soc/board-cfg/id when
|
|
||||||
// not running on Debian so we don't make unnecessary calls in situations
|
|
||||||
// where we definitely are NOT on a UDM Pro. In other words, the have() call
|
|
||||||
// is much cheaper than the two os.ReadFile() in fileContainsAnyString().
|
|
||||||
// That said, on Debian systems we will still be making the two
|
|
||||||
// os.ReadFile() in fileContainsAnyString().
|
|
||||||
if !have("/etc/debian_version") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if exists, err := fileContainsAnyString("/etc/board.info", "UDMPRO", "Dream Machine PRO"); err == nil && exists {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if exists, err := fileContainsAnyString("/sys/firmware/devicetree/base/soc/board-cfg/id", "udm pro"); err == nil && exists {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// fileContainsAnyString is used to determine if one or more of the provided
|
|
||||||
// strings exists in a file. This is not efficient for larger files. If you want
|
|
||||||
// to use this function to parse large files, please refactor to use
|
|
||||||
// `io.LimitedReader`.
|
|
||||||
func fileContainsAnyString(filePath string, searchStrings ...string) (bool, error) {
|
|
||||||
data, err := os.ReadFile(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
content := string(data)
|
|
||||||
for _, searchString := range searchStrings {
|
|
||||||
if strings.Contains(content, searchString) {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
@ -1184,7 +1184,7 @@ func mustRouteTable(num int) RouteTable {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// baseIPRules are the policy routing rules that Tailscale uses, when not
|
// baseIPRules are the policy routing rules that Tailscale uses, when not
|
||||||
// running on a UDM-Pro.
|
// running on a UBNT device.
|
||||||
//
|
//
|
||||||
// The priority is the value represented here added to r.ipPolicyPrefBase,
|
// The priority is the value represented here added to r.ipPolicyPrefBase,
|
||||||
// which is usually 5200.
|
// which is usually 5200.
|
||||||
@ -1236,15 +1236,15 @@ func mustRouteTable(num int) RouteTable {
|
|||||||
// usual rules (pref 32766 and 32767, ie. main and default).
|
// usual rules (pref 32766 and 32767, ie. main and default).
|
||||||
}
|
}
|
||||||
|
|
||||||
// udmProIPRules are the policy routing rules that Tailscale uses, when running
|
// ubntIPRules are the policy routing rules that Tailscale uses, when running
|
||||||
// on a UDM-Pro.
|
// on a UBNT device.
|
||||||
//
|
//
|
||||||
// The priority is the value represented here added to
|
// The priority is the value represented here added to
|
||||||
// r.ipPolicyPrefBase, which is usually 5200.
|
// r.ipPolicyPrefBase, which is usually 5200.
|
||||||
//
|
//
|
||||||
// This represents an experiment that will be used to gather more information.
|
// This represents an experiment that will be used to gather more information.
|
||||||
// If this goes well, Tailscale may opt to use this for all of Linux.
|
// If this goes well, Tailscale may opt to use this for all of Linux.
|
||||||
var udmProIPRules = []netlink.Rule{
|
var ubntIPRules = []netlink.Rule{
|
||||||
// non-fwmark packets fall through to the usual rules (pref 32766 and 32767,
|
// non-fwmark packets fall through to the usual rules (pref 32766 and 32767,
|
||||||
// ie. main and default).
|
// ie. main and default).
|
||||||
{
|
{
|
||||||
@ -1256,10 +1256,10 @@ func mustRouteTable(num int) RouteTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ipRules returns the appropriate list of ip rules to be used by Tailscale. See
|
// ipRules returns the appropriate list of ip rules to be used by Tailscale. See
|
||||||
// comments on baseIPRules and udmProIPRules for more details.
|
// comments on baseIPRules and ubntIPRules for more details.
|
||||||
func ipRules() []netlink.Rule {
|
func ipRules() []netlink.Rule {
|
||||||
if getDistroFunc() == distro.UDMPro {
|
if getDistroFunc() == distro.UBNT {
|
||||||
return udmProIPRules
|
return ubntIPRules
|
||||||
}
|
}
|
||||||
return baseIPRules
|
return baseIPRules
|
||||||
}
|
}
|
||||||
|
@ -1233,14 +1233,14 @@ func adjustFwmask(t *testing.T, s string) string {
|
|||||||
return fwmaskAdjustRe.ReplaceAllString(s, "$1")
|
return fwmaskAdjustRe.ReplaceAllString(s, "$1")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIPRulesForUDMPro(t *testing.T) {
|
func TestIPRulesForUBNT(t *testing.T) {
|
||||||
// Override the global getDistroFunc
|
// Override the global getDistroFunc
|
||||||
getDistroFunc = func() distro.Distro {
|
getDistroFunc = func() distro.Distro {
|
||||||
return distro.UDMPro
|
return distro.UBNT
|
||||||
}
|
}
|
||||||
defer func() { getDistroFunc = distro.Get }() // Restore original after the test
|
defer func() { getDistroFunc = distro.Get }() // Restore original after the test
|
||||||
|
|
||||||
expected := udmProIPRules
|
expected := ubntIPRules
|
||||||
actual := ipRules()
|
actual := ipRules()
|
||||||
|
|
||||||
if len(expected) != len(actual) {
|
if len(expected) != len(actual) {
|
||||||
|
Loading…
Reference in New Issue
Block a user