[lxc-devel] [lxd/master] Network: Ping OVN router's external IPv6 address on startup

tomponline on Github lxc-bot at linuxcontainers.org
Wed Aug 19 09:11:25 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 347 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200819/853fd8dd/attachment.bin>
-------------- next part --------------
From fb50fc4a964a1bfdd46b1abff82251a17c9fe0dc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 09:24:26 +0100
Subject: [PATCH 1/3] doc/networks: Adds link to OVN network

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

diff --git a/doc/networks.md b/doc/networks.md
index 2887aad829..c44dca2abf 100644
--- a/doc/networks.md
+++ b/doc/networks.md
@@ -5,6 +5,7 @@ LXD supports the following network types:
  - [bridge](#network-bridge): Creates an L2 bridge for connecting instances to (can provide local DHCP and DNS). This is the default.
  - [macvlan](#network-macvlan): Provides preset configuration to use when connecting instances to a parent macvlan interface.
  - [sriov](#network-sriov): Provides preset configuration to use when connecting instances to a parent SR-IOV interface.
+ - [ovn](#network-ovn): Creates a logical network using the OVN software defined networking system.
 
 The desired type can be specified using the `--type` argument, e.g.
 

From 5398036a31ed17b0a31b13c60454ea80c698a72d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 09:34:48 +0100
Subject: [PATCH 2/3] lxd/network/network/utils: Adds pingIP function

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

diff --git a/lxd/network/network_utils.go b/lxd/network/network_utils.go
index c8d05367e7..b4757742d3 100644
--- a/lxd/network/network_utils.go
+++ b/lxd/network/network_utils.go
@@ -543,6 +543,22 @@ func inRoutingTable(subnet *net.IPNet) bool {
 	return false
 }
 
+// pingIP sends a single ping packet to the specified IP, returns true if responds, false if not.
+func pingIP(ip net.IP) bool {
+	cmd := "ping"
+	if ip.To4() == nil {
+		cmd = "ping6"
+	}
+
+	_, err := shared.RunCommand(cmd, "-n", "-q", ip.String(), "-c", "1", "-W", "1")
+	if err != nil {
+		// Remote didn't answer.
+		return false
+	}
+
+	return true
+}
+
 func pingSubnet(subnet *net.IPNet) bool {
 	var fail bool
 	var failLock sync.Mutex
@@ -551,14 +567,7 @@ func pingSubnet(subnet *net.IPNet) bool {
 	ping := func(ip net.IP) {
 		defer wgChecks.Done()
 
-		cmd := "ping"
-		if ip.To4() == nil {
-			cmd = "ping6"
-		}
-
-		_, err := shared.RunCommand(cmd, "-n", "-q", ip.String(), "-c", "1", "-W", "1")
-		if err != nil {
-			// Remote didn't answer
+		if !pingIP(ip) {
 			return
 		}
 

From 522cedb58fd94649606a888b2e7e5be8c17a3c9e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 19 Aug 2020 10:07:12 +0100
Subject: [PATCH 3/3] lxd/network/driver/ovn: Pings OVN external IPv6 router IP
 on bridge port start

This is to workaround an issue in older versions of OVN where the router will not perform neighbour discovery for the IPv6 gateway when using IPv6 SNAT.

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

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index bf7f12b5d8..2beb096fd9 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -581,6 +581,31 @@ func (n *ovn) startParentPortBridge(parentNet Network) error {
 		return errors.Wrapf(err, "Failed to associate parent OVS bridge %q to OVN provider %q", vars.ovsBridge, parentNet.Name())
 	}
 
+	routerExtPortIPv6 := net.ParseIP(n.config[ovnVolatileParentIPv6])
+	if routerExtPortIPv6 != nil {
+		// Now that the OVN router is connected to the uplink parent bridge, attempt to ping the OVN
+		// router's external IPv6 from the LXD host running the parent bridge in an attempt to trigger the
+		// OVN router to learn the parent uplink gateway's MAC address. This is to work around a bug in
+		// older versions of OVN that meant that the OVN router would not attempt to learn the external
+		// uplink IPv6 gateway MAC address when using SNAT, meaning that external IPv6 connectivity
+		// wouldn't work until the next router advertisement was sent (which could be several minutes).
+		// By pinging the OVN router's external IP this will trigger an NDP request from the parent bridge
+		// which will cause the OVN router to learn its MAC address.
+		func() {
+			// Try several attempts as it can take a few seconds for the network to come up.
+			for i := 0; i < 5; i++ {
+				if pingIP(routerExtPortIPv6) {
+					n.logger.Debug("OVN router external IPv6 address reachable", log.Ctx{"ip": routerExtPortIPv6.String()})
+					return
+				}
+
+				time.Sleep(time.Second)
+			}
+
+			n.logger.Warn("OVN router external IPv6 address unreachable", log.Ctx{"ip": routerExtPortIPv6.String()})
+		}()
+	}
+
 	revert.Success()
 	return nil
 }


More information about the lxc-devel mailing list