|
@@ -24,6 +24,10 @@ import (
|
|
|
|
|
|
const defaultPrefix = "/var/run/docker"
|
|
|
|
|
|
+func init() {
|
|
|
+ reexec.Register("set-ipv6", reexecSetIPv6)
|
|
|
+}
|
|
|
+
|
|
|
var (
|
|
|
once sync.Once
|
|
|
garbagePathMap = make(map[string]bool)
|
|
@@ -47,6 +51,7 @@ type networkNamespace struct {
|
|
|
nextIfIndex int
|
|
|
isDefault bool
|
|
|
nlHandle *netlink.Handle
|
|
|
+ loV6Enabled bool
|
|
|
sync.Mutex
|
|
|
}
|
|
|
|
|
@@ -216,6 +221,12 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
|
|
|
logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
|
|
|
}
|
|
|
|
|
|
+ // As starting point, disable IPv6 on all interfaces
|
|
|
+ err = setIPv6(n.path, "all", false)
|
|
|
+ if err != nil {
|
|
|
+ logrus.Warnf("Failed to disable IPv6 on all interfaces on network namespace %q: %v", n.path, err)
|
|
|
+ }
|
|
|
+
|
|
|
if err = n.loopbackUp(); err != nil {
|
|
|
n.nlHandle.Delete()
|
|
|
return nil, err
|
|
@@ -263,6 +274,12 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
|
|
|
logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
|
|
|
}
|
|
|
|
|
|
+ // As starting point, disable IPv6 on all interfaces
|
|
|
+ err = setIPv6(n.path, "all", false)
|
|
|
+ if err != nil {
|
|
|
+ logrus.Warnf("Failed to disable IPv6 on all interfaces on network namespace %q: %v", n.path, err)
|
|
|
+ }
|
|
|
+
|
|
|
if err = n.loopbackUp(); err != nil {
|
|
|
n.nlHandle.Delete()
|
|
|
return nil, err
|
|
@@ -508,3 +525,84 @@ func (n *networkNamespace) Restore(ifsopt map[string][]IfaceOption, routes []*ty
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
+
|
|
|
+// Checks whether IPv6 needs to be enabled/disabled on the loopback interface
|
|
|
+func (n *networkNamespace) checkLoV6() {
|
|
|
+ var (
|
|
|
+ enable = false
|
|
|
+ action = "disable"
|
|
|
+ )
|
|
|
+
|
|
|
+ n.Lock()
|
|
|
+ for _, iface := range n.iFaces {
|
|
|
+ if iface.AddressIPv6() != nil {
|
|
|
+ enable = true
|
|
|
+ action = "enable"
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ n.Unlock()
|
|
|
+
|
|
|
+ if n.loV6Enabled == enable {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := setIPv6(n.path, "lo", enable); err != nil {
|
|
|
+ logrus.Warnf("Failed to %s IPv6 on loopback interface on network namespace %q: %v", action, n.path, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ n.loV6Enabled = enable
|
|
|
+}
|
|
|
+
|
|
|
+func reexecSetIPv6() {
|
|
|
+ runtime.LockOSThread()
|
|
|
+ defer runtime.UnlockOSThread()
|
|
|
+
|
|
|
+ if len(os.Args) < 3 {
|
|
|
+ logrus.Errorf("invalid number of arguments for %s", os.Args[0])
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ ns, err := netns.GetFromPath(os.Args[1])
|
|
|
+ if err != nil {
|
|
|
+ logrus.Errorf("failed get network namespace %q: %v", os.Args[1], err)
|
|
|
+ os.Exit(2)
|
|
|
+ }
|
|
|
+ defer ns.Close()
|
|
|
+
|
|
|
+ if err = netns.Set(ns); err != nil {
|
|
|
+ logrus.Errorf("setting into container netns %q failed: %v", os.Args[1], err)
|
|
|
+ os.Exit(3)
|
|
|
+ }
|
|
|
+
|
|
|
+ var (
|
|
|
+ action = "disable"
|
|
|
+ value = byte('1')
|
|
|
+ path = fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", os.Args[2])
|
|
|
+ )
|
|
|
+
|
|
|
+ if os.Args[3] == "true" {
|
|
|
+ action = "enable"
|
|
|
+ value = byte('0')
|
|
|
+ }
|
|
|
+
|
|
|
+ if err = ioutil.WriteFile(path, []byte{value, '\n'}, 0644); err != nil {
|
|
|
+ logrus.Errorf("failed to %s IPv6 forwarding for container's interface %s: %v", action, os.Args[2], err)
|
|
|
+ os.Exit(4)
|
|
|
+ }
|
|
|
+
|
|
|
+ os.Exit(0)
|
|
|
+}
|
|
|
+
|
|
|
+func setIPv6(path, iface string, enable bool) error {
|
|
|
+ cmd := &exec.Cmd{
|
|
|
+ Path: reexec.Self(),
|
|
|
+ Args: append([]string{"set-ipv6"}, path, iface, strconv.FormatBool(enable)),
|
|
|
+ Stdout: os.Stdout,
|
|
|
+ Stderr: os.Stderr,
|
|
|
+ }
|
|
|
+ if err := cmd.Run(); err != nil {
|
|
|
+ return fmt.Errorf("reexec to set IPv6 failed: %v", err)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|