Commit 9a794728 authored by Mikio Hara's avatar Mikio Hara

syscall: update routing socket parser for NetBSD 6 and beyond

NetBSD 6 kernel and beyond require 64-bit aligned access to routing
facilities.

Fixes #6226.

R=golang-dev, bsiegert, bradfitz
CC=golang-dev
https://golang.org/cl/13170043
parent 9ec0f30a
...@@ -109,14 +109,14 @@ func testAddrs(t *testing.T, ifat []Addr) { ...@@ -109,14 +109,14 @@ func testAddrs(t *testing.T, ifat []Addr) {
for _, ifa := range ifat { for _, ifa := range ifat {
switch ifa := ifa.(type) { switch ifa := ifa.(type) {
case *IPAddr: case *IPAddr:
if ifa == nil { if ifa == nil || ifa.IP == nil {
t.Errorf("\tunexpected value: %v", ifa) t.Errorf("\tunexpected value: %v, %v", ifa, ifa.IP)
} else { } else {
t.Logf("\tinterface address %q", ifa.String()) t.Logf("\tinterface address %q", ifa.String())
} }
case *IPNet: case *IPNet:
if ifa == nil { if ifa == nil || ifa.IP == nil || ifa.Mask == nil {
t.Errorf("\tunexpected value: %v", ifa) t.Errorf("\tunexpected value: %v, %v, %v", ifa, ifa.IP, ifa.Mask)
} else { } else {
_, prefixLen := ifa.Mask.Size() _, prefixLen := ifa.Mask.Size()
if ifa.IP.To4() != nil && prefixLen != 8*IPv4len || ifa.IP.To16() != nil && ifa.IP.To4() == nil && prefixLen != 8*IPv6len { if ifa.IP.To4() != nil && prefixLen != 8*IPv4len || ifa.IP.To16() != nil && ifa.IP.To4() == nil && prefixLen != 8*IPv6len {
......
...@@ -13,10 +13,14 @@ import "unsafe" ...@@ -13,10 +13,14 @@ import "unsafe"
// Round the length of a raw sockaddr up to align it properly. // Round the length of a raw sockaddr up to align it properly.
func rsaAlignOf(salen int) int { func rsaAlignOf(salen int) int {
salign := sizeofPtr salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit // NOTE: It seems like 64-bit Darwin kernel still requires
// aligned access to BSD subsystem. // 32-bit aligned access to BSD subsystem. Also NetBSD 6
if darwinAMD64 { // kernel and beyond require 64-bit aligned access to routing
// facilities.
if darwin64Bit {
salign = 4 salign = 4
} else if netbsd32Bit {
salign = 8
} }
if salen == 0 { if salen == 0 {
return salign return salign
...@@ -142,6 +146,12 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) { ...@@ -142,6 +146,12 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
return nil return nil
} }
b := m.Data[:] b := m.Data[:]
// We still see AF_UNSPEC in socket addresses on some
// platforms. To identify each address family correctly, we
// will use the address family of RTAX_NETMASK as a preferred
// one on the 32-bit NetBSD kernel, also use the length of
// RTAX_NETMASK socket address on the FreeBSD kernel.
preferredFamily := uint8(AF_UNSPEC)
for i := uint(0); i < RTAX_MAX; i++ { for i := uint(0); i < RTAX_MAX; i++ {
if m.Header.Addrs&rtaIfaMask&(1<<i) == 0 { if m.Header.Addrs&rtaIfaMask&(1<<i) == 0 {
continue continue
...@@ -149,21 +159,29 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) { ...@@ -149,21 +159,29 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
rsa := (*RawSockaddr)(unsafe.Pointer(&b[0])) rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
switch i { switch i {
case RTAX_IFA: case RTAX_IFA:
if rsa.Family == AF_UNSPEC {
rsa.Family = preferredFamily
}
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa))) sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil { if err != nil {
return nil return nil
} }
sas = append(sas, sa) sas = append(sas, sa)
case RTAX_NETMASK: case RTAX_NETMASK:
if rsa.Family == AF_UNSPEC { switch rsa.Family {
case AF_UNSPEC:
switch rsa.Len { switch rsa.Len {
case SizeofSockaddrInet4: case SizeofSockaddrInet4:
rsa.Family = AF_INET rsa.Family = AF_INET
case SizeofSockaddrInet6: case SizeofSockaddrInet6:
rsa.Family = AF_INET6 rsa.Family = AF_INET6
default: default:
rsa.Family = AF_INET // an old fasion, AF_UNSPEC means AF_INET rsa.Family = AF_INET // an old fashion, AF_UNSPEC means AF_INET
} }
case AF_INET, AF_INET6:
preferredFamily = rsa.Family
default:
return nil
} }
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa))) sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil { if err != nil {
......
...@@ -15,7 +15,7 @@ func cmsgAlignOf(salen int) int { ...@@ -15,7 +15,7 @@ func cmsgAlignOf(salen int) int {
salign := sizeofPtr salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit // NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem. // aligned access to BSD subsystem.
if darwinAMD64 { if darwin64Bit {
salign = 4 salign = 4
} }
return (salen + salign - 1) & ^(salign - 1) return (salen + salign - 1) & ^(salign - 1)
......
...@@ -18,7 +18,10 @@ var ( ...@@ -18,7 +18,10 @@ var (
Stderr = 2 Stderr = 2
) )
const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" const (
darwin64Bit = runtime.GOOS == "darwin" && sizeofPtr == 8
netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
)
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment