From 08ec2995baee8dfe8b5698bc518bcc1d9507d825 Mon Sep 17 00:00:00 2001 From: Ralf Nyren Date: Tue, 30 Jan 2018 15:12:24 +0100 Subject: [PATCH] Explicitly enable IPv6 sysctl If CNI is about to configure an IPv6 address, make sure IPv6 is not disabled through the "disable_ipv6" sysctl setting. This is a workaround for Docker 17.06 and later which sets disable_ipv6=1 for all interfaces even if ipv6 is enabled in Docker. --- pkg/ipam/ipam_linux.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pkg/ipam/ipam_linux.go b/pkg/ipam/ipam_linux.go index 1fe89d8bb..e14197448 100644 --- a/pkg/ipam/ipam_linux.go +++ b/pkg/ipam/ipam_linux.go @@ -21,10 +21,15 @@ import ( "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ip" + "github.com/containernetworking/plugins/pkg/utils/sysctl" "github.com/vishvananda/netlink" ) +const ( + DisableIPv6SysctlTemplate = "net.ipv6.conf.%s.disable_ipv6" +) + // ConfigureIface takes the result of IPAM plugin and // applies to the ifName interface func ConfigureIface(ifName string, res *current.Result) error { @@ -42,6 +47,7 @@ func ConfigureIface(ifName string, res *current.Result) error { } var v4gw, v6gw net.IP + var has_enabled_ipv6 bool = false for _, ipc := range res.IPs { if ipc.Interface == nil { continue @@ -52,6 +58,30 @@ func ConfigureIface(ifName string, res *current.Result) error { return fmt.Errorf("failed to add IP addr %v to %q: invalid interface index", ipc, ifName) } + // Make sure sysctl "disable_ipv6" is 0 if we are about to add + // an IPv6 address to the interface + if !has_enabled_ipv6 && ipc.Version == "6" { + // Enabled IPv6 for loopback "lo" and the interface + // being configured + for _, iface := range [2]string{"lo", ifName} { + ipv6SysctlValueName := fmt.Sprintf(DisableIPv6SysctlTemplate, iface) + + // Read current sysctl value + value, err := sysctl.Sysctl(ipv6SysctlValueName) + if err != nil || value == "0" { + // FIXME: log warning if unable to read sysctl value + continue + } + + // Write sysctl to enable IPv6 + _, err = sysctl.Sysctl(ipv6SysctlValueName, "0") + if err != nil { + return fmt.Errorf("failed to enable IPv6 for interface %q (%s=%s): %v", iface, ipv6SysctlValueName, value, err) + } + } + has_enabled_ipv6 = true + } + addr := &netlink.Addr{IPNet: &ipc.Address, Label: ""} if err = netlink.AddrAdd(link, addr); err != nil { return fmt.Errorf("failed to add IP addr %v to %q: %v", ipc, ifName, err)