[release-branch.go1.11] route: don't run NET_RT_IFLIST vs. NET_RT_IFLISTL test in 386 emulation (again)

We are no longer able to use the kernel bug for detecting the execution
of 386 emulation on 11.2-RELEASE or above kernels. This change uses a
variable that holds the execution mode detected in init instead.

Updates golang/go#31221

Change-Id: Ib6afdbc40ae1feb8caf040c64c4b01971efc6325
Reviewed-on: https://go-review.googlesource.com/c/139917
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 146acd28ed5894421fb5aac80ca93bc1b1f46f87)
Reviewed-on: https://go-review.googlesource.com/c/net/+/170618
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/route/message_freebsd_test.go b/route/message_freebsd_test.go
index db4b567..c6d8a5f 100644
--- a/route/message_freebsd_test.go
+++ b/route/message_freebsd_test.go
@@ -4,10 +4,7 @@
 
 package route
 
-import (
-	"testing"
-	"unsafe"
-)
+import "testing"
 
 func TestFetchAndParseRIBOnFreeBSD(t *testing.T) {
 	for _, typ := range []RIBType{sysNET_RT_IFMALIST} {
@@ -40,8 +37,7 @@
 	if _, err := FetchRIB(sysAF_UNSPEC, sysNET_RT_IFLISTL, 0); err != nil {
 		t.Skip("NET_RT_IFLISTL not supported")
 	}
-	var p uintptr
-	if kernelAlign != int(unsafe.Sizeof(p)) {
+	if compatFreeBSD32 {
 		t.Skip("NET_RT_IFLIST vs. NET_RT_IFLISTL doesn't work for 386 emulation on amd64")
 	}
 
diff --git a/route/sys_freebsd.go b/route/sys_freebsd.go
index a1a0d79..fe91be1 100644
--- a/route/sys_freebsd.go
+++ b/route/sys_freebsd.go
@@ -54,6 +54,8 @@
 	}
 }
 
+var compatFreeBSD32 bool // 386 emulation on amd64
+
 func probeRoutingStack() (int, map[int]*wireFormat) {
 	var p uintptr
 	wordSize := int(unsafe.Sizeof(p))
@@ -83,8 +85,11 @@
 			break
 		}
 	}
+	if align != wordSize {
+		compatFreeBSD32 = true // 386 emulation on amd64
+	}
 	var rtm, ifm, ifam, ifmam, ifanm *wireFormat
-	if align != wordSize { // 386 emulation on amd64
+	if compatFreeBSD32 {
 		rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10Emu - sizeofRtMetricsFreeBSD10Emu, bodyOff: sizeofRtMsghdrFreeBSD10Emu}
 		ifm = &wireFormat{extOff: 16}
 		ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10Emu, bodyOff: sizeofIfaMsghdrFreeBSD10Emu}
@@ -100,31 +105,31 @@
 	rel, _ := syscall.SysctlUint32("kern.osreldate")
 	switch {
 	case rel < 800000:
-		if align != wordSize { // 386 emulation on amd64
+		if compatFreeBSD32 {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD7Emu
 		} else {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD7
 		}
 	case 800000 <= rel && rel < 900000:
-		if align != wordSize { // 386 emulation on amd64
+		if compatFreeBSD32 {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD8Emu
 		} else {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD8
 		}
 	case 900000 <= rel && rel < 1000000:
-		if align != wordSize { // 386 emulation on amd64
+		if compatFreeBSD32 {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD9Emu
 		} else {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD9
 		}
 	case 1000000 <= rel && rel < 1100000:
-		if align != wordSize { // 386 emulation on amd64
+		if compatFreeBSD32 {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD10Emu
 		} else {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD10
 		}
 	default:
-		if align != wordSize { // 386 emulation on amd64
+		if compatFreeBSD32 {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD11Emu
 		} else {
 			ifm.bodyOff = sizeofIfMsghdrFreeBSD11