[lxc-devel] [lxd/master] Network: OVN restructure to accommodate different uplink network types

tomponline on Github lxc-bot at linuxcontainers.org
Tue Oct 6 13:30:11 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 327 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201006/c6717431/attachment.bin>
-------------- next part --------------
From 27fbdd30a059a98051180ac7cee574548a05125b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:30:54 +0100
Subject: [PATCH 01/13] lxd/networks: Log error in doNetworksCreate after
 failed create if cleanup fails too

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/networks.go | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lxd/networks.go b/lxd/networks.go
index ae67d059a8..09ea358629 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -456,7 +456,11 @@ func doNetworksCreate(d *Daemon, projectName string, req api.NetworksPost, clien
 	if clientType != cluster.ClientTypeJoiner {
 		err = n.Start()
 		if err != nil {
-			n.Delete(clientType)
+			delErr := n.Delete(clientType)
+			if delErr != nil {
+				logger.Errorf("Failed clearing up network %q after failed create: %v", n.Name(), delErr)
+			}
+
 			return err
 		}
 	}

From 4a50691e278f8bf9219669072ce27f83fc677bcd Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:51:40 +0100
Subject: [PATCH 02/13] lxd/network/driver: Improve missing parent network
 error message

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_macvlan.go | 2 +-
 lxd/network/driver_sriov.go   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/network/driver_macvlan.go b/lxd/network/driver_macvlan.go
index 8f82680e35..2b4903670b 100644
--- a/lxd/network/driver_macvlan.go
+++ b/lxd/network/driver_macvlan.go
@@ -29,7 +29,7 @@ func (n *macvlan) DBType() db.NetworkType {
 // Validate network config.
 func (n *macvlan) Validate(config map[string]string) error {
 	rules := map[string]func(value string) error{
-		"parent":           validInterfaceName,
+		"parent":           validate.Required(validate.IsNotEmpty, validInterfaceName),
 		"mtu":              validate.Optional(validate.IsNetworkMTU),
 		"vlan":             validate.Optional(validate.IsNetworkVLAN),
 		"maas.subnet.ipv4": validate.IsAny,
diff --git a/lxd/network/driver_sriov.go b/lxd/network/driver_sriov.go
index 698242778f..54ead8c60c 100644
--- a/lxd/network/driver_sriov.go
+++ b/lxd/network/driver_sriov.go
@@ -29,7 +29,7 @@ func (n *sriov) DBType() db.NetworkType {
 // Validate network config.
 func (n *sriov) Validate(config map[string]string) error {
 	rules := map[string]func(value string) error{
-		"parent":           validInterfaceName,
+		"parent":           validate.Required(validate.IsNotEmpty, validInterfaceName),
 		"mtu":              validate.Optional(validate.IsNetworkMTU),
 		"vlan":             validate.Optional(validate.IsNetworkVLAN),
 		"maas.subnet.ipv4": validate.IsAny,

From 36c2637c3259268e62dcec5c66dacb2630d31f08 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 14:52:56 +0100
Subject: [PATCH 03/13] lxd/network/driver/ovn: Moves uplink type agnostic
 parent port allocation logic into allocateParentPortIPs()

Ready to accomodate other types of uplink network types.

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index c05910891f..f4ab603101 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -371,8 +371,6 @@ func (n *ovn) setupParentPort(routerMAC net.HardwareAddr) (*ovnParentVars, error
 // setupParentPortBridge allocates external IPs on the parent bridge.
 // Returns the derived ovnParentVars settings.
 func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAddr) (*ovnParentVars, error) {
-	v := &ovnParentVars{}
-
 	bridgeNet, ok := parentNet.(*bridge)
 	if !ok {
 		return nil, fmt.Errorf("Network is not bridge type")
@@ -383,19 +381,32 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd
 		return nil, errors.Wrapf(err, "Network %q is not suitable for use as OVN parent", bridgeNet.name)
 	}
 
+	v, err := n.allocateParentPortIPs(parentNet, "ipv4.address", "ipv6.address", routerMAC)
+	if err != nil {
+		return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network", parentNet.Name())
+	}
+
+	return v, nil
+}
+
+// allocateParentPortIPs attempts to find a free IP in the parent network's OVN ranges and then stores it in
+// ovnVolatileParentIPv4 and ovnVolatileParentIPv6 config keys on this network. Returns ovnParentVars settings.
+func (n *ovn) allocateParentPortIPs(parentNet Network, v4CIDRKey string, v6CIDRKey string, routerMAC net.HardwareAddr) (*ovnParentVars, error) {
+	v := &ovnParentVars{}
+
 	parentNetConf := parentNet.Config()
 
 	// Parent derived settings.
 	v.extSwitchProviderName = parentNet.Name()
 
 	// Optional parent values.
-	parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentNetConf["ipv4.address"])
+	parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentNetConf[v4CIDRKey])
 	if err == nil {
 		v.dnsIPv4 = parentIPv4
 		v.routerExtGwIPv4 = parentIPv4
 	}
 
-	parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentNetConf["ipv6.address"])
+	parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentNetConf[v6CIDRKey])
 	if err == nil {
 		v.dnsIPv6 = parentIPv6
 		v.routerExtGwIPv6 = parentIPv6

From b30f975a6838367a1e117b27583666781d8903f1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:33:29 +0100
Subject: [PATCH 04/13] lxd/network/driver/ovn: Better error messages

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index f4ab603101..ff185854a5 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -365,7 +365,7 @@ func (n *ovn) setupParentPort(routerMAC net.HardwareAddr) (*ovnParentVars, error
 		return n.setupParentPortBridge(parentNet, routerMAC)
 	}
 
-	return nil, fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type())
+	return nil, fmt.Errorf("Failed setting up parent port, network type %q unsupported as OVN parent", parentNet.Type())
 }
 
 // setupParentPortBridge allocates external IPs on the parent bridge.
@@ -597,7 +597,7 @@ func (n *ovn) startParentPort() error {
 		return n.startParentPortBridge(parentNet)
 	}
 
-	return fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type())
+	return fmt.Errorf("Failed starting parent port, network type %q unsupported as OVN parent", parentNet.Type())
 }
 
 // parentOperationLockName returns the lock name to use for operations on the parent network.
@@ -727,7 +727,7 @@ func (n *ovn) deleteParentPort() error {
 			return n.deleteParentPortBridge(parentNet)
 		}
 
-		return fmt.Errorf("Network type %q unsupported as OVN parent", parentNet.Type())
+		return fmt.Errorf("Failed deleting parent port, network type %q unsupported as OVN parent", parentNet.Type())
 	}
 
 	return nil

From fdc703d3e3e83fea3c89da0c849b018ca7976da9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:33:46 +0100
Subject: [PATCH 05/13] lxd/network/driver/ovn: Moves parent port lock into
 deleteParentPort

So it applies to all uplink parent network types.

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index ff185854a5..d73e02f4d7 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -722,6 +722,10 @@ func (n *ovn) deleteParentPort() error {
 			return errors.Wrapf(err, "Failed loading parent network")
 		}
 
+		// Lock parent network so we don't race each other networks using the OVS uplink bridge.
+		unlock := locking.Lock(n.parentOperationLockName(parentNet))
+		defer unlock()
+
 		switch parentNet.Type() {
 		case "bridge":
 			return n.deleteParentPortBridge(parentNet)
@@ -735,10 +739,6 @@ func (n *ovn) deleteParentPort() error {
 
 // deleteParentPortBridge deletes the dnsmasq static lease and removes parent uplink OVS bridge if not in use.
 func (n *ovn) deleteParentPortBridge(parentNet Network) error {
-	// Lock parent network so we don't race each other networks using the OVS uplink bridge.
-	unlock := locking.Lock(n.parentOperationLockName(parentNet))
-	defer unlock()
-
 	// Check OVS uplink bridge exists, if it does, check how many ports it has.
 	removeVeths := false
 	vars := n.parentPortBridgeVars(parentNet)

From 2d4c4be6b06d519a89f09ef1fd88405da094c412 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 16:28:54 +0100
Subject: [PATCH 06/13] lxd/network/driver/ovn: Moves parent port lock into
 startParentPort

So it applies to all uplink parent network types.

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index d73e02f4d7..c4981aa68f 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -592,6 +592,11 @@ func (n *ovn) startParentPort() error {
 		return errors.Wrapf(err, "Failed loading parent network")
 	}
 
+	// Lock parent network so that if multiple OVN networks are trying to connect to the same parent we don't
+	// race each other setting up the connection.
+	unlock := locking.Lock(n.parentOperationLockName(parentNet))
+	defer unlock()
+
 	switch parentNet.Type() {
 	case "bridge":
 		return n.startParentPortBridge(parentNet)
@@ -621,11 +626,6 @@ func (n *ovn) parentPortBridgeVars(parentNet Network) *ovnParentPortBridgeVars {
 func (n *ovn) startParentPortBridge(parentNet Network) error {
 	vars := n.parentPortBridgeVars(parentNet)
 
-	// Lock parent network so that if multiple OVN networks are trying to connect to the same parent we don't
-	// race each other setting up the connection.
-	unlock := locking.Lock(n.parentOperationLockName(parentNet))
-	defer unlock()
-
 	// Do this after gaining lock so that on failure we revert before release locking.
 	revert := revert.New()
 	defer revert.Fail()

From 8e821a1af8fdd708cd353b11d4daeb2933be836c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:34:41 +0100
Subject: [PATCH 07/13] lxd/network/driver/ovn: deleteParentPortBridge comments

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index c4981aa68f..3e3c29c4bc 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -737,7 +737,7 @@ func (n *ovn) deleteParentPort() error {
 	return nil
 }
 
-// deleteParentPortBridge deletes the dnsmasq static lease and removes parent uplink OVS bridge if not in use.
+// deleteParentPortBridge deletes parent uplink OVS bridge, OVN bridge mappings and veth interfaces if not in use.
 func (n *ovn) deleteParentPortBridge(parentNet Network) error {
 	// Check OVS uplink bridge exists, if it does, check how many ports it has.
 	removeVeths := false

From e8f50946eeed770926ef7648d730943bf23b8406 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:35:35 +0100
Subject: [PATCH 08/13] lxd/network/driver/ovn: Don't setup SNAT if no external
 uplink IPs

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 3e3c29c4bc..7d6909abab 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1052,14 +1052,14 @@ func (n *ovn) setup(update bool) error {
 	}
 
 	// Add SNAT rules.
-	if routerIntPortIPv4Net != nil {
+	if routerIntPortIPv4Net != nil && routerExtPortIPv4 != nil {
 		err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv4Net, routerExtPortIPv4)
 		if err != nil {
 			return err
 		}
 	}
 
-	if routerIntPortIPv6Net != nil {
+	if routerIntPortIPv6Net != nil && routerExtPortIPv6 != nil {
 		err = client.LogicalRouterSNATAdd(n.getRouterName(), routerIntPortIPv6Net, routerExtPortIPv6)
 		if err != nil {
 			return err

From 02cb55fc11e0d597d67a094858ccf9e478bb1988 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:58:24 +0100
Subject: [PATCH 09/13] lxd/network/driver/ovn: Makes setting up external
 router port and switch conditional on having external IPs

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 84 ++++++++++++++++++++-------------------
 1 file changed, 43 insertions(+), 41 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 7d6909abab..2c0a5ae001 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1066,17 +1066,6 @@ func (n *ovn) setup(update bool) error {
 		}
 	}
 
-	// Create external logical switch.
-	if update {
-		client.LogicalSwitchDelete(n.getExtSwitchName())
-	}
-
-	err = client.LogicalSwitchAdd(n.getExtSwitchName(), false)
-	if err != nil {
-		return errors.Wrapf(err, "Failed adding external switch")
-	}
-	revert.Add(func() { client.LogicalSwitchDelete(n.getExtSwitchName()) })
-
 	// Generate external router port IPs (in CIDR format).
 	extRouterIPs := []*net.IPNet{}
 	if routerExtPortIPv4Net != nil {
@@ -1093,41 +1082,54 @@ func (n *ovn) setup(update bool) error {
 		})
 	}
 
-	// Create external router port.
-	err = client.LogicalRouterPortAdd(n.getRouterName(), n.getRouterExtPortName(), routerMAC, extRouterIPs...)
-	if err != nil {
-		return errors.Wrapf(err, "Failed adding external router port")
-	}
-	revert.Add(func() { client.LogicalRouterPortDelete(n.getRouterExtPortName()) })
+	if len(extRouterIPs) > 0 {
+		// Create external logical switch.
+		if update {
+			client.LogicalSwitchDelete(n.getExtSwitchName())
+		}
 
-	// Associate external router port to chassis group.
-	err = client.LogicalRouterPortLinkChassisGroup(n.getRouterExtPortName(), n.getChassisGroupName())
-	if err != nil {
-		return errors.Wrapf(err, "Failed linking external router port to chassis group")
-	}
+		err = client.LogicalSwitchAdd(n.getExtSwitchName(), false)
+		if err != nil {
+			return errors.Wrapf(err, "Failed adding external switch")
+		}
+		revert.Add(func() { client.LogicalSwitchDelete(n.getExtSwitchName()) })
 
-	// Create external switch port and link to router port.
-	err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchRouterPortName(), false)
-	if err != nil {
-		return errors.Wrapf(err, "Failed adding external switch router port")
-	}
-	revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchRouterPortName()) })
+		// Create external router port.
+		err = client.LogicalRouterPortAdd(n.getRouterName(), n.getRouterExtPortName(), routerMAC, extRouterIPs...)
+		if err != nil {
+			return errors.Wrapf(err, "Failed adding external router port")
+		}
+		revert.Add(func() { client.LogicalRouterPortDelete(n.getRouterExtPortName()) })
 
-	err = client.LogicalSwitchPortLinkRouter(n.getExtSwitchRouterPortName(), n.getRouterExtPortName())
-	if err != nil {
-		return errors.Wrapf(err, "Failed linking external router port to external switch port")
-	}
+		// Associate external router port to chassis group.
+		err = client.LogicalRouterPortLinkChassisGroup(n.getRouterExtPortName(), n.getChassisGroupName())
+		if err != nil {
+			return errors.Wrapf(err, "Failed linking external router port to chassis group")
+		}
 
-	// Create external switch port and link to external provider network.
-	err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchProviderPortName(), false)
-	if err != nil {
-		return errors.Wrapf(err, "Failed adding external switch provider port")
-	}
-	revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchProviderPortName()) })
+		// Create external switch port and link to router port.
+		err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchRouterPortName(), false)
+		if err != nil {
+			return errors.Wrapf(err, "Failed adding external switch router port")
+		}
+		revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchRouterPortName()) })
 
-	err = client.LogicalSwitchPortLinkProviderNetwork(n.getExtSwitchProviderPortName(), parent.extSwitchProviderName)
-	if err != nil {
-		return errors.Wrapf(err, "Failed linking external switch provider port to external provider network")
+		err = client.LogicalSwitchPortLinkRouter(n.getExtSwitchRouterPortName(), n.getRouterExtPortName())
+		if err != nil {
+			return errors.Wrapf(err, "Failed linking external router port to external switch port")
+		}
+
+		// Create external switch port and link to external provider network.
+		err = client.LogicalSwitchPortAdd(n.getExtSwitchName(), n.getExtSwitchProviderPortName(), false)
+		if err != nil {
+			return errors.Wrapf(err, "Failed adding external switch provider port")
+		}
+		revert.Add(func() { client.LogicalSwitchPortDelete(n.getExtSwitchProviderPortName()) })
+
+		err = client.LogicalSwitchPortLinkProviderNetwork(n.getExtSwitchProviderPortName(), parent.extSwitchProviderName)
+		if err != nil {
+			return errors.Wrapf(err, "Failed linking external switch provider port to external provider network")
+		}
 	}
 
 	// Create internal logical switch if not updating.

From 3099041494bec4a42bb53e75c5a85f30e50718f6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 2 Oct 2020 15:58:44 +0100
Subject: [PATCH 10/13] lxd/network/driver/ovn: Removes old comment

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 2c0a5ae001..bc0404218e 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1149,8 +1149,6 @@ func (n *ovn) setup(update bool) error {
 		return errors.Wrapf(err, "Failed setting IP allocation settings on internal switch")
 	}
 
