[lxc-devel] [lxd/master] network: Adds support for multiple upstream DNS servers in OVN networks

tomponline on Github lxc-bot at linuxcontainers.org
Tue Oct 6 15:56:15 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 626 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201006/2ff6bedc/attachment-0001.bin>
-------------- next part --------------
From efffd128341001511c5b3bbeb82af6178c71fd3d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 16:31:37 +0100
Subject: [PATCH 1/5] shares/validate: Whitespace

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 shared/validate/validate.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/shared/validate/validate.go b/shared/validate/validate.go
index 356a7d8744..4217ecf89f 100644
--- a/shared/validate/validate.go
+++ b/shared/validate/validate.go
@@ -226,6 +226,7 @@ func IsNetworkAddressV4List(value string) error {
 			return err
 		}
 	}
+
 	return nil
 }
 

From 896679be6effa830345a836920db173bd3935210 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 16:33:00 +0100
Subject: [PATCH 2/5] lxd/network/openvswitch/ovn: Updates RecursiveDNSServer
 to be list of IPs

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

diff --git a/lxd/network/openvswitch/ovn.go b/lxd/network/openvswitch/ovn.go
index ef181d8706..e0a0d0dc44 100644
--- a/lxd/network/openvswitch/ovn.go
+++ b/lxd/network/openvswitch/ovn.go
@@ -66,7 +66,7 @@ type OVNDHCPv4Opts struct {
 	ServerID           net.IP
 	ServerMAC          net.HardwareAddr
 	Router             net.IP
-	RecursiveDNSServer net.IP
+	RecursiveDNSServer []net.IP
 	DomainName         string
 	LeaseTime          time.Duration
 	MTU                uint32
@@ -75,7 +75,7 @@ type OVNDHCPv4Opts struct {
 // OVNDHCPv6Opts IPv6 DHCP option set that can be created (and then applied to a switch port by resulting ID).
 type OVNDHCPv6Opts struct {
 	ServerID           net.HardwareAddr
-	RecursiveDNSServer net.IP
+	RecursiveDNSServer []net.IP
 	DNSSearchList      []string
 }
 
@@ -358,7 +358,16 @@ func (o *OVN) LogicalSwitchDHCPv4OptionsSet(switchName OVNSwitch, uuid string, s
 	}
 
 	if opts.RecursiveDNSServer != nil {
-		args = append(args, fmt.Sprintf("dns_server=%s", opts.RecursiveDNSServer.String()))
+		nsIPs := make([]string, 0, len(opts.RecursiveDNSServer))
+		for _, nsIP := range opts.RecursiveDNSServer {
+			if nsIP.To4() == nil {
+				continue // Only include IPv4 addresses.
+			}
+
+			nsIPs = append(nsIPs, nsIP.String())
+		}
+
+		args = append(args, fmt.Sprintf("dns_server={%s}", strings.Join(nsIPs, ",")))
 	}
 
 	if opts.DomainName != "" {
@@ -416,7 +425,16 @@ func (o *OVN) LogicalSwitchDHCPv6OptionsSet(switchName OVNSwitch, uuid string, s
 	}
 
 	if opts.RecursiveDNSServer != nil {
-		args = append(args, fmt.Sprintf("dns_server=%s", opts.RecursiveDNSServer.String()))
+		nsIPs := make([]string, 0, len(opts.RecursiveDNSServer))
+		for _, nsIP := range opts.RecursiveDNSServer {
+			if nsIP.To4() != nil {
+				continue // Only include IPv6 addresses.
+			}
+
+			nsIPs = append(nsIPs, nsIP.String())
+		}
+
+		args = append(args, fmt.Sprintf("dns_server={%s}", strings.Join(nsIPs, ",")))
 	}
 
 	_, err = o.nbctl(args...)

From c775eceac72df08927c5f6799e9b88244b19ea9f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 16:35:07 +0100
Subject: [PATCH 3/5] lxd/network/driver/ovn: Updates allocateParentPortIPs to
 detect the parent network IP address and DNS settings

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 99423d4b3c..3080c9da3f 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -44,8 +44,8 @@ type ovnParentVars struct {
 	extSwitchProviderName string
 
 	// DNS.
-	dnsIPv6 net.IP
-	dnsIPv4 net.IP
+	dnsIPv6 []net.IP
+	dnsIPv4 []net.IP
 }
 
 // ovnParentPortBridgeVars parent bridge port variables used for start/stop.
@@ -391,7 +391,7 @@ func (n *ovn) setupParentPortBridge(parentNet Network, routerMAC net.HardwareAdd
 
 // 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) {
+func (n *ovn) allocateParentPortIPs(parentNet Network, routerMAC net.HardwareAddr) (*ovnParentVars, error) {
 	v := &ovnParentVars{}
 
 	parentNetConf := parentNet.Config()
@@ -399,19 +399,51 @@ func (n *ovn) allocateParentPortIPs(parentNet Network, v4CIDRKey string, v6CIDRK
 	// Parent derived settings.
 	v.extSwitchProviderName = parentNet.Name()
 
+	// Detect parent gateway setting.
+	parentIPv4CIDR := parentNetConf["ipv4.address"]
+	if parentIPv4CIDR == "" {
+		parentIPv4CIDR = parentNetConf["ipv4.gateway"]
+	}
+
+	parentIPv6CIDR := parentNetConf["ipv6.address"]
+	if parentIPv6CIDR == "" {
+		parentIPv6CIDR = parentNetConf["ipv6.gateway"]
+	}
+
 	// Optional parent values.
-	parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentNetConf[v4CIDRKey])
+	parentIPv4, parentIPv4Net, err := net.ParseCIDR(parentIPv4CIDR)
 	if err == nil {
-		v.dnsIPv4 = parentIPv4
+		v.dnsIPv4 = []net.IP{parentIPv4}
 		v.routerExtGwIPv4 = parentIPv4
 	}
 
-	parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentNetConf[v6CIDRKey])
+	parentIPv6, parentIPv6Net, err := net.ParseCIDR(parentIPv6CIDR)
 	if err == nil {
-		v.dnsIPv6 = parentIPv6
+		v.dnsIPv6 = []net.IP{parentIPv6}
 		v.routerExtGwIPv6 = parentIPv6
 	}
 
+	// Detect optional DNS server list.
+	if parentNetConf["dns.nameservers"] != "" {
+		// Reset nameservers.
+		v.dnsIPv4 = nil
+		v.dnsIPv6 = nil
+
+		nsList := strings.Split(parentNetConf["dns.nameservers"], ",")
+		for _, ns := range nsList {
+			nsIP := net.ParseIP(strings.TrimSpace(ns))
+			if nsIP == nil {
+				return nil, fmt.Errorf("Invalid parent nameserver")
+			}
+
+			if nsIP.To4() == nil {
+				v.dnsIPv6 = append(v.dnsIPv6, nsIP)
+			} else {
+				v.dnsIPv4 = append(v.dnsIPv4, nsIP)
+			}
+		}
+	}
+
 	// Parse existing allocated IPs for this network on the parent network (if not set yet, will be nil).
 	routerExtPortIPv4 := net.ParseIP(n.config[ovnVolatileParentIPv4])
 	routerExtPortIPv6 := net.ParseIP(n.config[ovnVolatileParentIPv6])

From 6c99bdfd32f4cce8b6cb3032eda69113ee8b0b92 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 16:36:54 +0100
Subject: [PATCH 4/5] lxd/network/driver/ovn: Updates n.allocateParentPortIPs
 usage

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 3080c9da3f..4af51c3092 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -381,7 +381,7 @@ 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)
+	v, err := n.allocateParentPortIPs(parentNet, routerMAC)
 	if err != nil {
 		return nil, errors.Wrapf(err, "Failed allocating parent port IPs on network %q", parentNet.Name())
 	}

From 11a0289883dbeb856344a803535cafb169e8edb3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 6 Oct 2020 16:37:32 +0100
Subject: [PATCH 5/5] lxd/network/driver/ovn: Updates setup IPv6 RDNSS setting

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 4af51c3092..445e555433 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -1257,11 +1257,16 @@ func (n *ovn) setup(update bool) error {
 			adressMode = openvswitch.OVNIPv6AddressModeDHCPStateful
 		}
 
+		var recursiveDNSServer net.IP
+		if len(parent.dnsIPv6) > 0 {
+			recursiveDNSServer = parent.dnsIPv6[0] // OVN only supports 1 RA DNS server.
+		}
+
 		err = client.LogicalRouterPortSetIPv6Advertisements(n.getRouterIntPortName(), &openvswitch.OVNIPv6RAOpts{
 			AddressMode:        adressMode,
 			SendPeriodic:       true,
 			DNSSearchList:      n.getDNSSearchList(),
-			RecursiveDNSServer: parent.dnsIPv6,
+			RecursiveDNSServer: recursiveDNSServer,
 			MTU:                bridgeMTU,
 
 			// Keep these low until we support DNS search domains via DHCPv4, as otherwise RA DNSSL


More information about the lxc-devel mailing list