diff --git a/pkg/kubelet/network/hairpin/hairpin.go b/pkg/kubelet/network/hairpin/hairpin.go index 14586f61dd4..cf5d2937563 100644 --- a/pkg/kubelet/network/hairpin/hairpin.go +++ b/pkg/kubelet/network/hairpin/hairpin.go @@ -20,6 +20,7 @@ import ( "fmt" "io/ioutil" "net" + "os" "path" "regexp" "strconv" @@ -30,7 +31,8 @@ import ( const ( sysfsNetPath = "/sys/devices/virtual/net" - hairpinModeRelativePath = "brport/hairpin_mode" + brportRelativePath = "brport" + hairpinModeRelativePath = "hairpin_mode" hairpinEnable = "1" ) @@ -95,6 +97,15 @@ func setUpAllInterfaces() error { func setUpInterface(ifName string) error { glog.V(3).Infof("Enabling hairpin on interface %s", ifName) - hairpinModeFile := path.Join(sysfsNetPath, ifName, hairpinModeRelativePath) + ifPath := path.Join(sysfsNetPath, ifName) + if _, err := os.Stat(ifPath); err != nil { + return err + } + brportPath := path.Join(ifPath, brportRelativePath) + if _, err := os.Stat(brportPath); err != nil && os.IsNotExist(err) { + // Device is not on a bridge, so doesn't need hairpin mode + return nil + } + hairpinModeFile := path.Join(brportPath, hairpinModeRelativePath) return ioutil.WriteFile(hairpinModeFile, []byte(hairpinEnable), 0644) } diff --git a/pkg/kubelet/network/hairpin/hairpin_test.go b/pkg/kubelet/network/hairpin/hairpin_test.go index 1cc3ee3ae99..63bc9ef5bad 100644 --- a/pkg/kubelet/network/hairpin/hairpin_test.go +++ b/pkg/kubelet/network/hairpin/hairpin_test.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "net" + "os" "strings" "testing" @@ -84,13 +85,23 @@ func TestFindPairInterfaceOfContainerInterface(t *testing.T) { } } -func TestSetUpInterface(t *testing.T) { +func TestSetUpInterfaceNonExistent(t *testing.T) { err := setUpInterface("non-existent") if err == nil { t.Errorf("unexpected non-error") } - hairpinModeFile := fmt.Sprintf("%s/%s/%s", sysfsNetPath, "non-existent", hairpinModeRelativePath) - if !strings.Contains(fmt.Sprintf("%v", err), hairpinModeFile) { - t.Errorf("should have tried to open %s", hairpinModeFile) + deviceDir := fmt.Sprintf("%s/%s", sysfsNetPath, "non-existent") + if !strings.Contains(fmt.Sprintf("%v", err), deviceDir) { + t.Errorf("should have tried to open %s", deviceDir) + } +} + +func TestSetUpInterfaceNotBridged(t *testing.T) { + err := setUpInterface("lo") + if err != nil { + if os.IsNotExist(err) { + t.Skipf("'lo' device does not exist??? (%v)", err) + } + t.Errorf("unexpected error: %v", err) } }