[lxc-devel] [lxd/master] netns_ifaddrs: support NETLINK_DUMP_STRICT_CHK

brauner on Github lxc-bot at linuxcontainers.org
Mon Oct 8 19:34:28 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181008/3cbe13c7/attachment.bin>
-------------- next part --------------
From 75493bf35ccb466dccd87b1634d5832f06485a68 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 8 Oct 2018 21:17:27 +0200
Subject: [PATCH 1/4] macro: add SOL_NETLINK

This allows to set netlink socket properties.

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

diff --git a/shared/network.c b/shared/network.c
index 688a18686d..9e4984388f 100644
--- a/shared/network.c
+++ b/shared/network.c
@@ -24,6 +24,10 @@
 	((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))))
 #endif
 
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+
 #ifndef RTM_GETLINK
 #define RTM_GETLINK 18
 #endif

From 3bd2066c96cbc3c7af9aa7260014e8da5f434e0b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 8 Oct 2018 21:17:54 +0200
Subject: [PATCH 2/4] macro: add NETLINK_DUMP_STRICT_CHK

This adds support for the new socket option, NETLINK_DUMP_STRICT_CHK,
that userspace can use via setsockopt to request strict checking of
headers and attributes on dump requests.

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

diff --git a/shared/network.c b/shared/network.c
index 9e4984388f..83563357c8 100644
--- a/shared/network.c
+++ b/shared/network.c
@@ -28,6 +28,10 @@
 #define SOL_NETLINK 270
 #endif
 
+#ifndef NETLINK_DUMP_STRICT_CHK
+#define NETLINK_DUMP_STRICT_CHK 12
+#endif
+
 #ifndef RTM_GETLINK
 #define RTM_GETLINK 18
 #endif

From cc849e100e7d6fa5400e19cacd4dab46b9dfbdf0 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 8 Oct 2018 21:19:03 +0200
Subject: [PATCH 3/4] netns_ifaddrs: check for NETLINK_DUMP_STRICT_CHK

Make use of the new socket option, NETLINK_DUMP_STRICT_CHK, that
userspace can use via setsockopt to request strict checking of headers
and attributes on dump requests.

To get dump features such as kernel side filtering based on data in
the header or attributes appended to the dump request, userspace
must call setsockopt() for NETLINK_DUMP_STRICT_CHK and a non-zero
value. This is necessary to make use of the IFA_TARGET_NETNSID property.

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

diff --git a/shared/netns_getifaddrs.c b/shared/netns_getifaddrs.c
index 3ecfb50374..d6f368baf3 100644
--- a/shared/netns_getifaddrs.c
+++ b/shared/netns_getifaddrs.c
@@ -430,6 +430,14 @@ static int __rtnl_enumerate(int link_af, int addr_af, __s32 netns_id,
 	if (fd < 0)
 		return -1;
 
+	r = setsockopt(fd, SOL_NETLINK, NETLINK_DUMP_STRICT_CHK, &(int){1},
+		       sizeof(int));
+	if (r < 0 && netns_id >= 0) {
+		close(fd);
+		*netnsid_aware = false;
+		return -1;
+	}
+
 	r = __netlink_recv(fd, 1, RTM_GETLINK, link_af, netns_id,
 			   &getlink_netnsid_aware, cb, ctx);
 	if (!r)

From 888ad17d261a58a5c2142efd868a9dc22fd0ccdc Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 8 Oct 2018 21:31:10 +0200
Subject: [PATCH 4/4] checkfeature: simplify is_netnsid_aware() check

The IFA_TARGET_NETNSID patch is bundled with the NETLINK_DUMP_STRICT_CHK
socket property patch. If the latter isn't present the former can't
work. So just check whether we can set that socket option. If we can we
know we're good.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/main_checkfeature.go | 53 ++++++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/lxd/main_checkfeature.go b/lxd/main_checkfeature.go
index b769304969..724b4fdd62 100644
--- a/lxd/main_checkfeature.go
+++ b/lxd/main_checkfeature.go
@@ -67,56 +67,54 @@ static int netns_set_nsid(int fd)
 	return 0;
 }
 
-void is_netnsid_aware(int *hostnetns_fd)
+void is_netnsid_aware(int *hostnetns_fd, int *newnetns_fd)
 {
-	int netnsid, ret;
+	int sock_fd, netnsid, ret;
 	struct netns_ifaddrs *ifaddrs;
-	int newnetns_fd = -1;
 
 	*hostnetns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
 	if (*hostnetns_fd < 0) {
 		(void)sprintf(errbuf, "%s", "Failed to preserve host network namespace\n");
-		goto on_error;
+		return;
 	}
 
 	ret = unshare(CLONE_NEWNET);
 	if (ret < 0) {
 		(void)sprintf(errbuf, "%s", "Failed to unshare network namespace\n");
-		goto on_error;
+		return;
 	}
 
-	newnetns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
-	if (newnetns_fd < 0) {
+	*newnetns_fd = open("/proc/self/ns/net", O_RDONLY | O_CLOEXEC);
+	if (*newnetns_fd < 0) {
 		(void)sprintf(errbuf, "%s", "Failed to preserve new network namespace\n");
-		goto on_error;
+		return;
 	}
 
 	ret = netns_set_nsid(*hostnetns_fd);
 	if (ret < 0) {
 		(void)sprintf(errbuf, "%s", "failed to set network namespace identifier\n");
-		goto on_error;
+		return;
 	}
 
 	netnsid = netns_get_nsid(*hostnetns_fd);
 	if (netnsid < 0) {
 		(void)sprintf(errbuf, "%s", "Failed to get network namespace identifier\n");
-		goto on_error;
+		return;
 	}
 
-	ret = netns_getifaddrs(&ifaddrs, netnsid, &netnsid_aware);
-	netns_freeifaddrs(ifaddrs);
-	if (ret < 0) {
-		(void)sprintf(errbuf, "%s", "Netlink is not fully network namespace id aware\n");
-		goto on_error;
+	sock_fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
+	if (sock_fd < 0) {
+		(void)sprintf(errbuf, "%s", "Failed to open netlink routing socket\n");
+		return;
 	}
 
-	ret = setns(*hostnetns_fd, CLONE_NEWNET);
-	if (ret < 0)
-		(void)sprintf(errbuf, "%s", "Failed to attach to host network namespace\n");
-
-on_error:
-	if (newnetns_fd >= 0)
-		close(newnetns_fd);
+	ret = setsockopt(sock_fd, SOL_NETLINK, NETLINK_DUMP_STRICT_CHK, &(int){1}, sizeof(int));
+	close(sock_fd);
+	if (ret < 0) {
+		(void)sprintf(errbuf, "%s", "Failed to set NETLINK_DUMP_STRICT_CHK socket option\n");
+		return;
+	}
+	netnsid_aware = true;
 }
 
 void is_uevent_aware()
@@ -128,13 +126,20 @@ void is_uevent_aware()
 }
 
 void checkfeature() {
-	int hostnetns_fd = -1;
+	int hostnetns_fd = -1, newnetns_fd = -1;
 
-	is_netnsid_aware(&hostnetns_fd);
+	is_netnsid_aware(&hostnetns_fd, &newnetns_fd);
 	is_uevent_aware();
 
+	if (setns(hostnetns_fd, CLONE_NEWNET) < 0)
+		(void)sprintf(errbuf, "%s", "Failed to attach to host network namespace\n");
+
 	if (hostnetns_fd >= 0)
 		close(hostnetns_fd);
+
+	if (newnetns_fd >= 0)
+		close(newnetns_fd);
+
 }
 
 static bool is_empty_string(char *s)


More information about the lxc-devel mailing list