A crude way of cloning an eth interface
This commit is contained in:
parent
470bbb9a5d
commit
9960304cab
@ -198,6 +198,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
{{"silent", no_argument, NULL, 0x0504}, "Redirect child's fd:0/1/2 to /dev/null (default: false)"},
|
||||
{{"bindmount", required_argument, NULL, 'B'}, "List of mountpoints to be mounted --bind inside the container. Can be specified multiple times (default: none)"},
|
||||
{{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times (default: none)"},
|
||||
{{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVTAP) and put inside the subprocess' namespace"},
|
||||
{{0, 0, 0, 0}, NULL},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
@ -209,7 +210,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
|
||||
int opt_index = 0;
|
||||
for (;;) {
|
||||
int c = getopt_long(argc, argv, "H:c:p:i:u:g:l:t:M:Ndveh?B:T:", opts, &opt_index);
|
||||
int c = getopt_long(argc, argv, "H:c:p:i:u:g:l:t:M:Ndveh?B:T:I:", opts, &opt_index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
@ -356,6 +357,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
nsjconf->iface = optarg;
|
||||
break;
|
||||
default:
|
||||
cmdlineUsage(argv[0], custom_opts);
|
||||
return false;
|
||||
|
1
common.h
1
common.h
@ -81,6 +81,7 @@ struct nsjconf_t {
|
||||
bool is_silent;
|
||||
struct mountfs_t *bindmountpts;
|
||||
struct mountfs_t *tmpfsmountpts;
|
||||
char *iface;
|
||||
uid_t initial_uid;
|
||||
gid_t initial_gid;
|
||||
unsigned int max_conns_per_ip;
|
||||
|
63
net.c
63
net.c
@ -30,12 +30,75 @@
|
||||
#include <strings.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
static bool netSystem(const char *bin, char *const *argv)
|
||||
{
|
||||
int pid = fork();
|
||||
if (pid == -1) {
|
||||
PLOG_E("fork()");
|
||||
return false;
|
||||
}
|
||||
if (pid == 0) {
|
||||
execv(bin, argv);
|
||||
PLOG_E("execve('%s')", bin);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int status;
|
||||
while (wait4(pid, &status, __WALL, NULL) != pid) ;
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) == 0) {
|
||||
return true;
|
||||
}
|
||||
LOG_W("'%s' returned with exit status: %d", bin, WEXITSTATUS(status));
|
||||
return false;
|
||||
}
|
||||
if (WIFSIGNALED(status)) {
|
||||
LOG_W("'%s' killed with signal: %d", bin, WTERMSIG(status));
|
||||
return false;
|
||||
}
|
||||
LOG_E("Unknown exit status for '%s' (pid=%d): %d", bin, pid, status);
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
bool netCloneMacVtapAndNS(struct nsjconf_t * nsjconf, int pid)
|
||||
{
|
||||
if (nsjconf->iface == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char iface[512];
|
||||
snprintf(iface, sizeof(iface), "%s.ns.%d", nsjconf->iface, pid);
|
||||
|
||||
#define SBIN_IP_PATH "/sbin/ip"
|
||||
char *const argv_add[] =
|
||||
{ SBIN_IP_PATH, "link", "add", "link", nsjconf->iface, iface, "type", "macvtap", NULL };
|
||||
if (netSystem(SBIN_IP_PATH, argv_add) == false) {
|
||||
LOG_E("Couldn't create MACVTAP interface for '%s'", nsjconf->iface);
|
||||
return false;
|
||||
}
|
||||
|
||||
char pid_str[512];
|
||||
snprintf(pid_str, sizeof(pid_str), "%d", pid);
|
||||
char *const argv_netns[] = { SBIN_IP_PATH, "link", "set", "dev", iface, "netns", pid_str, NULL };
|
||||
if (netSystem(SBIN_IP_PATH, argv_netns) == false) {
|
||||
LOG_E("Couldn't put interface '%s' into NS of PID '%d'", iface, pid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool netIsSocket(int fd)
|
||||
{
|
||||
int optval;
|
||||
|
1
net.h
1
net.h
@ -26,6 +26,7 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid);
|
||||
bool netLimitConns(struct nsjconf_t *nsjconf, int connsock);
|
||||
int netGetRecvSocket(int port);
|
||||
int netAcceptConn(int listenfd);
|
||||
|
1
nsjail.c
1
nsjail.c
@ -187,6 +187,7 @@ int main(int argc, char *argv[])
|
||||
.is_silent = false,
|
||||
.bindmountpts = NULL,
|
||||
.tmpfsmountpts = NULL,
|
||||
.iface = NULL,
|
||||
.initial_uid = getuid(),
|
||||
.initial_gid = getgid(),
|
||||
.max_conns_per_ip = 0,
|
||||
|
@ -223,6 +223,10 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
|
||||
return;
|
||||
}
|
||||
|
||||
if (netCloneMacVtapAndNS(nsjconf, pid) == false) {
|
||||
LOG_E("Couldn't create and put MACVTAP interface into NS of PID '%d'", pid);
|
||||
}
|
||||
|
||||
char log_buf[4096];
|
||||
|
||||
close(pipefd[1]);
|
||||
|
Loading…
Reference in New Issue
Block a user