[lxc-devel] [lxd/master] Network: OVN MTU

tomponline on Github lxc-bot at linuxcontainers.org
Tue Aug 18 09:04:59 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 549 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200818/75d67839/attachment.bin>
-------------- next part --------------
From 870553245b21e4c7b91dc98bffed3b5aa1862ffe Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:53:43 +0100
Subject: [PATCH 1/6] lxd/network/network/utils: Removes OVN specific helper
 functions

Moved to own file.

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

diff --git a/lxd/network/network_utils.go b/lxd/network/network_utils.go
index 514a575702..c8d05367e7 100644
--- a/lxd/network/network_utils.go
+++ b/lxd/network/network_utils.go
@@ -867,29 +867,6 @@ func randomHwaddr(r *rand.Rand) string {
 	return ret.String()
 }
 
-// OVNInstanceDevicePortAdd adds a logical port to the OVN network's internal switch and returns the logical
-// port name for use linking an OVS port on the integration bridge to the logical switch port.
-func OVNInstanceDevicePortAdd(network Network, instanceID int, deviceName string, mac net.HardwareAddr, ips []net.IP) (openvswitch.OVNSwitchPort, error) {
-	// Check network is of type OVN.
-	n, ok := network.(*ovn)
-	if !ok {
-		return "", fmt.Errorf("Network is not OVN type")
-	}
-
-	return n.instanceDevicePortAdd(instanceID, deviceName, mac, ips)
-}
-
-// OVNInstanceDevicePortDelete deletes a logical port from the OVN network's internal switch.
-func OVNInstanceDevicePortDelete(network Network, instanceID int, deviceName string) error {
-	// Check network is of type OVN.
-	n, ok := network.(*ovn)
-	if !ok {
-		return fmt.Errorf("Network is not OVN type")
-	}
-
-	return n.instanceDevicePortDelete(instanceID, deviceName)
-}
-
 // parseIPRange parses an IP range in the format "start-end" and converts it to a shared.IPRange.
 // If allowedNets are supplied, then each IP in the range is checked that it belongs to at least one of them.
 // IPs in the range can be zero prefixed, e.g. "::1" or "0.0.0.1", however they should not overlap with any
diff --git a/lxd/network/network_utils_ovn.go b/lxd/network/network_utils_ovn.go
new file mode 100644
index 0000000000..9d02575335
--- /dev/null
+++ b/lxd/network/network_utils_ovn.go
@@ -0,0 +1,31 @@
+package network
+
+import (
+	"fmt"
+	"net"
+
+	"github.com/lxc/lxd/lxd/network/openvswitch"
+)
+
+// OVNInstanceDevicePortAdd adds a logical port to the OVN network's internal switch and returns the logical
+// port name for use linking an OVS port on the integration bridge to the logical switch port.
+func OVNInstanceDevicePortAdd(network Network, instanceID int, deviceName string, mac net.HardwareAddr, ips []net.IP) (openvswitch.OVNSwitchPort, error) {
+	// Check network is of type OVN.
+	n, ok := network.(*ovn)
+	if !ok {
+		return "", fmt.Errorf("Network is not OVN type")
+	}
+
+	return n.instanceDevicePortAdd(instanceID, deviceName, mac, ips)
+}
+
+// OVNInstanceDevicePortDelete deletes a logical port from the OVN network's internal switch.
+func OVNInstanceDevicePortDelete(network Network, instanceID int, deviceName string) error {
+	// Check network is of type OVN.
+	n, ok := network.(*ovn)
+	if !ok {
+		return fmt.Errorf("Network is not OVN type")
+	}
+
+	return n.instanceDevicePortDelete(instanceID, deviceName)
+}

From f7439b8a9d61d7c9b1295161aaf9dfd2e8b6ff66 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:54:48 +0100
Subject: [PATCH 2/6] lxd/network/network/utils/ovn: Adds OVNInstanceDeviceMTU
 function

For retrieving the bridge.mtu setting from the parent network for use when creating instance devices.

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

diff --git a/lxd/network/network_utils_ovn.go b/lxd/network/network_utils_ovn.go
index 9d02575335..03123de306 100644
--- a/lxd/network/network_utils_ovn.go
+++ b/lxd/network/network_utils_ovn.go
@@ -29,3 +29,14 @@ func OVNInstanceDevicePortDelete(network Network, instanceID int, deviceName str
 
 	return n.instanceDevicePortDelete(instanceID, deviceName)
 }
+
+// OVNInstanceDeviceMTU returns the MTU that should be used for an OVN instance device.
+func OVNInstanceDeviceMTU(network Network) (uint32, error) {
+	// Check network is of type OVN.
+	n, ok := network.(*ovn)
+	if !ok {
+		return 0, fmt.Errorf("Network is not OVN type")
+	}
+
+	return n.getBridgeMTU(), nil
+}

From 7c834489ec6ee3601800489d6d31dadebd641a48 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:55:26 +0100
Subject: [PATCH 3/6] lxd/device/nic: Validates mtu field as optional Uint32

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

diff --git a/lxd/device/nic.go b/lxd/device/nic.go
index 8eb86440bf..b029dc6749 100644
--- a/lxd/device/nic.go
+++ b/lxd/device/nic.go
@@ -11,7 +11,7 @@ func nicValidationRules(requiredFields []string, optionalFields []string) map[st
 		"name":                    validate.IsAny,
 		"parent":                  validate.IsAny,
 		"network":                 validate.IsAny,
-		"mtu":                     validate.IsAny,
+		"mtu":                     validate.Optional(validate.IsUint32),
 		"vlan":                    validate.IsNetworkVLAN,
 		"hwaddr":                  validate.IsNetworkMAC,
 		"host_name":               validate.IsAny,

From 637bfeee5d5828889eae2dfe9b2dec88f99fa7b4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:56:01 +0100
Subject: [PATCH 4/6] lxd/network/openvwitch/ovn: Adds MTU support for DHCP and
 IPv6 RA

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

diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go
index 919f275116..3b63fb773a 100644
--- a/lxd/network/openvswitch/ovn.go
+++ b/lxd/network/openvswitch/ovn.go
@@ -51,6 +51,7 @@ type OVNIPv6RAOpts struct {
 	MaxInterval        time.Duration
 	RecursiveDNSServer net.IP
 	DNSSearchList      []string
+	MTU                uint32
 }
 
 // OVNDHCPOptsSet is an existing DHCP options set in the northbound database.
@@ -67,6 +68,7 @@ type OVNDHCPv4Opts struct {
 	RecursiveDNSServer net.IP
 	DomainName         string
 	LeaseTime          time.Duration
+	MTU                uint32
 }
 
 // OVNDHCPv6Opts IPv6 DHCP option set that can be created (and then applied to a switch port by resulting ID).
@@ -193,13 +195,16 @@ func (o *OVN) LogicalRouterPortSetIPv6Advertisements(portName OVNRouterPort, opt
 		args = append(args, fmt.Sprintf("ipv6_ra_configs:min_interval=%d", opts.MinInterval/time.Second))
 	}
 
+	if opts.MTU > 0 {
+		args = append(args, fmt.Sprintf("ipv6_ra_configs:mtu=%d", opts.MTU))
+	}
+
 	if len(opts.DNSSearchList) > 0 {
 		args = append(args, fmt.Sprintf("ipv6_ra_configs:dnssl=%s", strings.Join(opts.DNSSearchList, ",")))
 	}
 
 	if opts.RecursiveDNSServer != nil {
 		args = append(args, fmt.Sprintf("ipv6_ra_configs:rdnss=%s", opts.RecursiveDNSServer.String()))
-
 	}
 
 	// Configure IPv6 Router Advertisements.
@@ -345,6 +350,10 @@ func (o *OVN) LogicalSwitchDHCPv4OptionsSet(switchName OVNSwitch, uuid string, s
 		args = append(args, fmt.Sprintf(`domain_name="%s"`, opts.DomainName))
 	}
 
+	if opts.MTU > 0 {
+		args = append(args, fmt.Sprintf("mtu=%d", opts.MTU))
+	}
+
 	_, err = o.nbctl(args...)
 	if err != nil {
 		return err

From a20cf4073dd37a097d584485989fb6e6fb6f979f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:56:34 +0100
Subject: [PATCH 5/6] lxd/network/driver/ovn: Adds bridge.mtu config option and
 passes to DHCP/RA setup

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 doc/networks.md           |  1 +
 lxd/network/driver_ovn.go | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/doc/networks.md b/doc/networks.md
index ec42f56ffe..2887aad829 100644
--- a/doc/networks.md
+++ b/doc/networks.md
@@ -290,6 +290,7 @@ lxc ls
 Key                             | Type      | Condition             | Default                   | Description
 :--                             | :--       | :--                   | :--                       | :--
 bridge.hwaddr                   | string    | -                     | -                         | MAC address for the bridge
+bridge.mtu                      | integer   | -                     | 1442                      | Bridge MTU (default allows host to host geneve tunnels)
 dns.domain                      | string    | -                     | lxd                       | Domain to advertise to DHCP clients and use for DNS resolution
 dns.search                      | string    | -                     | -                         | Full comma separated domain search list, defaulting to `dns.domain` value
 ipv4.address                    | string    | standard mode         | random unused subnet      | IPv4 address for the bridge (CIDR notation). Use "none" to turn off IPv4 or "auto" to generate a new one
diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index cabe01f2f8..3cfa022542 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -8,6 +8,7 @@ import (
 	"math/big"
 	"math/rand"
 	"net"
+	"strconv"
 	"strings"
 	"time"
 
@@ -28,6 +29,9 @@ import (
 	"github.com/lxc/lxd/shared/validate"
 )
 
+// ovnGeneveTunnelMTU is the MTU that is safe to use when tunneling using geneve.
+const ovnGeneveTunnelMTU = 1442
+
 const ovnChassisPriorityMax = 32767
 const ovnVolatileParentIPv4 = "volatile.parent.ipv4.address"
 const ovnVolatileParentIPv6 = "volatile.parent.ipv6.address"
@@ -71,6 +75,7 @@ func (n *ovn) Validate(config map[string]string) error {
 			return nil
 		},
 		"bridge.hwaddr": validate.Optional(validate.IsNetworkMAC),
+		"bridge.mtu":    validate.Optional(validate.IsUint32),
 		"ipv4.address": func(value string) error {
 			if validate.IsOneOf(value, []string{"auto"}) == nil {
 				return nil
@@ -114,6 +119,21 @@ func (n *ovn) getClient() (*openvswitch.OVN, error) {
 	return client, nil
 }
 
+// getBridgeMTU returns MTU that should be used for the bridge and instance devices. Will also be used to configure
+// the OVN DHCP and IPv6 RA options.
+func (n *ovn) getBridgeMTU() uint32 {
+	if n.config["bridge.mtu"] != "" {
+		mtu, err := strconv.ParseUint(n.config["bridge.mtu"], 10, 32)
+		if err != nil {
+			return ovnGeneveTunnelMTU
+		}
+
+		return uint32(mtu)
+	}
+
+	return ovnGeneveTunnelMTU
+}
+
 // getNetworkPrefix returns OVN network prefix to use for object names.
 func (n *ovn) getNetworkPrefix() string {
 	return fmt.Sprintf("lxd-net%d", n.id)
@@ -932,6 +952,7 @@ func (n *ovn) setup(update bool) error {
 		RecursiveDNSServer: parent.dnsIPv4,
 		DomainName:         n.getDomainName(),
 		LeaseTime:          time.Duration(time.Hour * 1),
+		MTU:                n.getBridgeMTU(),
 	})
 	if err != nil {
 		return errors.Wrapf(err, "Failed adding DHCPv4 settings for internal switch")
@@ -977,6 +998,7 @@ func (n *ovn) setup(update bool) error {
 			SendPeriodic:       true,
 			DNSSearchList:      n.getDNSSearchList(),
 			RecursiveDNSServer: parent.dnsIPv6,
+			MTU:                n.getBridgeMTU(),
 
 			// Keep these low until we support DNS search domains via DHCPv4, as otherwise RA DNSSL
 			// won't take effect until advert after DHCPv4 has run on instance.

From 2fd269bafeebde16ac250ea13432c5b9df323bb3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 18 Aug 2020 09:58:40 +0100
Subject: [PATCH 6/6] lxd/device/nic/ovn: Use parent network's bridge.mtu
 setting for setting device MTU

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

diff --git a/lxd/device/nic_ovn.go b/lxd/device/nic_ovn.go
index 3485841596..5631b02a97 100644
--- a/lxd/device/nic_ovn.go
+++ b/lxd/device/nic_ovn.go
@@ -51,6 +51,7 @@ func (d *nicOVN) validateConfig(instConf instance.ConfigReader) error {
 		"name",
 		"hwaddr",
 		"host_name",
+		"mtu",
 		"ipv4.address",
 		"ipv6.address",
 		"boot.priority",
@@ -70,6 +71,13 @@ func (d *nicOVN) validateConfig(instConf instance.ConfigReader) error {
 		return fmt.Errorf("Specified network must be of type ovn")
 	}
 
+	bannedKeys := []string{"mtu"}
+	for _, bannedKey := range bannedKeys {
+		if d.config[bannedKey] != "" {
+			return fmt.Errorf("Cannot use %q property in conjunction with %q property", bannedKey, "network")
+		}
+	}
+
 	d.network = n // Stored loaded instance for use by other functions.
 	netConfig := d.network.Config()
 
@@ -109,6 +117,14 @@ func (d *nicOVN) validateConfig(instConf instance.ConfigReader) error {
 		}
 	}
 
+	// Apply network level config options to device config before validation.
+	mtu, err := network.OVNInstanceDeviceMTU(n)
+	if err != nil {
+		return err
+	}
+
+	d.config["mtu"] = fmt.Sprintf("%d", mtu)
+
 	rules := nicValidationRules(requiredFields, optionalFields)
 
 	// Now run normal validation.


More information about the lxc-devel mailing list