aboutgitcodebugslistschat
path: root/tap.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2021-10-11 12:01:31 +0200
committerStefano Brivio <sbrivio@redhat.com>2021-10-14 13:15:12 +0200
commit675174d4ba255383b213437e29b617d8f55dbc69 (patch)
tree7add0cf70e595028f9ca9485eb8e139d3d652bb6 /tap.c
parentdcd3605d14aba011fa6c2f4596cb7494f64d2b93 (diff)
downloadpasst-675174d4ba255383b213437e29b617d8f55dbc69.tar
passt-675174d4ba255383b213437e29b617d8f55dbc69.tar.gz
passt-675174d4ba255383b213437e29b617d8f55dbc69.tar.bz2
passt-675174d4ba255383b213437e29b617d8f55dbc69.tar.lz
passt-675174d4ba255383b213437e29b617d8f55dbc69.tar.xz
passt-675174d4ba255383b213437e29b617d8f55dbc69.tar.zst
passt-675174d4ba255383b213437e29b617d8f55dbc69.zip
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 <sbrivio@redhat.com>
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);