[lxc-devel] [lxd/master] NIC Routed: Improves VLAN validation of sysctl settings

tomponline on Github lxc-bot at linuxcontainers.org
Wed Apr 8 14:45:49 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200408/a47243f9/attachment.bin>
-------------- next part --------------
From 9c6e286200f9b585b05d9b48d52769f3216e78d2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 8 Apr 2020 15:43:40 +0100
Subject: [PATCH 1/2] lxd/device/nic/routed: Improves validation of sysctl
 settings when using vlan option

Previously device specific sysctl settings were being validated on parent of vlan not the vlan interface (if it existed).

If it doesn't exist yet, we don't fail validation, as we will create the interface and set the required sysctls later.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/device/nic_routed.go | 70 +++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/lxd/device/nic_routed.go b/lxd/device/nic_routed.go
index 2319ba06a2..c0a4854869 100644
--- a/lxd/device/nic_routed.go
+++ b/lxd/device/nic_routed.go
@@ -76,6 +76,11 @@ func (d *nicRouted) validateEnvironment() error {
 		return fmt.Errorf("Requires name property to start")
 	}
 
+	extensions := d.state.OS.LXCFeatures
+	if !extensions["network_veth_router"] || !extensions["network_l2proxy"] {
+		return fmt.Errorf("Requires liblxc has following API extensions: network_veth_router, network_l2proxy")
+	}
+
 	if d.config["parent"] != "" && !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", d.config["parent"])) {
 		return fmt.Errorf("Parent device '%s' doesn't exist", d.config["parent"])
 	}
@@ -84,24 +89,7 @@ func (d *nicRouted) validateEnvironment() error {
 		return fmt.Errorf("The vlan setting can only be used when combined with a parent interface")
 	}
 
