1
0
mirror of https://github.com/golang/go synced 2024-09-24 05:20:13 -06:00

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
This commit is contained in:
Mikio Hara 2013-08-25 08:44:31 +09:00
parent 9ec0f30a25
commit 9a7947288b
4 changed files with 32 additions and 11 deletions

View File

@ -109,14 +109,14 @@ func testAddrs(t *testing.T, ifat []Addr) {
for _, ifa := range ifat {
switch ifa := ifa.(type) {
case *IPAddr:
if ifa == nil {
t.Errorf("\tunexpected value: %v", ifa)
if ifa == nil || ifa.IP == nil {
t.Errorf("\tunexpected value: %v, %v", ifa, ifa.IP)
} else {
t.Logf("\tinterface address %q", ifa.String())
}
case *IPNet:
if ifa == nil {
t.Errorf("\tunexpected value: %v", ifa)
if ifa == nil || ifa.IP == nil || ifa.Mask == nil {
t.Errorf("\tunexpected value: %v, %v, %v", ifa, ifa.IP, ifa.Mask)
} else {
_, prefixLen := ifa.Mask.Size()
if ifa.IP.To4() != nil && prefixLen != 8*IPv4len || ifa.IP.To16() != nil && ifa.IP.To4() == nil && prefixLen != 8*IPv6len {

View File

@ -13,10 +13,14 @@ import "unsafe"
// Round the length of a raw sockaddr up to align it properly.
func rsaAlignOf(salen int) int {
salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem.
if darwinAMD64 {
// NOTE: It seems like 64-bit Darwin kernel still requires
// 32-bit aligned access to BSD subsystem. Also NetBSD 6
// kernel and beyond require 64-bit aligned access to routing
// facilities.
if darwin64Bit {
salign = 4
} else if netbsd32Bit {
salign = 8
}
if salen == 0 {
return salign
@ -142,6 +146,12 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
return nil
}
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++ {
if m.Header.Addrs&rtaIfaMask&(1<<i) == 0 {
continue
@ -149,21 +159,29 @@ func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
switch i {
case RTAX_IFA:
if rsa.Family == AF_UNSPEC {
rsa.Family = preferredFamily
}
sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
if err != nil {
return nil
}
sas = append(sas, sa)
case RTAX_NETMASK:
if rsa.Family == AF_UNSPEC {
switch rsa.Family {
case AF_UNSPEC:
switch rsa.Len {
case SizeofSockaddrInet4:
rsa.Family = AF_INET
case SizeofSockaddrInet6:
rsa.Family = AF_INET6
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)))
if err != nil {

View File

@ -15,7 +15,7 @@ func cmsgAlignOf(salen int) int {
salign := sizeofPtr
// NOTE: It seems like 64-bit Darwin kernel still requires 32-bit
// aligned access to BSD subsystem.
if darwinAMD64 {
if darwin64Bit {
salign = 4
}
return (salen + salign - 1) & ^(salign - 1)

View File

@ -18,7 +18,10 @@ var (
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 Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)