aboutgitcodebugslistschat
path: root/tap.c
diff options
context:
space:
mode:
Diffstat (limited to 'tap.c')
-rw-r--r--tap.c120
1 files changed, 16 insertions, 104 deletions
diff --git a/tap.c b/tap.c
index 0abf5a0..ec2b8b5 100644
--- a/tap.c
+++ b/tap.c
@@ -25,10 +25,10 @@
#include <arpa/inet.h>
#include <stdint.h>
#include <sys/epoll.h>
+#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/ioctl.h>
#include <sys/uio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -50,6 +50,8 @@
#include "ndp.h"
#include "dhcpv6.h"
#include "pcap.h"
+#include "netlink.h"
+#include "pasta.h"
/* IPv4 (plus ARP) and IPv6 message batches from tap/guest to IP handlers */
static struct tap_msg seq4[TAP_MSGS];
@@ -844,102 +846,23 @@ static void tap_sock_init_unix(struct ctx *c)
static int tun_ns_fd = -1;
/**
- * tap_sock_init_tun_ns() - Create tuntap fd in namespace, bring up loopback
+ * tap_ns_tun() - Get tuntap fd in namespace
* @c: Execution context
- */
-static int tap_sock_init_tun_ns(void *c)
-{
- int fd;
-
- if (ns_enter((struct ctx *)c))
- goto fail;
-
- if ((fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0)
- goto fail;
-
- tun_ns_fd = fd;
-
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("socket for ioctl");
- goto fail;
- }
-
- if (ioctl(fd, SIOCSIFFLAGS, &((struct ifreq){ .ifr_name = "lo",
- .ifr_flags = IFF_UP }))) {
- perror("SIOCSIFFLAGS ioctl for \"lo\"");
- close(fd);
- goto fail;
- }
-
- close(fd);
-
- return 0;
-
-fail:
- tun_ns_fd = -1;
- return 0;
-}
-
-/**
- * struct tap_sock_if_up_ns_arg - Arguments for tap_sock_if_up_ns()
- * @c: Execution context
- * @ifname: Interface name of tap device
- */
-struct tap_sock_if_up_ns_arg {
- struct ctx *c;
- char ifname[IFNAMSIZ];
-};
-
-/**
- * tap_sock_if_up_ns() - Bring up tap, get or set MAC address (if we have one)
- * @ifname: Interface name
*
- * Return: 0 -- not fundamental, the interface can be brought up later
+ * Return: 0
*/
-static int tap_sock_if_up_ns(void *arg)
+static int tap_ns_tun(void *arg)
{
- struct ifreq ifr = { .ifr_flags = IFF_UP };
- struct tap_sock_if_up_ns_arg *a;
- int fd;
-
- a = (struct tap_sock_if_up_ns_arg *)arg;
-
- if (ns_enter(a->c))
- return 0;
-
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- perror("socket for ioctl");
- return 0;
- }
-
- strncpy(ifr.ifr_name, a->ifname, IFNAMSIZ);
- if (ioctl(fd, SIOCSIFFLAGS, &ifr)) {
- perror("SIOCSIFFLAGS ioctl for tap");
- goto out;
- }
-
- if (memcmp(a->c->mac_guest,
- ((uint8_t [ETH_ALEN]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }),
- ETH_ALEN)) {
- ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
- memcpy(ifr.ifr_hwaddr.sa_data, a->c->mac_guest, ETH_ALEN);
-
- if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
- perror("SIOCSIFHWADDR ioctl for tap");
- goto out;
- }
- } else {
- if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
- perror("SIOCGIFHWADDR ioctl for tap");
- goto out;
- }
+ struct ifreq ifr = { .ifr_flags = IFF_TAP | IFF_NO_PI };
+ struct ctx *c = (struct ctx *)arg;
- memcpy(a->c->mac_guest, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
- proto_update_l2_buf(a->c->mac_guest, NULL, NULL);
- }
+ strncpy(ifr.ifr_name, c->pasta_ifn, IFNAMSIZ);
-out:
- close(fd);
+ if (ns_enter(c) ||
+ (tun_ns_fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0 ||
+ ioctl(tun_ns_fd, TUNSETIFF, &ifr) ||
+ !(c->pasta_ifi = if_nametoindex(c->pasta_ifn)))
+ tun_ns_fd = -1;
return 0;
}
@@ -950,24 +873,13 @@ out:
*/
static void tap_sock_init_tun(struct ctx *c)
{
- struct ifreq ifr = { .ifr_flags = IFF_TAP | IFF_NO_PI };
- struct tap_sock_if_up_ns_arg ifup_arg;
-
- NS_CALL(tap_sock_init_tun_ns, c);
+ NS_CALL(tap_ns_tun, c);
if (tun_ns_fd == -1) {
err("Failed to open tun socket in namespace");
exit(EXIT_FAILURE);
}
- strncpy(ifr.ifr_name, c->pasta_ifn, IFNAMSIZ);
- if (ioctl(tun_ns_fd, TUNSETIFF, &ifr)) {
- perror("TUNSETIFF ioctl");
- exit(EXIT_FAILURE);
- }
-
- strncpy(ifup_arg.ifname, c->pasta_ifn, IFNAMSIZ);
- ifup_arg.c = c;
- NS_CALL(tap_sock_if_up_ns, (void *)&ifup_arg);
+ pasta_ns_conf(c);
pcap_init(c, c->pasta_netns_fd);