diff options
author | Florian Weimer <fweimer@redhat.com> | 2016-12-31 18:51:07 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2016-12-31 18:51:07 +0100 |
commit | 5707a64d9462001f9c7c2e02d3f52cf8b0181658 (patch) | |
tree | 21d7c8e03848524dd858199032194665847ee7b5 /support/support_enter_network_namespace.c | |
parent | a851999f61ad7ceabc2a945a3c31c60e8c914a4b (diff) | |
download | glibc-5707a64d9462001f9c7c2e02d3f52cf8b0181658.tar.gz |
support: Helper functions for entering namespaces
Diffstat (limited to 'support/support_enter_network_namespace.c')
-rw-r--r-- | support/support_enter_network_namespace.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c new file mode 100644 index 0000000000..3af18e6f5d --- /dev/null +++ b/support/support_enter_network_namespace.c @@ -0,0 +1,74 @@ +/* Enter a network namespace. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <support/namespace.h> + +#include <net/if.h> +#include <sched.h> +#include <stdio.h> +#include <string.h> +#include <support/check.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <xsocket.h> + +static bool in_uts_namespace; + +bool +support_enter_network_namespace (void) +{ +#ifdef CLONE_NEWUTS + if (unshare (CLONE_NEWUTS) == 0) + in_uts_namespace = true; + else + printf ("warning: unshare (CLONE_NEWUTS) failed: %m\n"); +#endif + +#ifdef CLONE_NEWNET + if (unshare (CLONE_NEWNET) == 0) + { + /* Bring up the loopback interface. */ + int fd = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); + struct ifreq req; + strcpy (req.ifr_name, "lo"); + TEST_VERIFY_EXIT (ioctl (fd, SIOCGIFFLAGS, &req) == 0); + bool already_up = req.ifr_flags & IFF_UP; + if (already_up) + /* This means that we likely have not achieved isolation from + the parent namespace. */ + printf ("warning: loopback interface already exists" + " in new network namespace\n"); + else + { + req.ifr_flags |= IFF_UP | IFF_RUNNING; + TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0); + } + close (fd); + + return !already_up; + } +#endif + printf ("warning: could not enter network namespace\n"); + return false; +} + +bool +support_in_uts_namespace (void) +{ + return in_uts_namespace; +} |