From 24d2ffbea1e81c630b3c6f82afe9bd2f3ecfce35 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 21 Oct 2019 00:21:33 +0200 Subject: [PATCH] all: fix tests on dragonfly after ABI changes Detect the ABI version based on kern.osreldate. Only use 32-bit cmsg alignment for versions before the September 2019 ABI changes: http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html Use RTM_VERSION 7 on Dragonfly master (5.8 release). Determine sizeof struct ifa_msghdr at runtime based on the ABI version. Temporarily skip some test relying on the net package which will only be fixed once this CL is re-vendored into std. Updates golang/go#34368 Change-Id: I732fab21d569b303f45dfb6a0bbbb11469511a07 Reviewed-on: https://go-review.googlesource.com/c/net/+/202317 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- internal/socket/sys_dragonfly.go | 27 ++++++++++++++++++++++++++- ipv6/multicastlistener_test.go | 8 ++++++++ route/defs_dragonfly.go | 25 ++++++++++++++++++++++++- route/message.go | 2 +- route/route_classic.go | 2 +- route/sys.go | 3 +++ route/sys_dragonfly.go | 14 +++++++++++++- route/zsys_dragonfly.go | 4 ++-- 8 files changed, 78 insertions(+), 7 deletions(-) diff --git a/internal/socket/sys_dragonfly.go b/internal/socket/sys_dragonfly.go index b17d223bf..ed0448fe9 100644 --- a/internal/socket/sys_dragonfly.go +++ b/internal/socket/sys_dragonfly.go @@ -4,4 +4,29 @@ package socket -func probeProtocolStack() int { return 4 } +import ( + "sync" + "syscall" + "unsafe" +) + +// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h +var ( + osreldateOnce sync.Once + osreldate uint32 +) + +// First __DragonFly_version after September 2019 ABI changes +// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html +const _dragonflyABIChangeVersion = 500705 + +func probeProtocolStack() int { + osreldateOnce.Do(func() { osreldate, _ = syscall.SysctlUint32("kern.osreldate") }) + var p uintptr + if int(unsafe.Sizeof(p)) == 8 && osreldate >= _dragonflyABIChangeVersion { + return int(unsafe.Sizeof(p)) + } + // 64-bit Dragonfly before the September 2019 ABI changes still requires + // 32-bit aligned access to network subsystem. + return 4 +} diff --git a/ipv6/multicastlistener_test.go b/ipv6/multicastlistener_test.go index 270912d75..6d35007c4 100644 --- a/ipv6/multicastlistener_test.go +++ b/ipv6/multicastlistener_test.go @@ -23,6 +23,8 @@ func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) + case "dragonfly": + t.Skipf("skipping on %s until CL 202317 is vendored into std; see golang.org/issue/34368", runtime.GOOS) } if !nettest.SupportsIPv6() { t.Skip("ipv6 is not supported") @@ -63,6 +65,8 @@ func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { switch runtime.GOOS { case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) + case "dragonfly": + t.Skipf("skipping on %s until CL 202317 is vendored into std; see golang.org/issue/34368", runtime.GOOS) } if !nettest.SupportsIPv6() { t.Skip("ipv6 is not supported") @@ -118,6 +122,8 @@ func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) + case "dragonfly": + t.Skipf("skipping on %s until CL 202317 is vendored into std; see golang.org/issue/34368", runtime.GOOS) } if !nettest.SupportsIPv6() { t.Skip("ipv6 is not supported") @@ -174,6 +180,8 @@ func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) { switch runtime.GOOS { case "fuchsia", "hurd", "js", "nacl", "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) + case "dragonfly": + t.Skipf("skipping on %s until CL 202317 is vendored into std; see golang.org/issue/34368", runtime.GOOS) } if !nettest.SupportsIPv6() { t.Skip("ipv6 is not supported") diff --git a/route/defs_dragonfly.go b/route/defs_dragonfly.go index 82657d314..e71dbc29d 100644 --- a/route/defs_dragonfly.go +++ b/route/defs_dragonfly.go @@ -15,6 +15,27 @@ package route #include #include + +struct ifa_msghdr_dfly4 { + u_short ifam_msglen; + u_char ifam_version; + u_char ifam_type; + int ifam_addrs; + int ifam_flags; + u_short ifam_index; + int ifam_metric; +}; + +struct ifa_msghdr_dfly58 { + u_short ifam_msglen; + u_char ifam_version; + u_char ifam_type; + u_short ifam_index; + int ifam_flags; + int ifam_addrs; + int ifam_addrflags; + int ifam_metric; +}; */ import "C" @@ -98,10 +119,12 @@ const ( const ( sizeofIfMsghdrDragonFlyBSD4 = C.sizeof_struct_if_msghdr - sizeofIfaMsghdrDragonFlyBSD4 = C.sizeof_struct_ifa_msghdr + sizeofIfaMsghdrDragonFlyBSD4 = C.sizeof_struct_ifa_msghdr_dfly4 sizeofIfmaMsghdrDragonFlyBSD4 = C.sizeof_struct_ifma_msghdr sizeofIfAnnouncemsghdrDragonFlyBSD4 = C.sizeof_struct_if_announcemsghdr + sizeofIfaMsghdrDragonFlyBSD58 = C.sizeof_struct_ifa_msghdr_dfly58 + sizeofRtMsghdrDragonFlyBSD4 = C.sizeof_struct_rt_msghdr sizeofRtMetricsDragonFlyBSD4 = C.sizeof_struct_rt_metrics diff --git a/route/message.go b/route/message.go index 0fa7e09f4..80c482ae9 100644 --- a/route/message.go +++ b/route/message.go @@ -45,7 +45,7 @@ func ParseRIB(typ RIBType, b []byte) ([]Message, error) { if len(b) < l { return nil, errMessageTooShort } - if b[2] != sysRTM_VERSION { + if b[2] != rtmVersion { b = b[l:] continue } diff --git a/route/route_classic.go b/route/route_classic.go index 02fa68830..a7d386464 100644 --- a/route/route_classic.go +++ b/route/route_classic.go @@ -25,7 +25,7 @@ func (m *RouteMessage) marshal() ([]byte, error) { b := make([]byte, l) nativeEndian.PutUint16(b[:2], uint16(l)) if m.Version == 0 { - b[2] = sysRTM_VERSION + b[2] = rtmVersion } else { b[2] = byte(m.Version) } diff --git a/route/sys.go b/route/sys.go index 13933f9af..a0ab3e9c7 100644 --- a/route/sys.go +++ b/route/sys.go @@ -11,6 +11,7 @@ import "unsafe" var ( nativeEndian binaryByteOrder kernelAlign int + rtmVersion byte wireFormats map[int]*wireFormat ) @@ -22,6 +23,8 @@ func init() { } else { nativeEndian = bigEndian } + // might get overridden in probeRoutingStack + rtmVersion = sysRTM_VERSION kernelAlign, wireFormats = probeRoutingStack() } diff --git a/route/sys_dragonfly.go b/route/sys_dragonfly.go index 0c14bc2b4..a138951f9 100644 --- a/route/sys_dragonfly.go +++ b/route/sys_dragonfly.go @@ -4,7 +4,10 @@ package route -import "unsafe" +import ( + "syscall" + "unsafe" +) func (typ RIBType) parseable() bool { return true } @@ -56,6 +59,15 @@ func probeRoutingStack() (int, map[int]*wireFormat) { ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage ifanm := &wireFormat{extOff: sizeofIfAnnouncemsghdrDragonFlyBSD4, bodyOff: sizeofIfAnnouncemsghdrDragonFlyBSD4} ifanm.parse = ifanm.parseInterfaceAnnounceMessage + + rel, _ := syscall.SysctlUint32("kern.osreldate") + if rel >= 500705 { + // https://github.com/DragonFlyBSD/DragonFlyBSD/commit/43a373152df2d405c9940983e584e6a25e76632d + // but only the size of struct ifa_msghdr actually changed + rtmVersion = 7 + ifam.bodyOff = sizeofIfaMsghdrDragonFlyBSD58 + } + return int(unsafe.Sizeof(p)), map[int]*wireFormat{ sysRTM_ADD: rtm, sysRTM_DELETE: rtm, diff --git a/route/zsys_dragonfly.go b/route/zsys_dragonfly.go index 8ed2d4d55..34f0eaaa4 100644 --- a/route/zsys_dragonfly.go +++ b/route/zsys_dragonfly.go @@ -46,8 +46,6 @@ const ( sysRTM_REDIRECT = 0x6 sysRTM_MISS = 0x7 sysRTM_LOCK = 0x8 - sysRTM_OLDADD = 0x9 - sysRTM_OLDDEL = 0xa sysRTM_RESOLVE = 0xb sysRTM_NEWADDR = 0xc sysRTM_DELADDR = 0xd @@ -89,6 +87,8 @@ const ( sizeofIfmaMsghdrDragonFlyBSD4 = 0x10 sizeofIfAnnouncemsghdrDragonFlyBSD4 = 0x18 + sizeofIfaMsghdrDragonFlyBSD58 = 0x18 + sizeofRtMsghdrDragonFlyBSD4 = 0x98 sizeofRtMetricsDragonFlyBSD4 = 0x70