From 675174d4ba255383b213437e29b617d8f55dbc69 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Mon, 11 Oct 2021 12:01:31 +0200 Subject: conf, tap: Split netlink and pasta functions, allow interface configuration Move netlink routines to their own file, and use netlink to configure or fetch all the information we need, except for the TUNSETIFF ioctl. Move pasta-specific functions to their own file as well, add parameters and calls to configure the tap interface in the namespace. Signed-off-by: Stefano Brivio --- tap.c | 120 +++++++++--------------------------------------------------------- 1 file changed, 16 insertions(+), 104 deletions(-) (limited to 'tap.c') diff --git a/tap.c b/tap.c index 0abf5a0..ec2b8b5 100644 --- a/tap.c +++ b/tap.c @@ -25,10 +25,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -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); -- cgit v1.2.3