1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2017 Oracle and/or its affiliates. All Rights Reserved.
4f08c3bdfSopenharmony_ci */
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci#define _GNU_SOURCE
7f08c3bdfSopenharmony_ci#include <stdlib.h>
8f08c3bdfSopenharmony_ci#include <errno.h>
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ci#include "tst_test.h"
11f08c3bdfSopenharmony_ci#include "clone_platform.h"
12f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
13f08c3bdfSopenharmony_ci#include "lapi/sched.h"
14f08c3bdfSopenharmony_ci
15f08c3bdfSopenharmony_cistatic void *child_stack;
16f08c3bdfSopenharmony_cistatic int sysctl_net = -1;
17f08c3bdfSopenharmony_cistatic int sysctl_net_new = -1;
18f08c3bdfSopenharmony_cistatic const char sysctl_path[] = "/proc/sys/net/ipv4/conf/lo/tag";
19f08c3bdfSopenharmony_cistatic const char sysctl_path_def[] = "/proc/sys/net/ipv4/conf/default/tag";
20f08c3bdfSopenharmony_cistatic int flags = CLONE_NEWNET | CLONE_VM | SIGCHLD;
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic void setup(void)
23f08c3bdfSopenharmony_ci{
24f08c3bdfSopenharmony_ci	child_stack = SAFE_MALLOC(CHILD_STACK_SIZE);
25f08c3bdfSopenharmony_ci}
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_cistatic void cleanup(void)
28f08c3bdfSopenharmony_ci{
29f08c3bdfSopenharmony_ci	if (sysctl_net != -1)
30f08c3bdfSopenharmony_ci		SAFE_FILE_PRINTF(sysctl_path, "%d", sysctl_net);
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci	free(child_stack);
33f08c3bdfSopenharmony_ci}
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_cistatic int newnet(void *arg LTP_ATTRIBUTE_UNUSED)
36f08c3bdfSopenharmony_ci{
37f08c3bdfSopenharmony_ci	SAFE_FILE_SCANF(sysctl_path, "%d", &sysctl_net_new);
38f08c3bdfSopenharmony_ci	tst_syscall(__NR_exit, 0);
39f08c3bdfSopenharmony_ci	return 0;
40f08c3bdfSopenharmony_ci}
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic long clone_child(void)
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	TEST(ltp_clone(flags, newnet, NULL, CHILD_STACK_SIZE, child_stack));
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	if (TST_RET == -1 && TST_ERR == EINVAL)
47f08c3bdfSopenharmony_ci		tst_brk(TCONF, "CONFIG_NET_NS was disabled");
48f08c3bdfSopenharmony_ci
49f08c3bdfSopenharmony_ci	if (TST_RET == -1)
50f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "clone(CLONE_NEWNET) failed");
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	return TST_RET;
53f08c3bdfSopenharmony_ci}
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_cistatic void do_test(void)
56f08c3bdfSopenharmony_ci{
57f08c3bdfSopenharmony_ci	int def_val;
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_ci	tst_res(TINFO, "create clone in a new netns with 'CLONE_NEWNET' flag");
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	SAFE_FILE_SCANF(sysctl_path, "%d", &sysctl_net);
62f08c3bdfSopenharmony_ci	SAFE_FILE_PRINTF(sysctl_path, "%d", sysctl_net + 1);
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	clone_child();
65f08c3bdfSopenharmony_ci	tst_reap_children();
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_ci	if (sysctl_net_new == (sysctl_net + 1)) {
68f08c3bdfSopenharmony_ci		tst_res(TFAIL, "sysctl params equal: %s=%d",
69f08c3bdfSopenharmony_ci			sysctl_path, sysctl_net_new);
70f08c3bdfSopenharmony_ci	}
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci	SAFE_FILE_SCANF(sysctl_path_def, "%d", &def_val);
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	if (sysctl_net_new != def_val) {
75f08c3bdfSopenharmony_ci		tst_res(TFAIL, "netns param init to non-default value %d",
76f08c3bdfSopenharmony_ci			sysctl_net_new);
77f08c3bdfSopenharmony_ci	}
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_ci	/* restore previous value */
80f08c3bdfSopenharmony_ci	SAFE_FILE_PRINTF(sysctl_path, "%d", sysctl_net);
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	tst_res(TPASS, "sysctl params differ in new netns");
83f08c3bdfSopenharmony_ci}
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_cistatic struct tst_test test = {
86f08c3bdfSopenharmony_ci	.test_all = do_test,
87f08c3bdfSopenharmony_ci	.setup = setup,
88f08c3bdfSopenharmony_ci	.cleanup = cleanup,
89f08c3bdfSopenharmony_ci	.needs_root = 1,
90f08c3bdfSopenharmony_ci};
91