On Mon, 30.06.14 22:23, Susant Sahani (sus...@redhat.com) wrote: > This patch introduces TUN/TAP device creation support > to networkd.
Please always also include the updates to the respective man pages that document these settings in these patches! THanks! > > Example conf to create a tap device: > > file: tap.netdev > ------------------ > [NetDev] > Name=tap-test > Kind=tap > > [Tap] > OneQueue=true > MultiQueue=true > PacketInfo=true > ------------------ > > Modifications: > > Added: > 1. file networkd-tuntap.c > 3. netdev kind NETDEV_KIND_TUN and NETDEV_KIND_TAP > 2. Tun and Tap Sections and config params to parse > conf and gperf conf parameters > > TODO: > 1. Add user(uid) group(gid) parameters > --- > Makefile.am | 1 + > src/network/networkd-netdev-gperf.gperf | 6 ++ > src/network/networkd-netdev.c | 34 ++++++++--- > src/network/networkd-tuntap.c | 101 > ++++++++++++++++++++++++++++++++ > src/network/networkd.h | 7 +++ > 5 files changed, 142 insertions(+), 7 deletions(-) > create mode 100644 src/network/networkd-tuntap.c > > diff --git a/Makefile.am b/Makefile.am > index bb85b2c..c947731 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -4514,6 +4514,7 @@ libsystemd_networkd_core_la_SOURCES = \ > src/network/networkd-tunnel.c \ > src/network/networkd-veth.c \ > src/network/networkd-vxlan.c \ > + src/network/networkd-tuntap.c \ > src/network/networkd-network.c \ > src/network/networkd-address.c \ > src/network/networkd-route.c \ > diff --git a/src/network/networkd-netdev-gperf.gperf > b/src/network/networkd-netdev-gperf.gperf > index 9125e1d..38133c8 100644 > --- a/src/network/networkd-netdev-gperf.gperf > +++ b/src/network/networkd-netdev-gperf.gperf > @@ -38,3 +38,9 @@ VXLAN.Group, config_parse_tunnel_address, > 0, > VXLAN.TOS, config_parse_unsigned, 0, > offsetof(NetDev, tos) > VXLAN.TTL, config_parse_unsigned, 0, > offsetof(NetDev, ttl) > VXLAN.MacLearning, config_parse_bool, 0, > offsetof(NetDev, learning) > +Tun.OneQueue, config_parse_bool, 0, > offsetof(NetDev, one_queue) > +Tun.MultiQueue, config_parse_bool, 0, > offsetof(NetDev, multi_queue) > +Tun.PacketInfo, config_parse_bool, 0, > offsetof(NetDev, packet_info) > +Tap.OneQueue, config_parse_bool, 0, > offsetof(NetDev, one_queue) > +Tap.MultiQueue, config_parse_bool, 0, > offsetof(NetDev, multi_queue) > +Tap.PacketInfo, config_parse_bool, 0, > offsetof(NetDev, packet_info) > diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c > index dcf7596..a25cb84 100644 > --- a/src/network/networkd-netdev.c > +++ b/src/network/networkd-netdev.c > @@ -41,7 +41,9 @@ static const char* const > netdev_kind_table[_NETDEV_KIND_MAX] = { > [NETDEV_KIND_GRE] = "gre", > [NETDEV_KIND_SIT] = "sit", > [NETDEV_KIND_VETH] = "veth", > - [NETDEV_KIND_VTI] = "vti" > + [NETDEV_KIND_VTI] = "vti", > + [NETDEV_KIND_TUN] = "tun", > + [NETDEV_KIND_TAP] = "tap", > }; > > DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); > @@ -221,6 +223,7 @@ static int netdev_enter_ready(NetDev *netdev) { > > return 0; > } > + > static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void > *userdata) { > NetDev *netdev = userdata; > int r; > @@ -521,11 +524,19 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message > *message) { > return -EINVAL; > } > > - if (!streq(kind, received_kind)) { > - log_error_netdev(netdev, "Received newlink with wrong KIND > %s, " > - "expected %s", received_kind, kind); > - netdev_enter_failed(netdev); > - return r; > + switch(netdev->kind) { > + case NETDEV_KIND_TUN: > + case NETDEV_KIND_TAP: > + break; > + default: > + if (!streq(kind, received_kind)) { > + log_error_netdev(netdev, > + "Received newlink with wrong KIND > %s, " > + "expected %s", received_kind, kind); > + netdev_enter_failed(netdev); > + return r; > + } > + break; > } > > netdev->ifindex = ifindex; > @@ -617,9 +628,10 @@ static int netdev_load_one(Manager *manager, const char > *filename) { > netdev->vxlanid = VXLAN_VID_MAX + 1; > netdev->tunnel_pmtudisc = true; > netdev->learning = true; > + netdev->packet_info = true; > > r = config_parse(NULL, filename, file, > - > "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0", > + > "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0", > config_item_perf_lookup, (void*) > network_netdev_gperf_lookup, > false, false, netdev); > if (r < 0) { > @@ -719,6 +731,14 @@ static int netdev_load_one(Manager *manager, const char > *filename) { > if (r < 0) > return r; > break; > + > + case NETDEV_KIND_TUN: > + case NETDEV_KIND_TAP: > + r = netdev_create_tuntap(netdev); > + if (r < 0) > + return r; > + break; > + > default: > break; > } > diff --git a/src/network/networkd-tuntap.c b/src/network/networkd-tuntap.c > new file mode 100644 > index 0000000..69a77f2 > --- /dev/null > +++ b/src/network/networkd-tuntap.c > @@ -0,0 +1,101 @@ > +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ > + > +/*** > + This file is part of systemd. > + > + Copyright 2014 Susant Sahani <sus...@redhat.com> > + > + systemd is free software; you can redistribute it and/or modify it > + under the terms of the GNU Lesser General Public License as published by > + the Free Software Foundation; either version 2.1 of the License, or > + (at your option) any later version. > + > + systemd is distributed in the hope that it will be useful, but > + WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public License > + along with systemd; If not, see <http://www.gnu.org/licenses/>. > +***/ > + > +#include <sys/ioctl.h> > +#include <net/if.h> > +#include <linux/if_tun.h> > + > +#include "networkd.h" > + > +#define TUN_DEV "/dev/net/tun" > + > + > +static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) { > + > + assert(netdev); > + assert(ifr); > + > + memset(ifr, 0, sizeof(*ifr)); > + > + if (netdev->kind != NETDEV_KIND_TAP) > + ifr->ifr_flags |= IFF_TUN; > + else > + ifr->ifr_flags |= IFF_TAP; > + > + if (netdev->packet_info) > + ifr->ifr_flags |= IFF_NO_PI; > + else > + ifr->ifr_flags &= ~IFF_NO_PI; > + > + if (netdev->one_queue) > + ifr->ifr_flags |= IFF_ONE_QUEUE; > + > + if (netdev->multi_queue) > + ifr->ifr_flags |= IFF_MULTI_QUEUE; > + > + strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1); > + > + return 0; > +} > + > +static int netdev_tuntap_add(struct ifreq *ifr) { > + _cleanup_close_ int fd; > + int r = 0; > + > + fd = open(TUN_DEV, O_RDWR); > + if (fd < 0) > + return -errno; > + > + r = ioctl(fd, TUNSETIFF, ifr); > + if (r < 0) > + return -errno; > + > + r = ioctl(fd, TUNSETPERSIST, 1); > + if (r < 0) > + return -errno; > + > + return r; > +} > + > +int netdev_create_tuntap(NetDev *netdev) { > + 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(&ifr); > +} > diff --git a/src/network/networkd.h b/src/network/networkd.h > index 11268de..f943a10 100644 > --- a/src/network/networkd.h > +++ b/src/network/networkd.h > @@ -81,6 +81,8 @@ typedef enum NetDevKind { > NETDEV_KIND_SIT, > NETDEV_KIND_VETH, > NETDEV_KIND_VTI, > + NETDEV_KIND_TUN, > + NETDEV_KIND_TAP, > _NETDEV_KIND_MAX, > _NETDEV_KIND_INVALID = -1 > } NetDevKind; > @@ -123,6 +125,10 @@ struct NetDev { > > bool tunnel_pmtudisc; > bool learning; > + bool one_queue; > + bool multi_queue; > + bool packet_info; > + > unsigned ttl; > unsigned tos; > struct in_addr local; > @@ -352,6 +358,7 @@ int netdev_enslave(NetDev *netdev, Link *link, > sd_rtnl_message_handler_t cb); > int netdev_create_tunnel(Link *link, sd_rtnl_message_handler_t callback); > int netdev_create_veth(NetDev *netdev, sd_rtnl_message_handler_t callback); > int netdev_create_vxlan(NetDev *netdev, Link *link, > sd_rtnl_message_handler_t callback); > +int netdev_create_tuntap(NetDev *netdev); > > const char *netdev_kind_to_string(NetDevKind d) _const_; > NetDevKind netdev_kind_from_string(const char *d) _pure_; Lennart -- Lennart Poettering, Red Hat _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel