[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