-	extensions := d.state.OS.LXCFeatures
-	if !extensions["network_veth_router"] || !extensions["network_l2proxy"] {
-		return fmt.Errorf("Requires liblxc has following API extensions: network_veth_router, network_l2proxy")
-	}
-
-	// Check necessary sysctls are configured for use with l2proxy parent for routed mode.
-	if d.config["parent"] != "" && d.config["ipv4.address"] != "" {
-		ipv4FwdPath := fmt.Sprintf("net/ipv4/conf/%s/forwarding", d.config["parent"])
-		sysctlVal, err := util.SysctlGet(ipv4FwdPath)
-		if err != nil || sysctlVal != "1\n" {
-			return fmt.Errorf("Error reading net sysctl %s: %v", ipv4FwdPath, err)
-		}
-		if sysctlVal != "1\n" {
-			return fmt.Errorf("Routed mode requires sysctl net.ipv4.conf.%s.forwarding=1", d.config["parent"])
-		}
-	}
-
-	// Check necessary sysctls are configured for use with l2proxy parent for routed mode.
+	// Check necessary "all" sysctls are configured for use with l2proxy parent for routed mode.
 	if d.config["parent"] != "" && d.config["ipv6.address"] != "" {
 		// net.ipv6.conf.all.forwarding=1 is required to enable general packet forwarding for IPv6.
 		ipv6FwdPath := fmt.Sprintf("net/ipv6/conf/%s/forwarding", "all")
@@ -113,15 +101,6 @@ func (d *nicRouted) validateEnvironment() error {
 			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.forwarding=1", "all")
 		}
 
-		ipv6FwdPath = fmt.Sprintf("net/ipv6/conf/%s/forwarding", d.config["parent"])
-		sysctlVal, err = util.SysctlGet(ipv6FwdPath)
-		if err != nil {
-			return fmt.Errorf("Error reading net sysctl %s: %v", ipv6FwdPath, err)
-		}
-		if sysctlVal != "1\n" {
-			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.forwarding=1", d.config["parent"])
-		}
-
 		// net.ipv6.conf.all.proxy_ndp=1 is needed otherwise unicast neighbour solicitations are rejected.
 		// This causes periodic latency spikes every 15-20s as the neighbour has to resort to using
 		// multicast NDP resolution and expires the previous neighbour entry.
@@ -133,14 +112,47 @@ func (d *nicRouted) validateEnvironment() error {
 		if sysctlVal != "1\n" {
 			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.proxy_ndp=1", "all")
 		}
+	}
+
+	// Generate effective parent name, including the VLAN part if option used.
+	effectiveParentName := network.GetHostDevice(d.config["parent"], d.config["vlan"])
+
+	// If the effective parent doesn't exist and the vlan option is specified, it means we are going to create
+	// the VLAN parent at start, and we will configure the needed sysctls so don't need to check them yet.
+	if d.config["vlan"] != "" && !shared.PathExists(fmt.Sprintf("/sys/class/net/%s", effectiveParentName)) {
+		return nil
+	}
+
+	// Check necessary sysctls are configured for use with l2proxy parent for routed mode.
+	if effectiveParentName != "" && d.config["ipv4.address"] != "" {
+		ipv4FwdPath := fmt.Sprintf("net/ipv4/conf/%s/forwarding", effectiveParentName)
+		sysctlVal, err := util.SysctlGet(ipv4FwdPath)
+		if err != nil || sysctlVal != "1\n" {
+			return fmt.Errorf("Error reading net sysctl %s: %v", ipv4FwdPath, err)
+		}
+		if sysctlVal != "1\n" {
+			return fmt.Errorf("Routed mode requires sysctl net.ipv4.conf.%s.forwarding=1", effectiveParentName)
+		}
+	}
+
+	// Check necessary devic specific sysctls are configured for use with l2proxy parent for routed mode.
+	if effectiveParentName != "" && d.config["ipv6.address"] != "" {
+		ipv6FwdPath := fmt.Sprintf("net/ipv6/conf/%s/forwarding", effectiveParentName)
+		sysctlVal, err := util.SysctlGet(ipv6FwdPath)
+		if err != nil {
+			return fmt.Errorf("Error reading net sysctl %s: %v", ipv6FwdPath, err)
+		}
+		if sysctlVal != "1\n" {
+			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.forwarding=1", effectiveParentName)
+		}
 
-		ipv6ProxyNdpPath = fmt.Sprintf("net/ipv6/conf/%s/proxy_ndp", d.config["parent"])
+		ipv6ProxyNdpPath := fmt.Sprintf("net/ipv6/conf/%s/proxy_ndp", effectiveParentName)
 		sysctlVal, err = util.SysctlGet(ipv6ProxyNdpPath)
 		if err != nil {
 			return fmt.Errorf("Error reading net sysctl %s: %v", ipv6ProxyNdpPath, err)
 		}
 		if sysctlVal != "1\n" {
-			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.proxy_ndp=1", d.config["parent"])
+			return fmt.Errorf("Routed mode requires sysctl net.ipv6.conf.%s.proxy_ndp=1", effectiveParentName)
 		}
 	}
 

From 940047fef681b4966ecf3be72771ab549e7dcff1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 8 Apr 2020 15:44:49 +0100
Subject: [PATCH 2/2] lxd/device/nic/routed: Corrects misleading error message
 when setting sysctls

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/device/nic_routed.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/device/nic_routed.go b/lxd/device/nic_routed.go
index c0a4854869..66372f1233 100644
--- a/lxd/device/nic_routed.go
+++ b/lxd/device/nic_routed.go
@@ -274,13 +274,13 @@ func (d *nicRouted) setupParentSysctls(parentName string) error {
 		ipv6FwdPath := fmt.Sprintf("net/ipv6/conf/%s/forwarding", parentName)
 		err := util.SysctlSet(ipv6FwdPath, "1")
 		if err != nil {
-			return fmt.Errorf("Error reading net sysctl %s: %v", ipv6FwdPath, err)
+			return fmt.Errorf("Error setting net sysctl %s: %v", ipv6FwdPath, err)
 		}
 
 		ipv6ProxyNdpPath := fmt.Sprintf("net/ipv6/conf/%s/proxy_ndp", parentName)
 		err = util.SysctlSet(ipv6ProxyNdpPath, "1")
 		if err != nil {
-			return fmt.Errorf("Error reading net sysctl %s: %v", ipv6ProxyNdpPath, err)
+			return fmt.Errorf("Error setting net sysctl %s: %v", ipv6ProxyNdpPath, err)
 		}
 	}
 


More information about the lxc-devel mailing list