summaryrefslogtreecommitdiff
path: root/src/network/networkd-netdev-tuntap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-netdev-tuntap.c')
-rw-r--r--src/network/networkd-netdev-tuntap.c83
1 files changed, 55 insertions, 28 deletions
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index 8f6046174..dd3bd96db 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -28,24 +28,27 @@
#define TUN_DEV "/dev/net/tun"
static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
+ TunTap *t;
assert(netdev);
+ assert(netdev->ifname);
assert(ifr);
- memset(ifr, 0, sizeof(*ifr));
-
- if (netdev->kind == NETDEV_KIND_TAP)
+ if (netdev->kind == NETDEV_KIND_TAP) {
+ t = TAP(netdev);
ifr->ifr_flags |= IFF_TAP;
- else
+ } else {
+ t = TUN(netdev);
ifr->ifr_flags |= IFF_TUN;
+ }
- if (!netdev->packet_info)
+ if (!t->packet_info)
ifr->ifr_flags |= IFF_NO_PI;
- if (netdev->one_queue)
+ if (t->one_queue)
ifr->ifr_flags |= IFF_ONE_QUEUE;
- if (netdev->multi_queue)
+ if (t->multi_queue)
ifr->ifr_flags |= IFF_MULTI_QUEUE;
strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
@@ -55,12 +58,16 @@ static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
_cleanup_close_ int fd;
+ TunTap *t = NULL;
const char *user;
const char *group;
uid_t uid;
gid_t gid;
int r = 0;
+ assert(netdev);
+ assert(ifr);
+
fd = open(TUN_DEV, O_RDWR);
if (fd < 0) {
log_error_netdev(netdev,
@@ -77,14 +84,21 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return r;
}
- if(netdev->user_name) {
+ if (netdev->kind == NETDEV_KIND_TAP)
+ t = TAP(netdev);
+ else
+ t = TUN(netdev);
+
+ assert(t);
- user = netdev->user_name;
+ if(t->user_name) {
+
+ user = t->user_name;
r = get_user_creds(&user, &uid, NULL, NULL, NULL);
if (r < 0) {
log_error("Cannot resolve user name %s: %s",
- netdev->user_name, strerror(-r));
+ t->user_name, strerror(-r));
return 0;
}
@@ -96,14 +110,14 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
}
- if(netdev->group_name) {
+ if(t->group_name) {
- group = netdev->group_name;
+ group = t->group_name;
r = get_group_creds(&group, &gid);
if (r < 0) {
log_error("Cannot resolve group name %s: %s",
- netdev->group_name, strerror(-r));
+ t->group_name, strerror(-r));
return 0;
}
@@ -129,34 +143,47 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
static int netdev_create_tuntap(NetDev *netdev) {
- struct ifreq ifr;
+ struct ifreq ifr = {};
int r;
- assert(netdev);
- assert(netdev->ifname);
-
- switch(netdev->kind) {
- case NETDEV_KIND_TUN:
- case NETDEV_KIND_TAP:
- break;
- default:
- return -ENOTSUP;
- }
-
r = netdev_fill_tuntap_message(netdev, &ifr);
if(r < 0)
return r;
- log_debug_netdev(netdev, "Creating tuntap netdev: %s",
- netdev_kind_to_string(netdev->kind));
-
return netdev_tuntap_add(netdev, &ifr);
}
+static void tuntap_done(NetDev *netdev) {
+ TunTap *t = NULL;
+
+ assert(netdev);
+
+ if (netdev->kind == NETDEV_KIND_TUN)
+ t = TUN(netdev);
+ else
+ t = TAP(netdev);
+
+ assert(t);
+
+ free(t->user_name);
+ t->user_name = NULL;
+
+ free(t->group_name);
+ t->group_name = NULL;
+}
+
const NetDevVTable tun_vtable = {
+ .object_size = sizeof(TunTap),
+ .sections = "Match\0NetDev\0Tun\0",
+ .done = tuntap_done,
.create = netdev_create_tuntap,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
};
const NetDevVTable tap_vtable = {
+ .object_size = sizeof(TunTap),
+ .sections = "Match\0NetDev\0Tap\0",
+ .done = tuntap_done,
.create = netdev_create_tuntap,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
};