mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
pkg/netutil: get default interface for tc commands
Fix https://github.com/coreos/etcd/issues/6841.
This commit is contained in:
parent
68b04b7067
commit
097cdbd0e4
@ -43,14 +43,19 @@ func RecoverPort(port int) error {
|
||||
|
||||
// SetLatency adds latency in millisecond scale with random variations.
|
||||
func SetLatency(ms, rv int) error {
|
||||
ifce, err := GetDefaultInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rv > ms {
|
||||
rv = 1
|
||||
}
|
||||
cmdStr := fmt.Sprintf("sudo tc qdisc add dev eth0 root netem delay %dms %dms distribution normal", ms, rv)
|
||||
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||
cmdStr := fmt.Sprintf("sudo tc qdisc add dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
|
||||
_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||
if err != nil {
|
||||
// the rule has already been added. Overwrite it.
|
||||
cmdStr = fmt.Sprintf("sudo tc qdisc change dev eth0 root netem delay %dms %dms distribution normal", ms, rv)
|
||||
cmdStr = fmt.Sprintf("sudo tc qdisc change dev %s root netem delay %dms %dms distribution normal", ifce, ms, rv)
|
||||
_, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -61,6 +66,10 @@ func SetLatency(ms, rv int) error {
|
||||
|
||||
// RemoveLatency resets latency configurations.
|
||||
func RemoveLatency() error {
|
||||
_, err := exec.Command("/bin/sh", "-c", "sudo tc qdisc del dev eth0 root netem").Output()
|
||||
ifce, err := GetDefaultInterface()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = exec.Command("/bin/sh", "-c", fmt.Sprintf("sudo tc qdisc del dev %s root netem", ifce)).Output()
|
||||
return err
|
||||
}
|
||||
|
@ -26,3 +26,8 @@ import (
|
||||
func GetDefaultHost() (string, error) {
|
||||
return "", fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
// GetDefaultInterface fetches the device name of default routable interface.
|
||||
func GetDefaultInterface() (string, error) {
|
||||
return "", fmt.Errorf("default host not supported on %s_%s", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
@ -35,33 +35,21 @@ func GetDefaultHost() (string, error) {
|
||||
return "", rerr
|
||||
}
|
||||
|
||||
attrs, aerr := syscall.ParseNetlinkRouteAttr(rmsg)
|
||||
if aerr != nil {
|
||||
return "", aerr
|
||||
host, oif, err := parsePREFSRC(rmsg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
oif := uint32(0)
|
||||
for _, attr := range attrs {
|
||||
if attr.Attr.Type == syscall.RTA_PREFSRC {
|
||||
return net.IP(attr.Value).String(), nil
|
||||
}
|
||||
if attr.Attr.Type == syscall.RTA_OIF {
|
||||
oif = binary.LittleEndian.Uint32(attr.Value)
|
||||
}
|
||||
}
|
||||
|
||||
if oif == 0 {
|
||||
return "", errNoDefaultRoute
|
||||
if host != "" {
|
||||
return host, nil
|
||||
}
|
||||
|
||||
// prefsrc not detected, fall back to getting address from iface
|
||||
|
||||
ifmsg, ierr := getIface(oif)
|
||||
if ierr != nil {
|
||||
return "", ierr
|
||||
}
|
||||
|
||||
attrs, aerr = syscall.ParseNetlinkRouteAttr(ifmsg)
|
||||
attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
|
||||
if aerr != nil {
|
||||
return "", aerr
|
||||
}
|
||||
@ -131,3 +119,60 @@ func getIface(idx uint32) (*syscall.NetlinkMessage, error) {
|
||||
|
||||
return nil, errNoDefaultRoute
|
||||
}
|
||||
|
||||
var errNoDefaultInterface = fmt.Errorf("could not find default interface")
|
||||
|
||||
func GetDefaultInterface() (string, error) {
|
||||
rmsg, rerr := getDefaultRoute()
|
||||
if rerr != nil {
|
||||
return "", rerr
|
||||
}
|
||||
|
||||
_, oif, err := parsePREFSRC(rmsg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ifmsg, ierr := getIface(oif)
|
||||
if ierr != nil {
|
||||
return "", ierr
|
||||
}
|
||||
|
||||
attrs, aerr := syscall.ParseNetlinkRouteAttr(ifmsg)
|
||||
if aerr != nil {
|
||||
return "", aerr
|
||||
}
|
||||
|
||||
for _, attr := range attrs {
|
||||
if attr.Attr.Type == syscall.IFLA_IFNAME {
|
||||
return string(attr.Value[:len(attr.Value)-1]), nil
|
||||
}
|
||||
}
|
||||
return "", errNoDefaultInterface
|
||||
}
|
||||
|
||||
// parsePREFSRC returns preferred source address and output interface index (RTA_OIF).
|
||||
func parsePREFSRC(m *syscall.NetlinkMessage) (host string, oif uint32, err error) {
|
||||
var attrs []syscall.NetlinkRouteAttr
|
||||
attrs, err = syscall.ParseNetlinkRouteAttr(m)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
for _, attr := range attrs {
|
||||
if attr.Attr.Type == syscall.RTA_PREFSRC {
|
||||
host = net.IP(attr.Value).String()
|
||||
}
|
||||
if attr.Attr.Type == syscall.RTA_OIF {
|
||||
oif = binary.LittleEndian.Uint32(attr.Value)
|
||||
}
|
||||
if host != "" && oif != uint32(0) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if oif == 0 {
|
||||
err = errNoDefaultRoute
|
||||
}
|
||||
return
|
||||
}
|
||||
|
27
pkg/netutil/routes_linux_test.go
Normal file
27
pkg/netutil/routes_linux_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// +build linux
|
||||
|
||||
package netutil
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGetDefaultInterface(t *testing.T) {
|
||||
ifc, err := GetDefaultInterface()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("default network interface: %q\n", ifc)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user