From e446c2c2c712e00b041f8e8d795666b3fc9060ea Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 20 Jan 2017 01:42:37 -0800 Subject: [PATCH 1/2] pkg/cpuutil: add cpuutil A package for unsafe cpu-ish things. --- pkg/cpuutil/doc.go | 16 ++++++++++++++++ pkg/cpuutil/endian.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 pkg/cpuutil/doc.go create mode 100644 pkg/cpuutil/endian.go diff --git a/pkg/cpuutil/doc.go b/pkg/cpuutil/doc.go new file mode 100644 index 00000000000..0323b2d34c6 --- /dev/null +++ b/pkg/cpuutil/doc.go @@ -0,0 +1,16 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package cpuutil provides facilities for detecting cpu-specific features. +package cpuutil diff --git a/pkg/cpuutil/endian.go b/pkg/cpuutil/endian.go new file mode 100644 index 00000000000..6ab898d4b59 --- /dev/null +++ b/pkg/cpuutil/endian.go @@ -0,0 +1,36 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cpuutil + +import ( + "encoding/binary" + "unsafe" +) + +const intWidth int = int(unsafe.Sizeof(0)) + +var byteOrder binary.ByteOrder + +// ByteOrder returns the byte order for the CPU's native endianness. +func ByteOrder() binary.ByteOrder { return byteOrder } + +func init() { + var i int = 0x1 + if v := (*[intWidth]byte)(unsafe.Pointer(&i)); v[0] == 0 { + byteOrder = binary.BigEndian + } else { + byteOrder = binary.LittleEndian + } +} From 1ada4f939fb8ffe35bb157efaf981637799c5cc4 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 20 Jan 2017 01:44:18 -0800 Subject: [PATCH 2/2] pkg/netutil: use native byte ordering for route information Fixes #7199 --- pkg/netutil/routes.go | 2 +- pkg/netutil/routes_linux.go | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/netutil/routes.go b/pkg/netutil/routes.go index d6979c13038..406ade632e5 100644 --- a/pkg/netutil/routes.go +++ b/pkg/netutil/routes.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !linux !386,!amd64 +// +build !linux package netutil diff --git a/pkg/netutil/routes_linux.go b/pkg/netutil/routes_linux.go index f8718ae6a9d..0f2769f1720 100644 --- a/pkg/netutil/routes_linux.go +++ b/pkg/netutil/routes_linux.go @@ -13,9 +13,6 @@ // limitations under the License. // +build linux -// +build 386 amd64 - -// TODO support native endian but without using "unsafe" package netutil @@ -25,6 +22,8 @@ import ( "fmt" "net" "syscall" + + "github.com/coreos/etcd/pkg/cpuutil" ) var errNoDefaultRoute = fmt.Errorf("could not find default route") @@ -80,7 +79,7 @@ func getDefaultRoute() (*syscall.NetlinkMessage, error) { continue } buf := bytes.NewBuffer(m.Data[:syscall.SizeofRtMsg]) - if rerr := binary.Read(buf, binary.LittleEndian, &rtmsg); rerr != nil { + if rerr := binary.Read(buf, cpuutil.ByteOrder(), &rtmsg); rerr != nil { continue } if rtmsg.Dst_len == 0 { @@ -109,7 +108,7 @@ func getIface(idx uint32) (*syscall.NetlinkMessage, error) { continue } buf := bytes.NewBuffer(m.Data[:syscall.SizeofIfAddrmsg]) - if rerr := binary.Read(buf, binary.LittleEndian, &ifaddrmsg); rerr != nil { + if rerr := binary.Read(buf, cpuutil.ByteOrder(), &ifaddrmsg); rerr != nil { continue } if ifaddrmsg.Index == idx { @@ -164,7 +163,7 @@ func parsePREFSRC(m *syscall.NetlinkMessage) (host string, oif uint32, err error host = net.IP(attr.Value).String() } if attr.Attr.Type == syscall.RTA_OIF { - oif = binary.LittleEndian.Uint32(attr.Value) + oif = cpuutil.ByteOrder().Uint32(attr.Value) } if host != "" && oif != uint32(0) { break