[lxc-devel] [lxd/master] Fix network interface state retrieval

stgraber on Github lxc-bot at linuxcontainers.org
Wed Apr 17 13:35:46 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190417/7ed65478/attachment.bin>
-------------- next part --------------
From fa9c30ba706b57df788fcc4ea4d6712a093ccd28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 17 Apr 2019 12:48:08 +0100
Subject: [PATCH 1/4] shared/network: Fix reporting of down interfaces
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/network_linux.go | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/shared/network_linux.go b/shared/network_linux.go
index 4de04e4cda..dc6dd40a3e 100644
--- a/shared/network_linux.go
+++ b/shared/network_linux.go
@@ -65,26 +65,31 @@ func NetnsGetifaddrs(initPID int32) (map[string]api.ContainerStateNetwork, error
 			}
 		}
 
-		if addr.ifa_addr != nil && (addr.ifa_addr.sa_family == C.AF_INET || addr.ifa_addr.sa_family == C.AF_INET6) {
-			netState := "down"
-			netType := "unknown"
+		// Interface flags
+		netState := "down"
+		netType := "unknown"
 
-			if (addr.ifa_flags & C.IFF_BROADCAST) > 0 {
-				netType = "broadcast"
-			}
+		if (addr.ifa_flags & C.IFF_BROADCAST) > 0 {
+			netType = "broadcast"
+		}
 
-			if (addr.ifa_flags & C.IFF_LOOPBACK) > 0 {
-				netType = "loopback"
-			}
+		if (addr.ifa_flags & C.IFF_LOOPBACK) > 0 {
+			netType = "loopback"
+		}
 
-			if (addr.ifa_flags & C.IFF_POINTOPOINT) > 0 {
-				netType = "point-to-point"
-			}
+		if (addr.ifa_flags & C.IFF_POINTOPOINT) > 0 {
+			netType = "point-to-point"
+		}
 
-			if (addr.ifa_flags & C.IFF_UP) > 0 {
-				netState = "up"
-			}
+		if (addr.ifa_flags & C.IFF_UP) > 0 {
+			netState = "up"
+		}
+		addNetwork.State = netState
+		addNetwork.Type = netType
+		addNetwork.Mtu = int(addr.ifa_mtu)
 
+		// Addresses
+		if addr.ifa_addr != nil && (addr.ifa_addr.sa_family == C.AF_INET || addr.ifa_addr.sa_family == C.AF_INET6) {
 			family := "inet"
 			if addr.ifa_addr.sa_family == C.AF_INET6 {
 				family = "inet6"
@@ -129,9 +134,6 @@ func NetnsGetifaddrs(initPID int32) (map[string]api.ContainerStateNetwork, error
 			address.Scope = scope
 
 			addNetwork.Addresses = append(addNetwork.Addresses, address)
-			addNetwork.State = netState
-			addNetwork.Type = netType
-			addNetwork.Mtu = int(addr.ifa_mtu)
 		} else if addr.ifa_addr != nil && addr.ifa_addr.sa_family == C.AF_PACKET {
 			if (addr.ifa_flags & C.IFF_LOOPBACK) == 0 {
 				var buf [1024]C.char

From c8fcb6f893a49535a396efd77748b6f9f263490e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Wed, 17 Apr 2019 14:34:00 +0100
Subject: [PATCH 2/4] shared/getifaddrs: Export peer link id

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 shared/netns_getifaddrs.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/shared/netns_getifaddrs.c b/shared/netns_getifaddrs.c
index d6fd96c1a0..2e854a44dd 100644
--- a/shared/netns_getifaddrs.c
+++ b/shared/netns_getifaddrs.c
@@ -30,6 +30,9 @@ struct netns_ifaddrs {
 	// This field is not present struct ifaddrs
 	int ifa_ifindex;
 
+	// This field is not present struct ifaddrs
+	int ifa_ifindex_peer;
+
 	unsigned ifa_flags;
 
 	// This field is not present struct ifaddrs
@@ -234,6 +237,12 @@ static int nl_msg_to_ifaddr(void *pctx, bool *netnsid_aware, struct nlmsghdr *h)
 			case IFLA_TARGET_NETNSID:
 				*netnsid_aware = true;
 				break;
+			case IFLA_LINK:
+				if (__RTA_DATALEN(rta))
+					memcpy(&ifs->ifa.ifa_ifindex_peer,
+						__RTA_DATA(rta),
+						__RTA_DATALEN(rta));
+				break;
 			}
 		}
 

From 896546466358b96306db4a0ad6ddf80110418026 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 17 Apr 2019 14:34:44 +0100
Subject: [PATCH 3/4] shared/network: Get HostName field when possible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 shared/network_linux.go | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/shared/network_linux.go b/shared/network_linux.go
index dc6dd40a3e..3e920f3ccb 100644
--- a/shared/network_linux.go
+++ b/shared/network_linux.go
@@ -6,6 +6,7 @@ package shared
 import (
 	"fmt"
 	"io"
+	"net"
 	"os"
 	"strings"
 
@@ -88,6 +89,13 @@ func NetnsGetifaddrs(initPID int32) (map[string]api.ContainerStateNetwork, error
 		addNetwork.Type = netType
 		addNetwork.Mtu = int(addr.ifa_mtu)
 
+		if initPID != 0 && int(addr.ifa_ifindex_peer) > 0 {
+			hostInterface, err := net.InterfaceByIndex(int(addr.ifa_ifindex_peer))
+			if err == nil {
+				addNetwork.HostName = hostInterface.Name
+			}
+		}
+
 		// Addresses
 		if addr.ifa_addr != nil && (addr.ifa_addr.sa_family == C.AF_INET || addr.ifa_addr.sa_family == C.AF_INET6) {
 			family := "inet"

From 59217a093b42606cc822c56c6daec3c9e7361caf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 17 Apr 2019 14:35:06 +0100
Subject: [PATCH 4/4] lxd: More reliably grab interface host name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/container_lxc.go | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index ea01370731..11d2271e8c 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -6278,7 +6278,6 @@ func (c *containerLXC) memoryState() api.ContainerStateMemory {
 
 func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork {
 	result := map[string]api.ContainerStateNetwork{}
-	var networks *map[string]api.ContainerStateNetwork
 
 	pid := c.InitPID()
 	if pid < 1 {
@@ -6292,7 +6291,7 @@ func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork {
 			couldUseNetnsGetifaddrs = false
 			logger.Error("Failed to retrieve network information via netlink", log.Ctx{"container": c.name, "pid": pid})
 		} else {
-			networks = &nw
+			result = nw
 		}
 	}
 
@@ -6321,13 +6320,7 @@ func (c *containerLXC) networkState() map[string]api.ContainerStateNetwork {
 			logger.Error("Failure to read forkgetnet json", log.Ctx{"container": c.name, "err": err})
 			return result
 		}
-		networks = &nw
-	}
-
-	// Add HostName field
-	for netName, net := range *networks {
-		net.HostName = c.getHostInterface(netName)
-		result[netName] = net
+		result = nw
 	}
 
 	return result
@@ -8544,6 +8537,13 @@ func (c *containerLXC) setNetworkPriority() error {
 }
 
 func (c *containerLXC) getHostInterface(name string) string {
+	// Pull directly from kernel
+	networks := c.networkState()
+	if networks[name].HostName != "" {
+		return networks[name].HostName
+	}
+
+	// Fallback to poking LXC
 	if c.IsRunning() {
 		networkKeyPrefix := "lxc.net"
 		if !util.RuntimeLiblxcVersionAtLeast(2, 1, 0) {
@@ -8563,6 +8563,7 @@ func (c *containerLXC) getHostInterface(name string) string {
 		}
 	}
 
+	// Fallback to parsing LXD config
 	for _, k := range c.expandedDevices.DeviceNames() {
 		dev := c.expandedDevices[k]
 		if dev["type"] != "nic" && dev["type"] != "infiniband" {
@@ -8581,6 +8582,7 @@ func (c *containerLXC) getHostInterface(name string) string {
 		return m["host_name"]
 	}
 
+	// Fail
 	return ""
 }
 


More information about the lxc-devel mailing list