X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-netdev-tuntap.c;h=eaf5df49718f14385372cf7b88f74ec73d72e390;hp=8f60461746e00cb250036346e6f3de3828ebb896;hb=6f44acfb48d4b58565d4c14714d082997389afd3;hpb=3be1d7e0c5bf60658d34eb6311d4e77c6803578c diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c index 8f6046174..eaf5df497 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,18 +58,20 @@ 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; + int r; + + assert(netdev); + assert(ifr); fd = open(TUN_DEV, O_RDWR); if (fd < 0) { - log_error_netdev(netdev, - "Failed to open tun dev: %s", - strerror(-r)); - return r; + log_error_netdev(netdev, "Failed to open tun dev: %m"); + return -errno; } r = ioctl(fd, TUNSETIFF, ifr); @@ -77,14 +82,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 +108,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; } @@ -125,38 +137,78 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) { return r; } - return r; + return 0; } 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; +} + +static int tuntap_verify(NetDev *netdev, const char *filename) { + TunTap *t = NULL; + + assert(netdev); + + if (netdev->kind == NETDEV_KIND_TUN) + t = TUN(netdev); + else + t = TAP(netdev); + + assert(t); + + if (netdev->mtu) { + log_warning_netdev(netdev, "MTU configured for %s, ignoring", + netdev_kind_to_string(netdev->kind)); + } + + if (netdev->mac) { + log_warning_netdev(netdev, "MAC configured for %s, ignoring", + netdev_kind_to_string(netdev->kind)); + } + + return 0; +} + const NetDevVTable tun_vtable = { + .object_size = sizeof(TunTap), + .sections = "Match\0NetDev\0Tun\0", + .config_verify = tuntap_verify, + .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", + .config_verify = tuntap_verify, + .done = tuntap_done, .create = netdev_create_tuntap, + .create_type = NETDEV_CREATE_INDEPENDENT, };