[lxc-devel] [lxd/master] Network fixes

stgraber on Github lxc-bot at linuxcontainers.org
Tue Feb 12 21:36:22 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 464 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190212/23a2c6f0/attachment.bin>
-------------- next part --------------
From 2965b9d04e493fe69338aa68ceeed06b864d807b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 12 Feb 2019 16:12:38 -0500
Subject: [PATCH 1/4] lxd/storage: Drop unused function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage_cgo.go | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index dade30c4f7..c1bd2a4142 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -286,9 +286,7 @@ import "C"
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
-	"strings"
 	"unsafe"
 
 	"github.com/pkg/errors"
@@ -354,24 +352,3 @@ func unsetAutoclearOnLoopDev(loopFd int) error {
 
 	return nil
 }
-
-func loopDeviceHasBackingFile(loopDevice string, loopFile string) (*os.File, error) {
-	lidx := strings.LastIndex(loopDevice, "/")
-	if lidx < 0 {
-		return nil, fmt.Errorf("Invalid loop device path: \"%s\"", loopDevice)
-	}
-
-	loopName := loopDevice[(lidx + 1):]
-	backingFile := fmt.Sprintf("/sys/block/%s/loop/backing_file", loopName)
-	contents, err := ioutil.ReadFile(backingFile)
-	if err != nil {
-		return nil, err
-	}
-
-	cleanBackingFile := strings.TrimSpace(string(contents))
-	if cleanBackingFile != loopFile {
-		return nil, fmt.Errorf("loop device has new backing file: \"%s\"", cleanBackingFile)
-	}
-
-	return os.OpenFile(loopDevice, os.O_RDWR, 0660)
-}

From ab0210a8944a46be73f3578db018199d20126e4d Mon Sep 17 00:00:00 2001
From: s3rj1k <evasive.gyron at gmail.com>
Date: Fri, 2 Nov 2018 00:50:30 +0200
Subject: [PATCH 2/4] lxd/network: Rework IP validation functions

Signed-off-by: s3rj1k <evasive.gyron at gmail.com>
---
 lxd/networks_config.go |  6 +++---
 lxd/networks_utils.go  | 28 +++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/lxd/networks_config.go b/lxd/networks_config.go
index bf0f0c5019..e2a31e4e2e 100644
--- a/lxd/networks_config.go
+++ b/lxd/networks_config.go
@@ -47,10 +47,10 @@ var networkConfigKeys = map[string]func(value string) error{
 	"tunnel.TARGET.protocol": func(value string) error {
 		return shared.IsOneOf(value, []string{"gre", "vxlan"})
 	},
-	"tunnel.TARGET.local":     networkValidAddressV4,
-	"tunnel.TARGET.remote":    networkValidAddressV4,
+	"tunnel.TARGET.local":     networkValidAddress,
+	"tunnel.TARGET.remote":    networkValidAddress,
 	"tunnel.TARGET.port":      networkValidPort,
-	"tunnel.TARGET.group":     networkValidAddressV4,
+	"tunnel.TARGET.group":     networkValidAddress,
 	"tunnel.TARGET.id":        shared.IsInt64,
 	"tunnel.TARGET.interface": networkValidName,
 	"tunnel.TARGET.ttl":       shared.IsUint8,
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 480318c252..d433684331 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -552,19 +552,45 @@ func networkValidAddressCIDRV4(value string) error {
 	return nil
 }
 
-func networkValidAddressV4(value string) error {
+func networkValidAddress(value string) error {
 	if value == "" {
 		return nil
 	}
 
 	ip := net.ParseIP(value)
 	if ip == nil {
+		return fmt.Errorf("Not an IP address: %s", value)
+	}
+
+	return nil
+}
+
+func networkValidAddressV4(value string) error {
+	if value == "" {
+		return nil
+	}
+
+	ip := net.ParseIP(value)
+	if ip != nil || ip.To4() == nil {
 		return fmt.Errorf("Not an IPv4 address: %s", value)
 	}
 
 	return nil
 }
 
+func networkValidAddressV6(value string) error {
+	if value == "" {
+		return nil
+	}
+
+	ip := net.ParseIP(value)
+	if ip == nil || ip.To4() != nil {
+		return fmt.Errorf("Not an IPv6 address: %s", value)
+	}
+
+	return nil
+}
+
 func networkValidNetworkV4(value string) error {
 	if value == "" {
 		return nil

From 7e27f4f482c7840a14c742fda4d73c0a44e45cf6 Mon Sep 17 00:00:00 2001
From: s3rj1k <evasive.gyron at gmail.com>
Date: Fri, 2 Nov 2018 00:56:41 +0200
Subject: [PATCH 3/4] lxd/network: Reword sysctl network functions

Signed-off-by: s3rj1k <evasive.gyron at gmail.com>
---
 lxd/container_lxc.go  |  6 +++---
 lxd/networks.go       | 12 ++++++------
 lxd/networks_utils.go | 14 +++++++++++---
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index d4bc9fd5d2..e06d355be6 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -2352,7 +2352,7 @@ func (c *containerLXC) startCommon() (string, error) {
 					}
 
 					// Attempt to disable IPv6 on the host side interface
-					networkSysctl(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", device), "1")
+					networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", device), "1")
 				}
 			}
 		}
@@ -7453,7 +7453,7 @@ func (c *containerLXC) createNetworkDevice(name string, m types.Device) (string,
 			}
 
 			// Attempt to disable IPv6 on the host side interface
-			networkSysctl(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", n1), "1")
+			networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", n1), "1")
 		}
 
 		dev = n2
@@ -7472,7 +7472,7 @@ func (c *containerLXC) createNetworkDevice(name string, m types.Device) (string,
 				}
 
 				// Attempt to disable IPv6 on the host side interface
-				networkSysctl(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", device), "1")
+				networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", device), "1")
 			}
 		}
 
diff --git a/lxd/networks.go b/lxd/networks.go
index 7bcbeb1e29..5fd8813dea 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -984,12 +984,12 @@ func (n *network) Start() error {
 
 	// IPv6 bridge configuration
 	if !shared.StringInSlice(n.config["ipv6.address"], []string{"", "none"}) {
-		err := networkSysctl(fmt.Sprintf("ipv6/conf/%s/autoconf", n.name), "0")
+		err := networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/autoconf", n.name), "0")
 		if err != nil {
 			return err
 		}
 
-		err = networkSysctl(fmt.Sprintf("ipv6/conf/%s/accept_dad", n.name), "0")
+		err = networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/accept_dad", n.name), "0")
 		if err != nil {
 			return err
 		}
@@ -1143,7 +1143,7 @@ func (n *network) Start() error {
 
 		// Allow forwarding
 		if n.config["bridge.mode"] == "fan" || n.config["ipv4.routing"] == "" || shared.IsTrue(n.config["ipv4.routing"]) {
-			err = networkSysctl("ipv4/ip_forward", "1")
+			err = networkSysctlSet("ipv4/ip_forward", "1")
 			if err != nil {
 				return err
 			}
@@ -1282,7 +1282,7 @@ func (n *network) Start() error {
 	// Configure IPv6
 	if !shared.StringInSlice(n.config["ipv6.address"], []string{"", "none"}) {
 		// Enable IPv6 for the subnet
-		err := networkSysctl(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", n.name), "0")
+		err := networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/disable_ipv6", n.name), "0")
 		if err != nil {
 			return err
 		}
@@ -1354,7 +1354,7 @@ func (n *network) Start() error {
 					continue
 				}
 
-				err = networkSysctl(fmt.Sprintf("ipv6/conf/%s/accept_ra", entry.Name()), "2")
+				err = networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/accept_ra", entry.Name()), "2")
 				if err != nil && !os.IsNotExist(err) {
 					return err
 				}
@@ -1362,7 +1362,7 @@ func (n *network) Start() error {
 
 			// Then set forwarding for all of them
 			for _, entry := range entries {
-				err = networkSysctl(fmt.Sprintf("ipv6/conf/%s/forwarding", entry.Name()), "1")
+				err = networkSysctlSet(fmt.Sprintf("ipv6/conf/%s/forwarding", entry.Name()), "1")
 				if err != nil && !os.IsNotExist(err) {
 					return err
 				}
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index d433684331..2eb3fb1037 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -981,13 +981,21 @@ func networkUpdateStatic(s *state.State, networkName string) error {
 	return nil
 }
 
-func networkSysctl(path string, value string) error {
+func networkSysctlGet(path string) (string, error) {
+	// Read the current content
 	content, err := ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/%s", path))
 	if err != nil {
-		return err
+		return "", err
 	}
 
-	if strings.TrimSpace(string(content)) == value {
+	return string(content), nil
+}
+
+func networkSysctlSet(path string, value string) error {
+	// Get current value
+	current, err := networkSysctlGet(path)
+	if err == nil && current == value {
+		// Nothing to update
 		return nil
 	}
 

From 54cf00413a567f2cf17405db520cbc02b886ffd8 Mon Sep 17 00:00:00 2001
From: s3rj1k <evasive.gyron at gmail.com>
Date: Fri, 2 Nov 2018 01:21:50 +0200
Subject: [PATCH 4/4] lxd/containers: Skip interface removal if missing

Signed-off-by: s3rj1k <evasive.gyron at gmail.com>
---
 lxd/container_lxc.go | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index e06d355be6..5e8a6089c5 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -7966,10 +7966,18 @@ func (c *containerLXC) removeNetworkDevice(name string, m types.Device) error {
 	}
 	defer cc.Release()
 
-	// Remove the interface from the container
-	err = cc.DetachInterfaceRename(m["name"], hostName)
+	// Check if interface exists inside container namespace
+	ifaces, err := cc.Interfaces()
 	if err != nil {
-		return fmt.Errorf("Failed to detach interface: %s: %s", m["name"], err)
+		return fmt.Errorf("Failed to list network interfaces: %v", err)
+	}
+
+	// Remove the interface from the container if it exists
+	if shared.StringInSlice(m["name"], ifaces) {
+		err = cc.DetachInterfaceRename(m["name"], hostName)
+		if err != nil {
+			return fmt.Errorf("Failed to detach interface: %s: %v", m["name"], err)
+		}
 	}
 
 	// If a veth, destroy it


More information about the lxc-devel mailing list