Skip to content

Commit c8c444c

Browse files
saiarcot895yanjundeng
authored andcommitted
Add fix for building libnl3 on Ubuntu 24.04 (sonic-net#22093)
Why I did it When building libnl3 inside a container with a newer kernel (such as what is used on Ubuntu 24.04), some commands to create a private network namespace may fail due to restrictions. This was seen in libnl3's own Github Actions CI, and is now seen on build machines running Ubuntu 24.04 as the host with kernel 6.8. Work item tracking Microsoft ADO (number only): 31902668 How I did it Backport a patch from libnl3 to handle such cases.
1 parent 7b2fd1d commit c8c444c

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

src/libnl3/patch/series

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
switch-to-debhelper.patch
33
keep-symbol-versions-in-libraries.patch
44
update-changelog.patch
5+
skip-tests-when-having-no-private-netns.patch
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
From b3822aa3b605b2dc5f01f9aee8ee224fc23e23a0 Mon Sep 17 00:00:00 2001
2+
From: Thomas Haller <[email protected]>
3+
Date: Sun, 12 Jan 2025 10:54:59 +0100
4+
Subject: [PATCH] test: skip tests when having no private netns
5+
6+
In github CI we seem now unable to create the netns. This worked
7+
previously, now it no longer does.
8+
9+
Handle that by skipping the tests that require a netns.
10+
---
11+
tests/cksuite-all-netns.c | 13 +++++++++-
12+
tests/nl-test-util.c | 50 +++++++++++++++++++++++++++++++++++++--
13+
tests/nl-test-util.h | 3 +++
14+
3 files changed, 63 insertions(+), 3 deletions(-)
15+
16+
diff --git a/tests/cksuite-all-netns.c b/tests/cksuite-all-netns.c
17+
index 1948c3e8..04e0f6df 100644
18+
--- a/tests/cksuite-all-netns.c
19+
+++ b/tests/cksuite-all-netns.c
20+
@@ -73,6 +73,9 @@ START_TEST(cache_and_clone)
21+
int i;
22+
int r;
23+
24+
+ if (_nltst_skip_no_netns())
25+
+ return;
26+
+
27+
for (i = 0; i < _NL_N_ELEMENTS(links); i++) {
28+
if (links[i].add)
29+
_nltst_add_link(NULL, links[i].ifname, links[i].kind,
30+
@@ -132,11 +135,16 @@ START_TEST(test_create_iface)
31+
_nl_auto_rtnl_link struct rtnl_link *link2 = NULL;
32+
_nl_auto_rtnl_link struct rtnl_link *peer = NULL;
33+
_nltst_auto_delete_link const char *IFNAME_DUMMY = NULL;
34+
- _nltst_auto_delete_link const char *IFNAME = "ifname";
35+
+ _nltst_auto_delete_link const char *IFNAME = NULL;
36+
int ifindex_dummy;
37+
uint32_t u32;
38+
int r;
39+
40+
+ if (_nltst_skip_no_netns())
41+
+ return;
42+
+
43+
+ IFNAME = "ifname";
44+
+
45+
switch (TEST_IDX) {
46+
case 0:
47+
link = _nltst_assert(rtnl_link_bridge_alloc());
48+
diff --git a/tests/nl-test-util.c b/tests/nl-test-util.c
49+
index dc8dc5ad..d1a8f3f1 100644
50+
--- a/tests/nl-test-util.c
51+
+++ b/tests/nl-test-util.c
52+
@@ -84,6 +84,7 @@ uint32_t _nltst_rand_u32(void)
53+
54+
struct nltst_netns {
55+
int canary;
56+
+ bool is_unshared;
57+
};
58+
59+
/*****************************************************************************/
60+
@@ -114,6 +115,23 @@ void nltst_netns_fixture_teardown(void)
61+
_nl_clear_pointer(&_netns_fixture_global.nsdata, nltst_netns_leave);
62+
}
63+
64+
+bool nltst_netns_fixture_is_unshared(void)
65+
+{
66+
+ _assert_nltst_netns(_netns_fixture_global.nsdata);
67+
+ return _netns_fixture_global.nsdata->is_unshared;
68+
+}
69+
+
70+
+/*****************************************************************************/
71+
+
72+
+bool _nltst_skip_no_netns(void)
73+
+{
74+
+ if (nltst_netns_fixture_is_unshared())
75+
+ return false;
76+
+
77+
+ printf("skip test due to having no private netns\n");
78+
+ return true;
79+
+}
80+
+
81+
/*****************************************************************************/
82+
83+
static void unshare_user(void)
84+
@@ -125,6 +143,10 @@ static void unshare_user(void)
85+
86+
/* Become a root in new user NS. */
87+
r = unshare(CLONE_NEWUSER);
88+
+ if (r != 0 && errno == EPERM) {
89+
+ /* No permissions? Ignore. Will be handled later. */
90+
+ return;
91+
+ }
92+
_nltst_assert_errno(r == 0);
93+
94+
/* Since Linux 3.19 we have to disable setgroups() in order to map users.
95+
@@ -149,14 +171,28 @@ static void unshare_user(void)
96+
}
97+
r = fprintf(f, "0 %d 1", uid);
98+
_nltst_assert_errno(r > 0);
99+
- _nltst_fclose(f);
100+
+ r = fclose(f);
101+
+ if (r != 0 && errno == EPERM) {
102+
+ /* Oddly, it seems close() can fail at this point. Ignore it,
103+
+ * but we probably will be unable to unshare (which we handle
104+
+ * later).
105+
+ */
106+
+ } else
107+
+ _nltst_assert_errno(r == 0);
108+
109+
/* Map current GID to root in NS to be created. */
110+
f = fopen("/proc/self/gid_map", "we");
111+
_nltst_assert_errno(f);
112+
r = fprintf(f, "0 %d 1", gid);
113+
_nltst_assert_errno(r > 0);
114+
- _nltst_fclose(f);
115+
+ r = fclose(f);
116+
+ if (r != 0 && errno == EPERM) {
117+
+ /* Oddly, it seems close() can fail at this point. Ignore it, but
118+
+ * we probably will be unable to unshare (which we handle
119+
+ * later).
120+
+ */
121+
+ } else
122+
+ _nltst_assert_errno(r == 0);
123+
}
124+
125+
struct nltst_netns *nltst_netns_enter(void)
126+
@@ -172,6 +208,15 @@ struct nltst_netns *nltst_netns_enter(void)
127+
unshare_user();
128+
129+
r = unshare(CLONE_NEWNET | CLONE_NEWNS);
130+
+ if (r != 0 && errno == EPERM) {
131+
+ /* The system is probably sandboxed somehow and we are unable
132+
+ * to create a private netns. That seems questionable, because
133+
+ * a point of a private netns is to sandbox an application.
134+
+ * Not having permissions to sandbox sounds bad.
135+
+ *
136+
+ * Anyway. We accept this and will later skip some tests. */
137+
+ return nsdata;
138+
+ }
139+
_nltst_assert_errno(r == 0);
140+
141+
/* We need a read-only /sys so that the platform knows there's no udev. */
142+
@@ -179,6 +224,7 @@ struct nltst_netns *nltst_netns_enter(void)
143+
r = mount("sys", "/sys", "sysfs", MS_RDONLY, NULL);
144+
_nltst_assert_errno(r == 0);
145+
146+
+ nsdata->is_unshared = true;
147+
return nsdata;
148+
}
149+
150+
diff --git a/tests/nl-test-util.h b/tests/nl-test-util.h
151+
index 981228b4..d840a4ab 100644
152+
--- a/tests/nl-test-util.h
153+
+++ b/tests/nl-test-util.h
154+
@@ -429,6 +429,9 @@ char **_nltst_strtokv(const char *str);
155+
156+
void nltst_netns_fixture_setup(void);
157+
void nltst_netns_fixture_teardown(void);
158+
+bool nltst_netns_fixture_is_unshared(void);
159+
+
160+
+bool _nltst_skip_no_netns(void);
161+
162+
struct nltst_netns;
163+

0 commit comments

Comments
 (0)