-	// Find MAC address for internal router port.
-
 	var dhcpv4UUID, dhcpv6UUID string
 
 	if update {

From e9fc96df5e28540c5a213e5895134d7589c26c9a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 5 Oct 2020 16:20:45 +0100
Subject: [PATCH 11/13] lxd/network/driver/ovn: Fix sentence in
 startParentPortBridge error

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index bc0404218e..6b98923523 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -648,7 +648,7 @@ func (n *ovn) startParentPortBridge(parentNet Network) error {
 		fmt.Sprintf("net.ipv6.conf.%s.forwarding=0", vars.ovsEnd),
 	)
 	if err != nil {
-		return errors.Wrapf(err, "Failed to set configure uplink veth interfaces %q and %q", vars.parentEnd, vars.ovsEnd)
+		return errors.Wrapf(err, "Failed to configure uplink veth interfaces %q and %q", vars.parentEnd, vars.ovsEnd)
 	}
 
 	// Connect parent end of veth pair to parent bridge and bring up.

From 137fcbb8b0813eba045c8f2972b2df465a9b9735 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 09:58:58 +0100
Subject: [PATCH 12/13] lxd/network/driver/ovn: Fixes error message in
 setupParentPortBridge

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/driver_ovn.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 6b98923523..99423d4b3c 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -383,7 +383,7 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd
 
 	v, err := n.allocateParentPortIPs(parentNet, "ipv4.address", "ipv6.address", routerMAC)
 	if err != nil {
-		return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network", parentNet.Name())
+		return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network %q", parentNet.Name())
 	}
 
 	return v, nil

From df0a848f3d9c889b7bd72e1401c850a1584a711a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 10:27:37 +0100
Subject: [PATCH 13/13] lxd/network/network/utils: Moves bridge related
 functions into own file

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/network/network_utils.go        | 82 -------------------------
 lxd/network/network_utils_bridge.go | 93 +++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 82 deletions(-)
 create mode 100644 lxd/network/network_utils_bridge.go

diff --git a/lxd/network/network_utils.go b/lxd/network/network_utils.go
index 4723340161..010a00978c 100644
--- a/lxd/network/network_utils.go
+++ b/lxd/network/network_utils.go
@@ -24,7 +24,6 @@ import (
 	"github.com/lxc/lxd/lxd/dnsmasq/dhcpalloc"
 	"github.com/lxc/lxd/lxd/instance"
 	"github.com/lxc/lxd/lxd/instance/instancetype"
-	"github.com/lxc/lxd/lxd/network/openvswitch"
 	"github.com/lxc/lxd/lxd/project"
 	"github.com/lxc/lxd/lxd/state"
 	"github.com/lxc/lxd/shared"
@@ -250,47 +249,6 @@ func isInUseByDevices(s *state.State, networkProjectName string, networkName str
 	return false, nil
 }
 
-// IsNativeBridge returns whether the bridge name specified is a Linux native bridge.
-func IsNativeBridge(bridgeName string) bool {
-	return shared.PathExists(fmt.Sprintf("/sys/class/net/%s/bridge", bridgeName))
-}
-
-// AttachInterface attaches an interface to a bridge.
-func AttachInterface(bridgeName string, devName string) error {
-	if IsNativeBridge(bridgeName) {
-		_, err := shared.RunCommand("ip", "link", "set", "dev", devName, "master", bridgeName)
-		if err != nil {
-			return err
-		}
-	} else {
-		ovs := openvswitch.NewOVS()
-		err := ovs.BridgePortAdd(bridgeName, devName, true)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// DetachInterface detaches an interface from a bridge.
-func DetachInterface(bridgeName string, devName string) error {
-	if IsNativeBridge(bridgeName) {
-		_, err := shared.RunCommand("ip", "link", "set", "dev", devName, "nomaster")
-		if err != nil {
-			return err
-		}
-	} else {
-		ovs := openvswitch.NewOVS()
-		err := ovs.BridgePortDelete(bridgeName, devName)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
 // GetDevMTU retrieves the current MTU setting for a named network device.
 func GetDevMTU(devName string) (uint32, error) {
 	content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/mtu", devName))
@@ -932,46 +890,6 @@ func usesIPv6Firewall(netConfig map[string]string) bool {
 	return false
 }
 
-// BridgeVLANFilteringStatus returns whether VLAN filtering is enabled on a bridge interface.
-func BridgeVLANFilteringStatus(interfaceName string) (string, error) {
-	content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName))
-	if err != nil {
-		return "", errors.Wrapf(err, "Failed getting bridge VLAN status for %q", interfaceName)
-	}
-
-	return strings.TrimSpace(fmt.Sprintf("%s", content)), nil
-}
-
-// BridgeVLANFilterSetStatus sets the status of VLAN filtering on a bridge interface.
-func BridgeVLANFilterSetStatus(interfaceName string, status string) error {
-	err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName), []byte(status), 0)
-	if err != nil {
-		return errors.Wrapf(err, "Failed enabling VLAN filtering on bridge %q", interfaceName)
-	}
-
-	return nil
-}
-
-// BridgeVLANDefaultPVID returns the VLAN default port VLAN ID (PVID).
-func BridgeVLANDefaultPVID(interfaceName string) (string, error) {
-	content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName))
-	if err != nil {
-		return "", errors.Wrapf(err, "Failed getting bridge VLAN default PVID for %q", interfaceName)
-	}
-
-	return strings.TrimSpace(fmt.Sprintf("%s", content)), nil
-}
-
-// BridgeVLANSetDefaultPVID sets the VLAN default port VLAN ID (PVID).
-func BridgeVLANSetDefaultPVID(interfaceName string, vlanID string) error {
-	err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName), []byte(vlanID), 0)
-	if err != nil {
-		return errors.Wrapf(err, "Failed setting bridge VLAN default PVID for %q", interfaceName)
-	}
-
-	return nil
-}
-
 // RandomHwaddr generates a random MAC address from the provided random source.
 func randomHwaddr(r *rand.Rand) string {
 	// Generate a new random MAC address using the usual prefix.
diff --git a/lxd/network/network_utils_bridge.go b/lxd/network/network_utils_bridge.go
new file mode 100644
index 0000000000..f19b313e8d
--- /dev/null
+++ b/lxd/network/network_utils_bridge.go
@@ -0,0 +1,93 @@
+package network
+
+import (
+	"fmt"
+	"io/ioutil"
+	"strings"
+
+	"github.com/pkg/errors"
+
+	"github.com/lxc/lxd/lxd/network/openvswitch"
+	"github.com/lxc/lxd/shared"
+)
+
+// BridgeVLANFilteringStatus returns whether VLAN filtering is enabled on a bridge interface.
+func BridgeVLANFilteringStatus(interfaceName string) (string, error) {
+	content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName))
+	if err != nil {
+		return "", errors.Wrapf(err, "Failed getting bridge VLAN status for %q", interfaceName)
+	}
+
+	return strings.TrimSpace(fmt.Sprintf("%s", content)), nil
+}
+
+// BridgeVLANFilterSetStatus sets the status of VLAN filtering on a bridge interface.
+func BridgeVLANFilterSetStatus(interfaceName string, status string) error {
+	err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/vlan_filtering", interfaceName), []byte(status), 0)
+	if err != nil {
+		return errors.Wrapf(err, "Failed enabling VLAN filtering on bridge %q", interfaceName)
+	}
+
+	return nil
+}
+
+// BridgeVLANDefaultPVID returns the VLAN default port VLAN ID (PVID).
+func BridgeVLANDefaultPVID(interfaceName string) (string, error) {
+	content, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName))
+	if err != nil {
+		return "", errors.Wrapf(err, "Failed getting bridge VLAN default PVID for %q", interfaceName)
+	}
+
+	return strings.TrimSpace(fmt.Sprintf("%s", content)), nil
+}
+
+// BridgeVLANSetDefaultPVID sets the VLAN default port VLAN ID (PVID).
+func BridgeVLANSetDefaultPVID(interfaceName string, vlanID string) error {
+	err := ioutil.WriteFile(fmt.Sprintf("/sys/class/net/%s/bridge/default_pvid", interfaceName), []byte(vlanID), 0)
+	if err != nil {
+		return errors.Wrapf(err, "Failed setting bridge VLAN default PVID for %q", interfaceName)
+	}
+
+	return nil
+}
+
+// IsNativeBridge returns whether the bridge name specified is a Linux native bridge.
+func IsNativeBridge(bridgeName string) bool {
+	return shared.PathExists(fmt.Sprintf("/sys/class/net/%s/bridge", bridgeName))
+}
+
+// AttachInterface attaches an interface to a bridge.
+func AttachInterface(bridgeName string, devName string) error {
+	if IsNativeBridge(bridgeName) {
+		_, err := shared.RunCommand("ip", "link", "set", "dev", devName, "master", bridgeName)
+		if err != nil {
+			return err
+		}
+	} else {
+		ovs := openvswitch.NewOVS()
+		err := ovs.BridgePortAdd(bridgeName, devName, true)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// DetachInterface detaches an interface from a bridge.
+func DetachInterface(bridgeName string, devName string) error {
+	if IsNativeBridge(bridgeName) {
+		_, err := shared.RunCommand("ip", "link", "set", "dev", devName, "nomaster")
+		if err != nil {
+			return err
+		}
+	} else {
+		ovs := openvswitch.NewOVS()
+		err := ovs.BridgePortDelete(bridgeName, devName)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}


More information about the lxc-devel mailing list