.tmpfs_size = 4 * (1024 * 1024),
.mount_proc = true,
.iface = NULL,
- .iface_lo_up = false,
+ .iface_no_lo = false,
+ .iface_vs_ip = "192.168.255.2",
+ .iface_vs_nm = "255.255.255.0",
+ .iface_vs_gw = "192.168.255.1",
.sbinip_fd = -1,
};
/* *INDENT-OFF* */
{{"bindmount_ro", required_argument, NULL, 'R'}, "List of mountpoints to be mounted --bind (ro) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'"},
{{"bindmount", required_argument, NULL, 'B'}, "List of mountpoints to be mounted --bind (rw) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'"},
{{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax"},
- {{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVTAP) and put inside the subprocess' namespace"},
- {{"iface_lo_up", no_argument, NULL, 0x700}, "Bring up the 'lo' interface"},
{{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
{{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc in the jail"},
+ {{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVTAP) and put inside the subprocess' namespace as 'vs'"},
+ {{"iface_no_lo", no_argument, NULL, 0x700}, "Don't Bring up the 'lo' interface"},
+ {{"iface_vs_ip", required_argument, NULL, 0x701}, "IP of the 'vs' interface"},
+ {{"iface_vs_nm", required_argument, NULL, 0x702}, "Netmask of the 'vs' interface"},
+ {{"iface_vs_gw", required_argument, NULL, 0x703}, "Default GW for the 'vs' interface"},
{{0, 0, 0, 0}, NULL},
};
/* *INDENT-ON* */
nsjconf->iface = optarg;
break;
case 0x700:
- nsjconf->iface_lo_up = true;
+ nsjconf->iface_no_lo = true;
+ break;
+ case 0x701:
+ nsjconf->iface_vs_ip = optarg;
+ break;
+ case 0x702:
+ nsjconf->iface_vs_nm = optarg;
+ break;
+ case 0x703:
+ nsjconf->iface_vs_gw = optarg;
break;
default:
cmdlineUsage(argv[0], custom_opts);
#include <arpa/inet.h>
#include <errno.h>
#include <net/if.h>
+#include <net/route.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
#include <sched.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/socket.h>
}
}
-bool netCloneMacVtapAndNS(struct nsjconf_t * nsjconf, int pid)
+#define IFACE_NAME "vs"
+bool netCloneMacVtapAndNS(struct nsjconf_t *nsjconf, int pid)
{
if (nsjconf->iface == NULL) {
return true;
char pid_str[256];
snprintf(pid_str, sizeof(pid_str), "%d", pid);
char *const argv_netns[] =
- { "ip", "link", "set", "dev", iface, "netns", pid_str, "name", "virt.ns",
+ { "ip", "link", "set", "dev", iface, "netns", pid_str, "name", IFACE_NAME,
NULL
};
if (netSystemSbinIp(nsjconf, argv_netns) == false) {
snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", ifacename);
if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
- PLOG_E("ioctl(iface='%s', SIOCGIFFLAGS, IFF_UP", ifacename);
+ PLOG_E("ioctl(iface='%s', SIOCGIFFLAGS, IFF_UP)", ifacename);
close(sock);
return false;
}
ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
- PLOG_E("ioctl(iface='%s', SIOCSIFFLAGS, IFF_UP", ifacename);
+ PLOG_E("ioctl(iface='%s', SIOCSIFFLAGS, IFF_UP)", ifacename);
+ close(sock);
+ return false;
+ }
+
+ close(sock);
+ return true;
+}
+
+bool netConfigureVs(struct nsjconf_t * nsjconf)
+{
+ struct ifreq ifr;
+ snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", IFACE_NAME);
+ struct in_addr addr;
+
+ int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (sock == -1) {
+ PLOG_E("socket(AF_INET, SOCK_STREAM, IPPROTO_IP)");
+ return false;
+ }
+
+ if (inet_pton(AF_INET, nsjconf->iface_vs_ip, &addr) != 1) {
+ PLOG_E("Cannot convert '%s' into an IPv4 address", nsjconf->iface_vs_ip);
+ close(sock);
+ return false;
+ }
+ struct sockaddr_in *sa = (struct sockaddr_in *)(&ifr.ifr_addr);
+ sa->sin_family = AF_INET;
+ sa->sin_addr = addr;
+ if (ioctl(sock, SIOCSIFADDR, &ifr) == -1) {
+ PLOG_E("ioctl(iface='%s', SIOCSIFADDR, '%s')", IFACE_NAME, nsjconf->iface_vs_ip);
+ close(sock);
+ return false;
+ }
+
+ if (inet_pton(AF_INET, nsjconf->iface_vs_nm, &addr) != 1) {
+ PLOG_E("Cannot convert '%s' into an IPv4 netmask", nsjconf->iface_vs_nm);
+ close(sock);
+ return false;
+ }
+ sa->sin_family = AF_INET;
+ sa->sin_addr = addr;
+ if (ioctl(sock, SIOCSIFNETMASK, &ifr) == -1) {
+ PLOG_E("ioctl(iface='%s', SIOCSIFNETMASK, '%s')", IFACE_NAME, nsjconf->iface_vs_nm);
+ close(sock);
+ return false;
+ }
+
+ if (netIfaceUp(IFACE_NAME) == false) {
+ return false;
+ }
+
+ if (inet_pton(AF_INET, nsjconf->iface_vs_gw, &addr) != 1) {
+ PLOG_E("Cannot convert '%s' into an IPv4 GW address", nsjconf->iface_vs_gw);
+ close(sock);
+ return false;
+ }
+
+ struct rtentry rt;
+ memset(&rt, '\0', sizeof(rt));
+
+ struct sockaddr_in *sdest = (struct sockaddr_in *)(&rt.rt_dst);
+ struct sockaddr_in *smask = (struct sockaddr_in *)(&rt.rt_genmask);
+ struct sockaddr_in *sgate = (struct sockaddr_in *)(&rt.rt_gateway);
+ sdest->sin_family = AF_INET;
+ sdest->sin_addr.s_addr = INADDR_ANY;
+ smask->sin_family = AF_INET;
+ smask->sin_addr.s_addr = INADDR_ANY;
+ sgate->sin_family = AF_INET;
+ sgate->sin_addr = addr;
+
+ rt.rt_flags = RTF_UP | RTF_GATEWAY;
+
+ if (ioctl(sock, SIOCADDRT, &rt) == -1) {
+ PLOG_E("ioctl(SIOCADDRT, '%s')", nsjconf->iface_vs_gw);
close(sock);
return false;
}