mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-27 04:54:41 +08:00
selftests/bpf: Move open_netns() and close_netns() into network_helpers.c
These will also be used by the xdp_do_redirect test being added in the next commit. Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20220309105346.100053-5-toke@redhat.com
This commit is contained in:
parent
24592ad1ab
commit
a30338840f
@ -1,18 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <linux/limits.h>
|
||||
|
||||
#include "bpf_util.h"
|
||||
#include "network_helpers.h"
|
||||
#include "test_progs.h"
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
#define log_err(MSG, ...) ({ \
|
||||
@ -356,3 +363,82 @@ char *ping_command(int family)
|
||||
}
|
||||
return "ping";
|
||||
}
|
||||
|
||||
struct nstoken {
|
||||
int orig_netns_fd;
|
||||
};
|
||||
|
||||
static int setns_by_fd(int nsfd)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = setns(nsfd, CLONE_NEWNET);
|
||||
close(nsfd);
|
||||
|
||||
if (!ASSERT_OK(err, "setns"))
|
||||
return err;
|
||||
|
||||
/* Switch /sys to the new namespace so that e.g. /sys/class/net
|
||||
* reflects the devices in the new namespace.
|
||||
*/
|
||||
err = unshare(CLONE_NEWNS);
|
||||
if (!ASSERT_OK(err, "unshare"))
|
||||
return err;
|
||||
|
||||
/* Make our /sys mount private, so the following umount won't
|
||||
* trigger the global umount in case it's shared.
|
||||
*/
|
||||
err = mount("none", "/sys", NULL, MS_PRIVATE, NULL);
|
||||
if (!ASSERT_OK(err, "remount private /sys"))
|
||||
return err;
|
||||
|
||||
err = umount2("/sys", MNT_DETACH);
|
||||
if (!ASSERT_OK(err, "umount2 /sys"))
|
||||
return err;
|
||||
|
||||
err = mount("sysfs", "/sys", "sysfs", 0, NULL);
|
||||
if (!ASSERT_OK(err, "mount /sys"))
|
||||
return err;
|
||||
|
||||
err = mount("bpffs", "/sys/fs/bpf", "bpf", 0, NULL);
|
||||
if (!ASSERT_OK(err, "mount /sys/fs/bpf"))
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nstoken *open_netns(const char *name)
|
||||
{
|
||||
int nsfd;
|
||||
char nspath[PATH_MAX];
|
||||
int err;
|
||||
struct nstoken *token;
|
||||
|
||||
token = malloc(sizeof(struct nstoken));
|
||||
if (!ASSERT_OK_PTR(token, "malloc token"))
|
||||
return NULL;
|
||||
|
||||
token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY);
|
||||
if (!ASSERT_GE(token->orig_netns_fd, 0, "open /proc/self/ns/net"))
|
||||
goto fail;
|
||||
|
||||
snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name);
|
||||
nsfd = open(nspath, O_RDONLY | O_CLOEXEC);
|
||||
if (!ASSERT_GE(nsfd, 0, "open netns fd"))
|
||||
goto fail;
|
||||
|
||||
err = setns_by_fd(nsfd);
|
||||
if (!ASSERT_OK(err, "setns_by_fd"))
|
||||
goto fail;
|
||||
|
||||
return token;
|
||||
fail:
|
||||
free(token);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void close_netns(struct nstoken *token)
|
||||
{
|
||||
ASSERT_OK(setns_by_fd(token->orig_netns_fd), "setns_by_fd");
|
||||
free(token);
|
||||
}
|
||||
|
@ -55,4 +55,13 @@ int make_sockaddr(int family, const char *addr_str, __u16 port,
|
||||
struct sockaddr_storage *addr, socklen_t *len);
|
||||
char *ping_command(int family);
|
||||
|
||||
struct nstoken;
|
||||
/**
|
||||
* open_netns() - Switch to specified network namespace by name.
|
||||
*
|
||||
* Returns token with which to restore the original namespace
|
||||
* using close_netns().
|
||||
*/
|
||||
struct nstoken *open_netns(const char *name);
|
||||
void close_netns(struct nstoken *token);
|
||||
#endif
|
||||
|
@ -10,8 +10,6 @@
|
||||
* to drop unexpected traffic.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
@ -19,10 +17,8 @@
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/time_types.h>
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -92,91 +88,6 @@ static int write_file(const char *path, const char *newval)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nstoken {
|
||||
int orig_netns_fd;
|
||||
};
|
||||
|
||||
static int setns_by_fd(int nsfd)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = setns(nsfd, CLONE_NEWNET);
|
||||
close(nsfd);
|
||||
|
||||
if (!ASSERT_OK(err, "setns"))
|
||||
return err;
|
||||
|
||||
/* Switch /sys to the new namespace so that e.g. /sys/class/net
|
||||
* reflects the devices in the new namespace.
|
||||
*/
|
||||
err = unshare(CLONE_NEWNS);
|
||||
if (!ASSERT_OK(err, "unshare"))
|
||||
return err;
|
||||
|
||||
/* Make our /sys mount private, so the following umount won't
|
||||
* trigger the global umount in case it's shared.
|
||||
*/
|
||||
err = mount("none", "/sys", NULL, MS_PRIVATE, NULL);
|
||||
if (!ASSERT_OK(err, "remount private /sys"))
|
||||
return err;
|
||||
|
||||
err = umount2("/sys", MNT_DETACH);
|
||||
if (!ASSERT_OK(err, "umount2 /sys"))
|
||||
return err;
|
||||
|
||||
err = mount("sysfs", "/sys", "sysfs", 0, NULL);
|
||||
if (!ASSERT_OK(err, "mount /sys"))
|
||||
return err;
|
||||
|
||||
err = mount("bpffs", "/sys/fs/bpf", "bpf", 0, NULL);
|
||||
if (!ASSERT_OK(err, "mount /sys/fs/bpf"))
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* open_netns() - Switch to specified network namespace by name.
|
||||
*
|
||||
* Returns token with which to restore the original namespace
|
||||
* using close_netns().
|
||||
*/
|
||||
static struct nstoken *open_netns(const char *name)
|
||||
{
|
||||
int nsfd;
|
||||
char nspath[PATH_MAX];
|
||||
int err;
|
||||
struct nstoken *token;
|
||||
|
||||
token = calloc(1, sizeof(struct nstoken));
|
||||
if (!ASSERT_OK_PTR(token, "malloc token"))
|
||||
return NULL;
|
||||
|
||||
token->orig_netns_fd = open("/proc/self/ns/net", O_RDONLY);
|
||||
if (!ASSERT_GE(token->orig_netns_fd, 0, "open /proc/self/ns/net"))
|
||||
goto fail;
|
||||
|
||||
snprintf(nspath, sizeof(nspath), "%s/%s", "/var/run/netns", name);
|
||||
nsfd = open(nspath, O_RDONLY | O_CLOEXEC);
|
||||
if (!ASSERT_GE(nsfd, 0, "open netns fd"))
|
||||
goto fail;
|
||||
|
||||
err = setns_by_fd(nsfd);
|
||||
if (!ASSERT_OK(err, "setns_by_fd"))
|
||||
goto fail;
|
||||
|
||||
return token;
|
||||
fail:
|
||||
free(token);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void close_netns(struct nstoken *token)
|
||||
{
|
||||
ASSERT_OK(setns_by_fd(token->orig_netns_fd), "setns_by_fd");
|
||||
free(token);
|
||||
}
|
||||
|
||||
static int netns_setup_namespaces(const char *verb)
|
||||
{
|
||||
const char * const *ns = namespaces;
|
||||
|
Loading…
Reference in New Issue
Block a user