1 /*
2  * Copyright (c) International Business Machines Corp., 2008
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11  * the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Author: Veerendra C <vechandr@in.ibm.com>
17  *
18  * Net namespaces were introduced around 2.6.25.  Kernels before that,
19  * assume they are not enabled.  Kernels after that, check for -EINVAL
20  * when trying to use CLONE_NEWNET and CLONE_NEWNS.
21  ***************************************************************************/
22 
23 #define _GNU_SOURCE
24 #include <sched.h>
25 #include "config.h"
26 #include "libclone.h"
27 #include "lapi/syscalls.h"
28 #include "test.h"
29 #include "safe_macros.h"
30 
31 #ifndef CLONE_NEWNS
32 #define CLONE_NEWNS -1
33 #endif
34 
check_iproute(unsigned int spe_ipver)35 static void check_iproute(unsigned int spe_ipver)
36 {
37 	FILE *ipf;
38 	int n;
39 	unsigned int ipver = 0;
40 
41 	ipf = popen("ip -V", "r");
42 	if (ipf == NULL)
43 		tst_brkm(TCONF, NULL,
44 				"Failed while opening pipe for iproute check");
45 
46 	n = fscanf(ipf, "ip utility, iproute2-ss%u", &ipver);
47 	if (n < 1) {
48 		tst_brkm(TCONF, NULL,
49 			"Failed while obtaining version for iproute check");
50 	}
51 	if (ipver < spe_ipver) {
52 		tst_brkm(TCONF, NULL, "The commands in iproute tools do "
53 			"not support required objects");
54 	}
55 
56 	pclose(ipf);
57 }
58 
dummy(void * arg)59 static int dummy(void *arg)
60 {
61 	(void) arg;
62 	return 0;
63 }
64 
check_netns(void)65 static void check_netns(void)
66 {
67 	int pid, status;
68 	/* Checking if the kernel supports unshare with netns capabilities. */
69 	if (CLONE_NEWNS == -1)
70 		tst_brkm(TCONF | TERRNO, NULL, "CLONE_NEWNS (%d) not supported",
71 			 CLONE_NEWNS);
72 
73 	pid = do_clone_unshare_test(T_UNSHARE, CLONE_NEWNET | CLONE_NEWNS,
74 	                            dummy, NULL);
75 	if (pid == -1)
76 		tst_brkm(TCONF | TERRNO, NULL,
77 				"unshare syscall smoke test failed");
78 
79 	SAFE_WAIT(NULL, &status);
80 }
81