LCOV - code coverage report
Current view: top level - network - networkd-netdev-tuntap.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 0 79 0.0 %
Date: 2015-07-29 18:47:03 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :     This file is part of systemd.
       5             : 
       6             :     Copyright 2014 Susant Sahani <susant@redhat.com>
       7             : 
       8             :     systemd is free software; you can redistribute it and/or modify it
       9             :     under the terms of the GNU Lesser General Public License as published by
      10             :     the Free Software Foundation; either version 2.1 of the License, or
      11             :     (at your option) any later version.
      12             : 
      13             :     systemd is distributed in the hope that it will be useful, but
      14             :     WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :     Lesser General Public License for more details.
      17             : 
      18             :     You should have received a copy of the GNU Lesser General Public License
      19             :     along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include <sys/ioctl.h>
      23             : #include <net/if.h>
      24             : #include <linux/if_tun.h>
      25             : 
      26             : #include "networkd-netdev-tuntap.h"
      27             : 
      28             : #define TUN_DEV "/dev/net/tun"
      29             : 
      30           0 : static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
      31             :         TunTap *t;
      32             : 
      33           0 :         assert(netdev);
      34           0 :         assert(netdev->ifname);
      35           0 :         assert(ifr);
      36             : 
      37           0 :         if (netdev->kind == NETDEV_KIND_TAP) {
      38           0 :                 t = TAP(netdev);
      39           0 :                 ifr->ifr_flags |= IFF_TAP;
      40             :         } else {
      41           0 :                 t = TUN(netdev);
      42           0 :                 ifr->ifr_flags |= IFF_TUN;
      43             :         }
      44             : 
      45           0 :         if (!t->packet_info)
      46           0 :                 ifr->ifr_flags |= IFF_NO_PI;
      47             : 
      48           0 :         if (t->one_queue)
      49           0 :                 ifr->ifr_flags |= IFF_ONE_QUEUE;
      50             : 
      51           0 :         if (t->multi_queue)
      52           0 :                 ifr->ifr_flags |= IFF_MULTI_QUEUE;
      53             : 
      54           0 :         if (t->vnet_hdr)
      55           0 :                 ifr->ifr_flags |= IFF_VNET_HDR;
      56             : 
      57           0 :         strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
      58             : 
      59           0 :         return 0;
      60             : }
      61             : 
      62           0 : static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
      63           0 :         _cleanup_close_ int fd;
      64           0 :         TunTap *t = NULL;
      65             :         const char *user;
      66             :         const char *group;
      67             :         uid_t uid;
      68             :         gid_t gid;
      69             :         int r;
      70             : 
      71           0 :         assert(netdev);
      72           0 :         assert(ifr);
      73             : 
      74           0 :         fd = open(TUN_DEV, O_RDWR);
      75           0 :         if (fd < 0)
      76           0 :                 return log_netdev_error_errno(netdev, -errno,  "Failed to open tun dev: %m");
      77             : 
      78           0 :         r = ioctl(fd, TUNSETIFF, ifr);
      79           0 :         if (r < 0)
      80           0 :                 return log_netdev_error_errno(netdev, -errno, "TUNSETIFF failed on tun dev: %m");
      81             : 
      82           0 :         if (netdev->kind == NETDEV_KIND_TAP)
      83           0 :                 t = TAP(netdev);
      84             :         else
      85           0 :                 t = TUN(netdev);
      86             : 
      87           0 :         assert(t);
      88             : 
      89           0 :         if(t->user_name) {
      90             : 
      91           0 :                 user = t->user_name;
      92             : 
      93           0 :                 r = get_user_creds(&user, &uid, NULL, NULL, NULL);
      94           0 :                 if (r < 0)
      95           0 :                         return log_netdev_error_errno(netdev, r, "Cannot resolve user name %s: %m", t->user_name);
      96             : 
      97           0 :                 r = ioctl(fd, TUNSETOWNER, uid);
      98           0 :                 if (r < 0)
      99           0 :                         return log_netdev_error_errno(netdev, -errno, "TUNSETOWNER failed on tun dev: %m");
     100             :         }
     101             : 
     102           0 :         if (t->group_name) {
     103             : 
     104           0 :                 group = t->group_name;
     105             : 
     106           0 :                 r = get_group_creds(&group, &gid);
     107           0 :                 if (r < 0)
     108           0 :                         return log_netdev_error_errno(netdev, r, "Cannot resolve group name %s: %m", t->group_name);
     109             : 
     110           0 :                 r = ioctl(fd, TUNSETGROUP, gid);
     111           0 :                 if (r < 0)
     112           0 :                         return log_netdev_error_errno(netdev, -errno, "TUNSETGROUP failed on tun dev: %m");
     113             : 
     114             :         }
     115             : 
     116           0 :         r = ioctl(fd, TUNSETPERSIST, 1);
     117           0 :         if (r < 0)
     118           0 :                 return log_netdev_error_errno(netdev, -errno, "TUNSETPERSIST failed on tun dev: %m");
     119             : 
     120           0 :         return 0;
     121             : }
     122             : 
     123           0 : static int netdev_create_tuntap(NetDev *netdev) {
     124           0 :         struct ifreq ifr = {};
     125             :         int r;
     126             : 
     127           0 :         r = netdev_fill_tuntap_message(netdev, &ifr);
     128           0 :         if(r < 0)
     129           0 :                 return r;
     130             : 
     131           0 :         return netdev_tuntap_add(netdev, &ifr);
     132             : }
     133             : 
     134           0 : static void tuntap_done(NetDev *netdev) {
     135           0 :         TunTap *t = NULL;
     136             : 
     137           0 :         assert(netdev);
     138             : 
     139           0 :         if (netdev->kind == NETDEV_KIND_TUN)
     140           0 :                 t = TUN(netdev);
     141             :         else
     142           0 :                 t = TAP(netdev);
     143             : 
     144           0 :         assert(t);
     145             : 
     146           0 :         free(t->user_name);
     147           0 :         t->user_name = NULL;
     148             : 
     149           0 :         free(t->group_name);
     150           0 :         t->group_name = NULL;
     151           0 : }
     152             : 
     153           0 : static int tuntap_verify(NetDev *netdev, const char *filename) {
     154           0 :         assert(netdev);
     155             : 
     156           0 :         if (netdev->mtu)
     157           0 :                 log_netdev_warning(netdev, "MTU configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
     158             : 
     159           0 :         if (netdev->mac)
     160           0 :                 log_netdev_warning(netdev, "MAC configured for %s, ignoring", netdev_kind_to_string(netdev->kind));
     161             : 
     162           0 :         return 0;
     163             : }
     164             : 
     165             : const NetDevVTable tun_vtable = {
     166             :         .object_size = sizeof(TunTap),
     167             :         .sections = "Match\0NetDev\0Tun\0",
     168             :         .config_verify = tuntap_verify,
     169             :         .done = tuntap_done,
     170             :         .create = netdev_create_tuntap,
     171             :         .create_type = NETDEV_CREATE_INDEPENDENT,
     172             : };
     173             : 
     174             : const NetDevVTable tap_vtable = {
     175             :         .object_size = sizeof(TunTap),
     176             :         .sections = "Match\0NetDev\0Tap\0",
     177             :         .config_verify = tuntap_verify,
     178             :         .done = tuntap_done,
     179             :         .create = netdev_create_tuntap,
     180             :         .create_type = NETDEV_CREATE_INDEPENDENT,
     181             : };

Generated by: LCOV version 1.11