From 3be1d7e0c5bf60658d34eb6311d4e77c6803578c Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 6 Jul 2014 14:07:34 +0200 Subject: networkd: netdev - introduce vtable for netdev kinds Split each netdev kind into its own .h/.c. --- src/network/networkd-bond.c | 163 --------- src/network/networkd-bridge.c | 116 ------- src/network/networkd-dummy.c | 122 ------- src/network/networkd-link.c | 1 + src/network/networkd-macvlan.c | 160 --------- src/network/networkd-manager.c | 1 + src/network/networkd-netdev-bond.c | 129 ++++++++ src/network/networkd-netdev-bond.h | 43 +++ src/network/networkd-netdev-bridge.c | 84 +++++ src/network/networkd-netdev-bridge.h | 26 ++ src/network/networkd-netdev-dummy.c | 85 +++++ src/network/networkd-netdev-dummy.h | 26 ++ src/network/networkd-netdev-gperf.gperf | 5 +- src/network/networkd-netdev-macvlan.c | 130 ++++++++ src/network/networkd-netdev-macvlan.h | 40 +++ src/network/networkd-netdev-tunnel.c | 536 ++++++++++++++++++++++++++++++ src/network/networkd-netdev-tunnel.h | 29 ++ src/network/networkd-netdev-tuntap.c | 162 +++++++++ src/network/networkd-netdev-tuntap.h | 27 ++ src/network/networkd-netdev-veth.c | 143 ++++++++ src/network/networkd-netdev-veth.h | 26 ++ src/network/networkd-netdev-vlan.c | 133 ++++++++ src/network/networkd-netdev-vlan.h | 28 ++ src/network/networkd-netdev-vxlan.c | 142 ++++++++ src/network/networkd-netdev-vxlan.h | 28 ++ src/network/networkd-netdev.c | 184 +++++------ src/network/networkd-netdev.h | 170 ++++++++++ src/network/networkd-network.c | 1 + src/network/networkd-tunnel.c | 569 -------------------------------- src/network/networkd-tuntap.c | 155 --------- src/network/networkd-veth.c | 154 --------- src/network/networkd-vlan.c | 149 --------- src/network/networkd-vxlan.c | 165 --------- src/network/networkd.h | 161 --------- 34 files changed, 2084 insertions(+), 2009 deletions(-) delete mode 100644 src/network/networkd-bond.c delete mode 100644 src/network/networkd-bridge.c delete mode 100644 src/network/networkd-dummy.c delete mode 100644 src/network/networkd-macvlan.c create mode 100644 src/network/networkd-netdev-bond.c create mode 100644 src/network/networkd-netdev-bond.h create mode 100644 src/network/networkd-netdev-bridge.c create mode 100644 src/network/networkd-netdev-bridge.h create mode 100644 src/network/networkd-netdev-dummy.c create mode 100644 src/network/networkd-netdev-dummy.h create mode 100644 src/network/networkd-netdev-macvlan.c create mode 100644 src/network/networkd-netdev-macvlan.h create mode 100644 src/network/networkd-netdev-tunnel.c create mode 100644 src/network/networkd-netdev-tunnel.h create mode 100644 src/network/networkd-netdev-tuntap.c create mode 100644 src/network/networkd-netdev-tuntap.h create mode 100644 src/network/networkd-netdev-veth.c create mode 100644 src/network/networkd-netdev-veth.h create mode 100644 src/network/networkd-netdev-vlan.c create mode 100644 src/network/networkd-netdev-vlan.h create mode 100644 src/network/networkd-netdev-vxlan.c create mode 100644 src/network/networkd-netdev-vxlan.h create mode 100644 src/network/networkd-netdev.h delete mode 100644 src/network/networkd-tunnel.c delete mode 100644 src/network/networkd-tuntap.c delete mode 100644 src/network/networkd-veth.c delete mode 100644 src/network/networkd-vlan.c delete mode 100644 src/network/networkd-vxlan.c (limited to 'src') diff --git a/src/network/networkd-bond.c b/src/network/networkd-bond.c deleted file mode 100644 index 1e156775ee..0000000000 --- a/src/network/networkd-bond.c +++ /dev/null @@ -1,163 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include - -#include "conf-parser.h" -#include "sd-rtnl.h" -#include "networkd.h" -#include "missing.h" - -static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = { - [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr", - [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup", - [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor", - [NETDEV_BOND_MODE_BROADCAST] = "broadcast", - [NETDEV_BOND_MODE_802_3AD] = "802.3ad", - [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb", - [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb", -}; - -DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode"); - -static uint8_t bond_mode_to_kernel(BondMode mode) { - switch (mode) { - case NETDEV_BOND_MODE_BALANCE_RR: - return BOND_MODE_ROUNDROBIN; - case NETDEV_BOND_MODE_ACTIVE_BACKUP: - return BOND_MODE_ACTIVEBACKUP; - case NETDEV_BOND_MODE_BALANCE_XOR: - return BOND_MODE_XOR; - case NETDEV_BOND_MODE_BROADCAST: - return BOND_MODE_BROADCAST; - case NETDEV_BOND_MODE_802_3AD: - return BOND_MODE_8023AD; - case NETDEV_BOND_MODE_BALANCE_TLB: - return BOND_MODE_TLB; - case NETDEV_BOND_MODE_BALANCE_ALB: - return BOND_MODE_ALB; - default: - return (uint8_t) -1; - } -} - -static int netdev_fill_bond_rtnl_message(NetDev *netdev, sd_rtnl_message *m) { - int r; - - assert(m); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->bond_mode != _NETDEV_BOND_MODE_INVALID) { - r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE, - bond_mode_to_kernel(netdev->bond_mode)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_BOND_MODE attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_bond(NetDev *netdev, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(netdev->kind == NETDEV_KIND_BOND); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - r = netdev_fill_bond_rtnl_message(netdev, m); - if(r < 0) - return r; - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - netdev_ref(netdev); - - log_debug_netdev(netdev, "Creating bond netdev: %s", - netdev_kind_to_string(netdev->kind)); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-bridge.c b/src/network/networkd-bridge.c deleted file mode 100644 index 4c106eed32..0000000000 --- a/src/network/networkd-bridge.c +++ /dev/null @@ -1,116 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Tom Gundersen - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include - -#include "sd-rtnl.h" -#include "networkd.h" -#include "missing.h" - -static int netdev_fill_bridge_rtnl_message(NetDev *netdev, sd_rtnl_message *m) { - int r; - - assert(m); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_bridge(NetDev *netdev, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(netdev->kind == NETDEV_KIND_BRIDGE); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - r = netdev_fill_bridge_rtnl_message(netdev, m); - if(r < 0) - return r; - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - netdev_ref(netdev); - - log_debug_netdev(netdev, "Creating bridge netdev."); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-dummy.c b/src/network/networkd-dummy.c deleted file mode 100644 index 80fe41b0b7..0000000000 --- a/src/network/networkd-dummy.c +++ /dev/null @@ -1,122 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - Copyright 2014 Tom Gundersen - - 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 . -***/ - -#include -#include -#include -#include - -#include "sd-rtnl.h" -#include "networkd.h" - - -static int netdev_fill_dummy_rtnl_message(NetDev *netdev, sd_rtnl_message *m) { - int r; - - assert(netdev); - assert(m); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_dummy(NetDev *netdev, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - if(netdev->kind != NETDEV_KIND_DUMMY) - return -ENOTSUP; - - r = netdev_fill_dummy_rtnl_message(netdev, m); - if(r < 0) - return r; - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - netdev_ref(netdev); - - log_debug_netdev(netdev, "Creating dummy netdev."); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ccf818115b..0947b0c905 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -24,6 +24,7 @@ #include #include "networkd.h" +#include "networkd-netdev.h" #include "libudev-private.h" #include "udev-util.h" #include "util.h" diff --git a/src/network/networkd-macvlan.c b/src/network/networkd-macvlan.c deleted file mode 100644 index 7c234264ac..0000000000 --- a/src/network/networkd-macvlan.c +++ /dev/null @@ -1,160 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen - - 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 . -***/ - -#include - -#include "networkd.h" -#include "network-internal.h" -#include "conf-parser.h" -#include "list.h" - -static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = { - [NETDEV_MACVLAN_MODE_PRIVATE] = "private", - [NETDEV_MACVLAN_MODE_VEPA] = "vepa", - [NETDEV_MACVLAN_MODE_BRIDGE] = "bridge", - [NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru", -}; - -DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode); -DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); - -int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - const char *kind; - int r; - - assert(netdev); - assert(netdev->kind == NETDEV_KIND_MACVLAN); - assert(link); - assert(callback); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - if (link) { - r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINK attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->mtu) { - r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(req, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not open IFLA_LINKINFO container: %s", - strerror(-r)); - return r; - } - - kind = netdev_kind_to_string(netdev->kind); - if (!kind) { - log_error_netdev(netdev, "Invalid kind"); - return -EINVAL; - } - - r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind); - if (r < 0) { - log_error_netdev(netdev, - "Could not open IFLA_INFO_DATA container: %s", - strerror(-r)); - return r; - } - - if (netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) { - r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, netdev->macvlan_mode); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MACVLAN_MODE attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_error_netdev(netdev, - "Could not close IFLA_INFO_DATA container %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_error_netdev(netdev, - "Could not close IFLA_LINKINFO container %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - link_ref(link); - - log_debug_netdev(netdev, "creating netdev"); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 46b803fee5..4d105248f0 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -25,6 +25,7 @@ #include "conf-parser.h" #include "path-util.h" #include "networkd.h" +#include "networkd-netdev.h" #include "network-internal.h" #include "libudev-private.h" #include "udev-util.h" diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c new file mode 100644 index 0000000000..89e3965d16 --- /dev/null +++ b/src/network/networkd-netdev-bond.c @@ -0,0 +1,129 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include + +#include "conf-parser.h" +#include "sd-rtnl.h" +#include "networkd-netdev-bond.h" +#include "missing.h" + +static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = { + [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr", + [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup", + [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor", + [NETDEV_BOND_MODE_BROADCAST] = "broadcast", + [NETDEV_BOND_MODE_802_3AD] = "802.3ad", + [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb", + [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb", +}; + +DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode); +DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode"); + +static uint8_t bond_mode_to_kernel(BondMode mode) { + switch (mode) { + case NETDEV_BOND_MODE_BALANCE_RR: + return BOND_MODE_ROUNDROBIN; + case NETDEV_BOND_MODE_ACTIVE_BACKUP: + return BOND_MODE_ACTIVEBACKUP; + case NETDEV_BOND_MODE_BALANCE_XOR: + return BOND_MODE_XOR; + case NETDEV_BOND_MODE_BROADCAST: + return BOND_MODE_BROADCAST; + case NETDEV_BOND_MODE_802_3AD: + return BOND_MODE_8023AD; + case NETDEV_BOND_MODE_BALANCE_TLB: + return BOND_MODE_TLB; + case NETDEV_BOND_MODE_BALANCE_ALB: + return BOND_MODE_ALB; + default: + return (uint8_t) -1; + } +} + +static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) { + int r; + + assert(m); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->bond_mode != _NETDEV_BOND_MODE_INVALID) { + r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE, + bond_mode_to_kernel(netdev->bond_mode)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_BOND_MODE attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +const NetDevVTable bond_vtable = { + .fill_message_create = netdev_bond_fill_message_create, + .enslave = netdev_enslave, +}; diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h new file mode 100644 index 0000000000..03ef08167c --- /dev/null +++ b/src/network/networkd-netdev-bond.h @@ -0,0 +1,43 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable bond_vtable; + +typedef enum BondMode { + NETDEV_BOND_MODE_BALANCE_RR, + NETDEV_BOND_MODE_ACTIVE_BACKUP, + NETDEV_BOND_MODE_BALANCE_XOR, + NETDEV_BOND_MODE_BROADCAST, + NETDEV_BOND_MODE_802_3AD, + NETDEV_BOND_MODE_BALANCE_TLB, + NETDEV_BOND_MODE_BALANCE_ALB, + _NETDEV_BOND_MODE_MAX, + _NETDEV_BOND_MODE_INVALID = -1 +} BondMode; + +const char *bond_mode_to_string(BondMode d) _const_; +BondMode bond_mode_from_string(const char *d) _pure_; + +int config_parse_bond_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c new file mode 100644 index 0000000000..9a8bf57ee6 --- /dev/null +++ b/src/network/networkd-netdev-bridge.c @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include + +#include "sd-rtnl.h" +#include "networkd-netdev-bridge.h" +#include "missing.h" + +static int netdev_bridge_fill_message_create(NetDev *netdev, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->ifname); + assert(m); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "bridge"); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +const NetDevVTable bridge_vtable = { + .fill_message_create = netdev_bridge_fill_message_create, + .enslave = netdev_enslave, +}; diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h new file mode 100644 index 0000000000..4d971c62e0 --- /dev/null +++ b/src/network/networkd-netdev-bridge.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable bridge_vtable; diff --git a/src/network/networkd-netdev-dummy.c b/src/network/networkd-netdev-dummy.c new file mode 100644 index 0000000000..100dbbf781 --- /dev/null +++ b/src/network/networkd-netdev-dummy.c @@ -0,0 +1,85 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Susant Sahani + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#include +#include +#include +#include + +#include "sd-rtnl.h" +#include "networkd-netdev-dummy.h" + +static int netdev_dummy_fill_message_create(NetDev *netdev, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->ifname); + assert(m); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "dummy"); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +const NetDevVTable dummy_vtable = { + .fill_message_create = netdev_dummy_fill_message_create, +}; diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h new file mode 100644 index 0000000000..dcbd3cc025 --- /dev/null +++ b/src/network/networkd-netdev-dummy.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable dummy_vtable; diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index a698ea8c4d..090dfb35eb 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -1,7 +1,10 @@ %{ #include #include "conf-parser.h" -#include "networkd.h" +#include "networkd-netdev.h" +#include "networkd-netdev-tunnel.h" +#include "networkd-netdev-bond.h" +#include "networkd-netdev-macvlan.h" #include "network-internal.h" %} struct ConfigPerfItem; diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/networkd-netdev-macvlan.c new file mode 100644 index 0000000000..9eb66ffb71 --- /dev/null +++ b/src/network/networkd-netdev-macvlan.c @@ -0,0 +1,130 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Tom Gundersen + + 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 . +***/ + +#include + +#include "networkd-netdev-macvlan.h" +#include "network-internal.h" +#include "conf-parser.h" +#include "list.h" + +static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = { + [NETDEV_MACVLAN_MODE_PRIVATE] = "private", + [NETDEV_MACVLAN_MODE_VEPA] = "vepa", + [NETDEV_MACVLAN_MODE_BRIDGE] = "bridge", + [NETDEV_MACVLAN_MODE_PASSTHRU] = "passthru", +}; + +DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode); +DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); + +static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { + int r; + + assert(netdev); + assert(netdev->kind == NETDEV_KIND_MACVLAN); + assert(link); + assert(netdev->ifname); + + r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->mtu) { + r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(req, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not open IFLA_LINKINFO container: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "macvlan"); + if (r < 0) { + log_error_netdev(netdev, + "Could not open IFLA_INFO_DATA container: %s", + strerror(-r)); + return r; + } + + if (netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) { + r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, netdev->macvlan_mode); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MACVLAN_MODE attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_close_container(req); + if (r < 0) { + log_error_netdev(netdev, + "Could not close IFLA_INFO_DATA container %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(req); + if (r < 0) { + log_error_netdev(netdev, + "Could not close IFLA_LINKINFO container %s", + strerror(-r)); + return r; + } + + return 0; +} + +const NetDevVTable macvlan_vtable = { + .fill_message_create_on_link = netdev_macvlan_fill_message_create, +}; diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h new file mode 100644 index 0000000000..ea268cc270 --- /dev/null +++ b/src/network/networkd-netdev-macvlan.h @@ -0,0 +1,40 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable macvlan_vtable; + +typedef enum MacVlanMode { + NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE, + NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA, + NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE, + NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU, + _NETDEV_MACVLAN_MODE_MAX, + _NETDEV_MACVLAN_MODE_INVALID = -1 +} MacVlanMode; + +const char *macvlan_mode_to_string(MacVlanMode d) _const_; +MacVlanMode macvlan_mode_from_string(const char *d) _pure_; + +int config_parse_macvlan_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c new file mode 100644 index 0000000000..8acb74688d --- /dev/null +++ b/src/network/networkd-netdev-tunnel.c @@ -0,0 +1,536 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include +#include +#include + +#include "sd-rtnl.h" +#include "networkd-netdev-tunnel.h" +#include "network-internal.h" +#include "util.h" +#include "missing.h" +#include "conf-parser.h" + +static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->kind == NETDEV_KIND_IPIP); + assert(netdev->ifname); + assert(netdev->manager); + assert(netdev->manager->rtnl); + assert(link); + assert(m); + assert(netdev->family == AF_INET); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->mtu) { + r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LOCAL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_REMOTE attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_TTL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->kind == NETDEV_KIND_SIT); + assert(netdev->ifname); + assert(netdev->manager); + assert(netdev->manager->rtnl); + assert(link); + assert(m); + assert(netdev->family == AF_INET); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->mtu) { + r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LOCAL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_REMOTE attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_TTL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->kind == NETDEV_KIND_GRE); + assert(netdev->ifname); + assert(netdev->manager); + assert(netdev->manager->rtnl); + assert(link); + assert(m); + assert(netdev->family == AF_INET); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->mtu) { + r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_GRE_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_GRE_LOCAL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_GRE_REMOTE attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_GRE_TTL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_GRE_TOS attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->kind == NETDEV_KIND_VTI); + assert(netdev->ifname); + assert(netdev->manager); + assert(netdev->manager->rtnl); + assert(link); + assert(m); + assert(netdev->family == AF_INET); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->mtu) { + r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, + netdev_kind_to_string(netdev->kind)); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LOCAL attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_REMOTE attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_tunnel_verify(NetDev *netdev, const char *filename) { + assert(netdev); + assert(filename); + + if (netdev->local.in.s_addr == INADDR_ANY) { + log_warning("Tunnel without local address configured in %s. Ignoring", filename); + return -EINVAL; + } + + if (netdev->remote.in.s_addr == INADDR_ANY) { + log_warning("Tunnel without remote address configured in %s. Ignoring", filename); + return -EINVAL; + } + + if (netdev->family != AF_INET) { + log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename); + return -EINVAL; + } + + return 0; +} + +int config_parse_tunnel_address(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + NetDev *n = userdata; + union in_addr_union *addr = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = net_parse_inaddr(rvalue, &n->family, addr); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "Tunnel address is invalid, ignoring assignment: %s", rvalue); + return 0; + } + + return 0; +} + +const NetDevVTable ipip_vtable = { + .fill_message_create_on_link = netdev_ipip_fill_message_create, + .config_verify = netdev_tunnel_verify, +}; + +const NetDevVTable sit_vtable = { + .fill_message_create_on_link = netdev_sit_fill_message_create, + .config_verify = netdev_tunnel_verify, +}; + +const NetDevVTable vti_vtable = { + .fill_message_create_on_link = netdev_vti_fill_message_create, + .config_verify = netdev_tunnel_verify, +}; + +const NetDevVTable gre_vtable = { + .fill_message_create_on_link = netdev_gre_fill_message_create, + .config_verify = netdev_tunnel_verify, +}; diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h new file mode 100644 index 0000000000..b30204b76b --- /dev/null +++ b/src/network/networkd-netdev-tunnel.h @@ -0,0 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable ipip_vtable; +extern const NetDevVTable sit_vtable; +extern const NetDevVTable vti_vtable; +extern const NetDevVTable gre_vtable; diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c new file mode 100644 index 0000000000..8f60461746 --- /dev/null +++ b/src/network/networkd-netdev-tuntap.c @@ -0,0 +1,162 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include + +#include "networkd-netdev-tuntap.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_TAP; + else + ifr->ifr_flags |= IFF_TUN; + + if (!netdev->packet_info) + 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(NetDev *netdev, struct ifreq *ifr) { + _cleanup_close_ int fd; + const char *user; + const char *group; + uid_t uid; + gid_t gid; + int r = 0; + + fd = open(TUN_DEV, O_RDWR); + if (fd < 0) { + log_error_netdev(netdev, + "Failed to open tun dev: %s", + strerror(-r)); + return r; + } + + r = ioctl(fd, TUNSETIFF, ifr); + if (r < 0) { + log_error_netdev(netdev, + "TUNSETIFF failed on tun dev: %s", + strerror(-r)); + return r; + } + + if(netdev->user_name) { + + user = netdev->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)); + return 0; + } + + r = ioctl(fd, TUNSETOWNER, uid); + if ( r < 0) { + log_error_netdev(netdev, + "TUNSETOWNER failed on tun dev: %s", + strerror(-r)); + } + } + + if(netdev->group_name) { + + group = netdev->group_name; + + r = get_group_creds(&group, &gid); + if (r < 0) { + log_error("Cannot resolve group name %s: %s", + netdev->group_name, strerror(-r)); + return 0; + } + + r = ioctl(fd, TUNSETGROUP, gid); + if( r < 0) { + log_error_netdev(netdev, + "TUNSETGROUP failed on tun dev: %s", + strerror(-r)); + return r; + } + + } + + r = ioctl(fd, TUNSETPERSIST, 1); + if (r < 0) { + log_error_netdev(netdev, + "TUNSETPERSIST failed on tun dev: %s", + strerror(-r)); + return r; + } + + return r; +} + +static 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(netdev, &ifr); +} + +const NetDevVTable tun_vtable = { + .create = netdev_create_tuntap, +}; + +const NetDevVTable tap_vtable = { + .create = netdev_create_tuntap, +}; diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h new file mode 100644 index 0000000000..2b6e48f79b --- /dev/null +++ b/src/network/networkd-netdev-tuntap.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable tun_vtable; +extern const NetDevVTable tap_vtable; diff --git a/src/network/networkd-netdev-veth.c b/src/network/networkd-netdev-veth.c new file mode 100644 index 0000000000..aca8022f00 --- /dev/null +++ b/src/network/networkd-netdev-veth.c @@ -0,0 +1,143 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include +#include + +#include "sd-rtnl.h" +#include "networkd-netdev-veth.h" + +static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(netdev->ifname); + assert(m); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth"); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container(m, VETH_INFO_PEER); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IPTUN_LINK attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->ifname_peer) { + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname_peer); + if (r < 0) { + log_error("Failed to add netlink interface name: %s", strerror(-r)); + return r; + } + } + + if (netdev->mac_peer) { + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac_peer); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_veth_verify(NetDev *netdev, const char *filename) { + int r; + + assert(netdev); + assert(filename); + + if (!netdev->ifname_peer) { + log_warning("Veth NetDev without peer name configured in %s. Ignoring", + filename); + return -EINVAL; + } + + if (!netdev->mac_peer) { + r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer); + if (r < 0) { + log_warning("Failed to generate predictable MAC address for %s. Ignoring", + netdev->ifname_peer); + return -EINVAL; + } + } + + return 0; +} + +const NetDevVTable veth_vtable = { + .fill_message_create = netdev_veth_fill_message_create, + .config_verify = netdev_veth_verify, +}; diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h new file mode 100644 index 0000000000..93dcdfa1a4 --- /dev/null +++ b/src/network/networkd-netdev-veth.h @@ -0,0 +1,26 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +extern const NetDevVTable veth_vtable; diff --git a/src/network/networkd-netdev-vlan.c b/src/network/networkd-netdev-vlan.c new file mode 100644 index 0000000000..20d0fd5e49 --- /dev/null +++ b/src/network/networkd-netdev-vlan.c @@ -0,0 +1,133 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Tom Gundersen + + 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 . +***/ + +#include + +#include "networkd-netdev-vlan.h" +#include "network-internal.h" +#include "list.h" + +static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) { + int r; + + assert(netdev); + assert(netdev->ifname); + assert(netdev->kind == NETDEV_KIND_VLAN); + assert(link); + assert(req); + + r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINK attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->mtu) { + r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_MTU attribute: %s", + strerror(-r)); + return r; + } + } + + if (netdev->mac) { + r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac); + if (r < 0) { + log_error_netdev(netdev, + "Colud not append IFLA_ADDRESS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_open_container(req, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not open IFLA_LINKINFO container: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "vlan"); + if (r < 0) { + log_error_netdev(netdev, + "Could not open IFLA_INFO_DATA container: %s", + strerror(-r)); + return r; + } + + if (netdev->vlanid <= VLANID_MAX) { + r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VLAN_ID attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_close_container(req); + if (r < 0) { + log_error_netdev(netdev, + "Could not close IFLA_INFO_DATA container %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(req); + if (r < 0) { + log_error_netdev(netdev, + "Could not close IFLA_LINKINFO container %s", + strerror(-r)); + return r; + } + + return 0; +} + +static int netdev_vlan_verify(NetDev *netdev, const char *filename) { + assert(netdev); + assert(filename); + + if (netdev->vlanid > VLANID_MAX) { + log_warning("VLAN without valid Id configured in %s. Ignoring", filename); + return -EINVAL; + } + + return 0; +} + +const NetDevVTable vlan_vtable = { + .fill_message_create_on_link = netdev_vlan_fill_message_create, + .config_verify = netdev_vlan_verify, +}; diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h new file mode 100644 index 0000000000..95f630f190 --- /dev/null +++ b/src/network/networkd-netdev-vlan.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +#define VLANID_MAX 4094 + +extern const NetDevVTable vlan_vtable; diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c new file mode 100644 index 0000000000..38692c687c --- /dev/null +++ b/src/network/networkd-netdev-vxlan.c @@ -0,0 +1,142 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Susant Sahani + + 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 . +***/ + +#include +#include +#include + +#include "sd-rtnl.h" +#include "networkd-netdev-vxlan.h" +#include "missing.h" + +static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) { + int r; + + assert(netdev); + assert(link); + assert(link->ifname); + assert(m); + + r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_IFNAME, attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "vxlan"); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_INFO_DATA attribute: %s", + strerror(-r)); + return r; + } + + if (netdev->vlanid <= VXLAN_VID_MAX) { + r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, netdev->vxlanid); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_ID attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &netdev->group.in); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_GROUP attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_LINK attribute: %s", + strerror(-r)); + return r; + } + + if(netdev->ttl) { + r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, netdev->ttl); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_TTL attribute: %s", + strerror(-r)); + return r; + } + } + + if(netdev->tos) { + r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, netdev->tos); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_TOS attribute: %s", + strerror(-r)); + return r; + } + } + + r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, netdev->learning); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_VXLAN_LEARNING attribute: %s", + strerror(-r)); + return r; + } + + r = sd_rtnl_message_close_container(m); + if (r < 0) { + log_error_netdev(netdev, + "Could not append IFLA_LINKINFO attribute: %s", + strerror(-r)); + return r; + } + + return r; +} + +static int netdev_vxlan_verify(NetDev *netdev, const char *filename) { + assert(netdev); + assert(filename); + + if (netdev->vxlanid > VXLAN_VID_MAX) { + log_warning("VXLAN without valid Id configured in %s. Ignoring", filename); + return -EINVAL; + } + + return 0; +} + +const NetDevVTable vxlan_vtable = { + .fill_message_create_on_link = netdev_vxlan_fill_message_create, + .config_verify = netdev_vxlan_verify, +}; diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h new file mode 100644 index 0000000000..a2de2713cc --- /dev/null +++ b/src/network/networkd-netdev-vxlan.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd-netdev.h" + +#define VXLAN_VID_MAX (1u << 24) - 1 + +extern const NetDevVTable vxlan_vtable; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index ac47c03fee..a97831760e 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -21,7 +21,16 @@ #include -#include "networkd.h" +#include "networkd-netdev.h" +#include "networkd-netdev-bridge.h" +#include "networkd-netdev-bond.h" +#include "networkd-netdev-vlan.h" +#include "networkd-netdev-macvlan.h" +#include "networkd-netdev-vxlan.h" +#include "networkd-netdev-tunnel.h" +#include "networkd-netdev-veth.h" +#include "networkd-netdev-dummy.h" +#include "networkd-netdev-tuntap.h" #include "network-internal.h" #include "path-util.h" #include "conf-files.h" @@ -29,6 +38,22 @@ #include "list.h" #include "siphash24.h" +const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { + [NETDEV_KIND_BRIDGE] = &bridge_vtable, + [NETDEV_KIND_BOND] = &bond_vtable, + [NETDEV_KIND_VLAN] = &vlan_vtable, + [NETDEV_KIND_MACVLAN] = &macvlan_vtable, + [NETDEV_KIND_VXLAN] = &vxlan_vtable, + [NETDEV_KIND_IPIP] = &ipip_vtable, + [NETDEV_KIND_GRE] = &gre_vtable, + [NETDEV_KIND_SIT] = &sit_vtable, + [NETDEV_KIND_VTI] = &vti_vtable, + [NETDEV_KIND_VETH] = &veth_vtable, + [NETDEV_KIND_DUMMY] = &dummy_vtable, + [NETDEV_KIND_TUN] = &tun_vtable, + [NETDEV_KIND_TAP] = &tap_vtable, +}; + static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_BRIDGE] = "bridge", [NETDEV_KIND_BOND] = "bond", @@ -246,7 +271,7 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda return 1; } -static int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { +int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { int r; assert(netdev); @@ -276,27 +301,39 @@ static int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t /* the callback must be called, possibly after a timeout, as otherwise the Link will hang */ int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { + int r; assert(netdev); + assert(netdev->manager); + assert(netdev->manager->rtnl); + assert(NETDEV_VTABLE(netdev)); - switch(netdev->kind) { - case NETDEV_KIND_VLAN: - return netdev_create_vlan(netdev, link, callback); - case NETDEV_KIND_MACVLAN: - return netdev_create_macvlan(netdev, link, callback); - case NETDEV_KIND_VXLAN: - return netdev_create_vxlan(netdev, link, callback); - case NETDEV_KIND_IPIP: - case NETDEV_KIND_GRE: - case NETDEV_KIND_SIT: - case NETDEV_KIND_VTI: - return netdev_create_tunnel(netdev, link, callback); - case NETDEV_KIND_BRIDGE: - case NETDEV_KIND_BOND: - return netdev_enslave(netdev, link, callback); - default: - assert_not_reached("Enslaving by invalid netdev kind"); - } + if (NETDEV_VTABLE(netdev)->fill_message_create_on_link) { + _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; + + r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, + RTM_NEWLINK, 0); + if (r < 0) { + log_error_netdev(netdev, + "Could not allocate RTM_SETLINK message: %s", + strerror(-r)); + return r; + } + + NETDEV_VTABLE(netdev)->fill_message_create_on_link(netdev, link, req); + + r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL); + if (r < 0) { + log_error_netdev(netdev, + "Could not send rtnetlink message: %s", strerror(-r)); + return r; + } + + link_ref(link); + } else if (NETDEV_VTABLE(netdev)->enslave) { + return NETDEV_VTABLE(netdev)->enslave(netdev, link, callback); + } else + assert_not_reached("Joining link to netdev of invalid kind"); return 0; } @@ -406,7 +443,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) { #define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48) -static int netdev_get_mac(const char *ifname, struct ether_addr **ret) { +int netdev_get_mac(const char *ifname, struct ether_addr **ret) { _cleanup_free_ struct ether_addr *mac = NULL; uint8_t result[8]; size_t l, sz; @@ -502,63 +539,16 @@ static int netdev_load_one(Manager *manager, const char *filename) { NULL, NULL, NULL, NULL, NULL, NULL) <= 0) return 0; - /* verify configuration */ - switch (netdev->kind) { - case _NETDEV_KIND_INVALID: - log_warning("NetDev without Kind configured in %s. Ignoring", filename); + if (!NETDEV_VTABLE(netdev)) { + log_warning("NetDev with invalid Kind configured in %s. Igonring", filename); return 0; + } - case NETDEV_KIND_VLAN: - if (netdev->vlanid > VLANID_MAX) { - log_warning("VLAN without valid Id configured in %s. Ignoring", filename); - return 0; - } - break; - - case NETDEV_KIND_VXLAN: - if (netdev->vxlanid > VXLAN_VID_MAX) { - log_warning("VXLAN without valid Id configured in %s. Ignoring", filename); - return 0; - } - break; - - case NETDEV_KIND_IPIP: - case NETDEV_KIND_GRE: - case NETDEV_KIND_SIT: - case NETDEV_KIND_VTI: - if (netdev->local.in.s_addr == INADDR_ANY) { - log_warning("Tunnel without local address configured in %s. Ignoring", filename); - return 0; - } - if (netdev->remote.in.s_addr == INADDR_ANY) { - log_warning("Tunnel without remote address configured in %s. Ignoring", filename); - return 0; - } - if (netdev->family != AF_INET) { - log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename); - return 0; - } - break; - - case NETDEV_KIND_VETH: - if (!netdev->ifname_peer) { - log_warning("Veth NetDev without peer name configured " - "in %s. Ignoring", filename); + /* verify configuration */ + if (NETDEV_VTABLE(netdev)->config_verify) { + r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename); + if (r < 0) return 0; - } - - if (!netdev->mac_peer) { - r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer); - if (r < 0) { - log_error("Failed to generate predictable MAC address for %s", - netdev->ifname_peer); - return r; - } - } - break; - - default: - break; } if (!netdev->ifname) { @@ -604,36 +594,42 @@ static int netdev_load_one(Manager *manager, const char *filename) { LIST_HEAD_INIT(netdev->callbacks); + log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind)); + /* create netdev */ - switch (netdev->kind) { - case NETDEV_KIND_VETH: - r = netdev_create_veth(netdev, netdev_create_handler); - if (r < 0) + if (NETDEV_VTABLE(netdev)->fill_message_create) { + _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; + + r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); + if (r < 0) { + log_error_netdev(netdev, + "Could not allocate RTM_NEWLINK message: %s", + strerror(-r)); return r; + } - break; - case NETDEV_KIND_DUMMY: - r = netdev_create_dummy(netdev, netdev_create_handler); + r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, m); if (r < 0) return r; - break; - case NETDEV_KIND_BRIDGE: - r = netdev_create_bridge(netdev, netdev_create_handler); - if (r < 0) + r = sd_rtnl_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL); + if (r < 0) { + log_error_netdev(netdev, + "Could not send rtnetlink message: %s", strerror(-r)); return r; - break; - case NETDEV_KIND_BOND: - r = netdev_create_bond(netdev, netdev_create_handler); + } + + netdev_ref(netdev); + + log_debug_netdev(netdev, "creating"); + + netdev->state = NETDEV_STATE_CREATING; + } else if (NETDEV_VTABLE(netdev)->create) { + r = NETDEV_VTABLE(netdev)->create(netdev); if (r < 0) return r; - break; - default: - break; } - log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind)); - netdev = NULL; return 0; diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h new file mode 100644 index 0000000000..a523522887 --- /dev/null +++ b/src/network/networkd-netdev.h @@ -0,0 +1,170 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2013 Tom Gundersen + + 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 . +***/ + +#pragma once + +#include "networkd.h" +#include "hashmap.h" +#include "list.h" +#include "set.h" +#include "condition-util.h" +#include "in-addr-util.h" + +typedef struct NetDevVTable NetDevVTable; + +typedef struct netdev_join_callback netdev_join_callback; + +struct netdev_join_callback { + sd_rtnl_message_handler_t callback; + Link *link; + + LIST_FIELDS(netdev_join_callback, callbacks); +}; + +typedef enum NetDevKind { + NETDEV_KIND_BRIDGE, + NETDEV_KIND_BOND, + NETDEV_KIND_VLAN, + NETDEV_KIND_MACVLAN, + NETDEV_KIND_VXLAN, + NETDEV_KIND_IPIP, + NETDEV_KIND_GRE, + NETDEV_KIND_SIT, + NETDEV_KIND_VETH, + NETDEV_KIND_VTI, + NETDEV_KIND_DUMMY, + NETDEV_KIND_TUN, + NETDEV_KIND_TAP, + _NETDEV_KIND_MAX, + _NETDEV_KIND_INVALID = -1 +} NetDevKind; + +typedef enum NetDevState { + NETDEV_STATE_FAILED, + NETDEV_STATE_CREATING, + NETDEV_STATE_READY, + NETDEV_STATE_LINGER, + _NETDEV_STATE_MAX, + _NETDEV_STATE_INVALID = -1, +} NetDevState; + +struct NetDev { + Manager *manager; + + int n_ref; + + char *filename; + + Condition *match_host; + Condition *match_virt; + Condition *match_kernel; + Condition *match_arch; + + char *description; + char *ifname; + char *ifname_peer; + char *user_name; + char *group_name; + size_t mtu; + struct ether_addr *mac; + struct ether_addr *mac_peer; + NetDevKind kind; + + uint64_t vlanid; + uint64_t vxlanid; + int32_t macvlan_mode; + int32_t bond_mode; + + int ifindex; + NetDevState state; + + bool tunnel_pmtudisc; + bool learning; + bool one_queue; + bool multi_queue; + bool packet_info; + + unsigned ttl; + unsigned tos; + unsigned char family; + union in_addr_union local; + union in_addr_union remote; + union in_addr_union group; + + LIST_HEAD(netdev_join_callback, callbacks); +}; + +struct NetDevVTable { + /* fill in message to create netdev */ + int (*fill_message_create)(NetDev *netdev, sd_rtnl_message *message); + + /* fill in message to create netdev on top of a given link */ + int (*fill_message_create_on_link)(NetDev *netdev, Link *link, sd_rtnl_message *message); + + /* fill in message to enslave link by netdev */ + int (*enslave)(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback); + + /* create netdev, if not done via rtnl */ + int (*create)(NetDev *netdev); + + /* verify that compulsory configuration options were specified */ + int (*config_verify)(NetDev *netdev, const char *filename); +}; + +extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; + +#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind] + +int netdev_load(Manager *manager); +void netdev_drop(NetDev *netdev); + +NetDev *netdev_unref(NetDev *netdev); +NetDev *netdev_ref(NetDev *netdev); + +DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); +#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp) + +int netdev_get(Manager *manager, const char *name, NetDev **ret); +int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink); +int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback); +int netdev_get_mac(const char *ifname, struct ether_addr **ret); +int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb); + +const char *netdev_kind_to_string(NetDevKind d) _const_; +NetDevKind netdev_kind_from_string(const char *d) _pure_; + +int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +/* gperf */ +const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length); + +/* Macros which append INTERFACE= to the message */ + +#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__) +#define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__) +#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__) +#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__) +#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__) +#define log_error_netdev(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__) + +#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__) + +#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index c108ad2358..0375194e46 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -23,6 +23,7 @@ #include #include "networkd.h" +#include "networkd-netdev.h" #include "network-internal.h" #include "path-util.h" #include "conf-files.h" diff --git a/src/network/networkd-tunnel.c b/src/network/networkd-tunnel.c deleted file mode 100644 index 5a244f61b0..0000000000 --- a/src/network/networkd-tunnel.c +++ /dev/null @@ -1,569 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include -#include -#include - -#include "sd-rtnl.h" -#include "networkd.h" -#include "network-internal.h" -#include "util.h" -#include "missing.h" -#include "conf-parser.h" - - -static int netdev_fill_ipip_rtnl_message(Link *link, sd_rtnl_message *m) { - NetDev *netdev; - int r; - - assert(link); - assert(link->network); - assert(link->network->tunnel); - assert(m); - - netdev = link->network->tunnel; - - assert(netdev->family == AF_INET); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if(netdev->mtu) { - r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_TTL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_fill_sit_rtnl_message(Link *link, sd_rtnl_message *m) { - NetDev *netdev; - int r; - - assert(link); - assert(link->network); - assert(link->network->tunnel); - assert(m); - - netdev = link->network->tunnel; - - assert(netdev->family == AF_INET); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if(netdev->mtu) { - r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TOS, netdev->tos); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_TOS attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_PMTUDISC, netdev->tunnel_pmtudisc); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_PMTUDISC attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_fill_ipgre_rtnl_message(Link *link, sd_rtnl_message *m) { - NetDev *netdev; - int r; - - assert(link); - assert(link->network); - assert(link->network->tunnel); - assert(m); - - netdev = link->network->tunnel; - - assert(netdev->family == AF_INET); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if(netdev->mtu) { - r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_GRE_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_GRE_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_GRE_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_GRE_TTL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_GRE_TOS attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -static int netdev_fill_vti_rtnl_message(Link *link, sd_rtnl_message *m) { - NetDev *netdev; - int r; - - assert(link); - assert(link->network); - assert(link->network->tunnel); - assert(m); - - netdev = link->network->tunnel; - - assert(netdev->family == AF_INET); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if(netdev->mtu) { - r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LOCAL attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_REMOTE attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - assert(link); - assert(link->network); - assert(link->network->tunnel == netdev); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - switch(netdev->kind) { - case NETDEV_KIND_IPIP: - r = netdev_fill_ipip_rtnl_message(link, m); - if(r < 0) - return r; - break; - case NETDEV_KIND_SIT: - r = netdev_fill_sit_rtnl_message(link, m); - if(r < 0) - return r; - break; - case NETDEV_KIND_VTI: - netdev_fill_vti_rtnl_message(link, m); - if(r < 0) - return r; - break; - case NETDEV_KIND_GRE: - r = netdev_fill_ipgre_rtnl_message(link, m); - if(r < 0) - return r; - break; - default: - return -ENOTSUP; - } - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - link_ref(link); - - log_debug_netdev(netdev, "Creating tunnel netdev: %s", - netdev_kind_to_string(netdev->kind)); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} - -int config_parse_tunnel_address(const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - NetDev *n = userdata; - union in_addr_union *addr = data; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - assert(data); - - r = net_parse_inaddr(rvalue, &n->family, addr); - if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Tunnel address is invalid, ignoring assignment: %s", rvalue); - return 0; - } - - return 0; -} diff --git a/src/network/networkd-tuntap.c b/src/network/networkd-tuntap.c deleted file mode 100644 index ae2d5c1e33..0000000000 --- a/src/network/networkd-tuntap.c +++ /dev/null @@ -1,155 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include - -#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_TAP; - else - ifr->ifr_flags |= IFF_TUN; - - if (!netdev->packet_info) - 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(NetDev *netdev, struct ifreq *ifr) { - _cleanup_close_ int fd; - const char *user; - const char *group; - uid_t uid; - gid_t gid; - int r = 0; - - fd = open(TUN_DEV, O_RDWR); - if (fd < 0) { - log_error_netdev(netdev, - "Failed to open tun dev: %s", - strerror(-r)); - return r; - } - - r = ioctl(fd, TUNSETIFF, ifr); - if (r < 0) { - log_error_netdev(netdev, - "TUNSETIFF failed on tun dev: %s", - strerror(-r)); - return r; - } - - if(netdev->user_name) { - - user = netdev->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)); - return 0; - } - - r = ioctl(fd, TUNSETOWNER, uid); - if ( r < 0) { - log_error_netdev(netdev, - "TUNSETOWNER failed on tun dev: %s", - strerror(-r)); - } - } - - if(netdev->group_name) { - - group = netdev->group_name; - - r = get_group_creds(&group, &gid); - if (r < 0) { - log_error("Cannot resolve group name %s: %s", - netdev->group_name, strerror(-r)); - return 0; - } - - r = ioctl(fd, TUNSETGROUP, gid); - if( r < 0) { - log_error_netdev(netdev, - "TUNSETGROUP failed on tun dev: %s", - strerror(-r)); - return r; - } - - } - - r = ioctl(fd, TUNSETPERSIST, 1); - if (r < 0) { - log_error_netdev(netdev, - "TUNSETPERSIST failed on tun dev: %s", - strerror(-r)); - return r; - } - - 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(netdev, &ifr); -} diff --git a/src/network/networkd-veth.c b/src/network/networkd-veth.c deleted file mode 100644 index 50a5b676b1..0000000000 --- a/src/network/networkd-veth.c +++ /dev/null @@ -1,154 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include -#include - -#include "sd-rtnl.h" -#include "networkd.h" - - -static int netdev_fill_veth_rtnl_message(NetDev *netdev, sd_rtnl_message *m) { - int r; - - assert(netdev); - assert(m); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(m, VETH_INFO_PEER); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IPTUN_LINK attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->ifname_peer) { - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname_peer); - if (r < 0) { - log_error("Failed to add netlink interface name: %s", strerror(-r)); - return r; - } - } - - if (netdev->mac_peer) { - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac_peer); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_veth(NetDev *netdev, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - assert(netdev->kind == NETDEV_KIND_VETH); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - r = netdev_fill_veth_rtnl_message(netdev, m); - if(r < 0) - return r; - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - netdev_ref(netdev); - - log_debug_netdev(netdev, "Creating veth netdev: %s", - netdev_kind_to_string(netdev->kind)); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-vlan.c b/src/network/networkd-vlan.c deleted file mode 100644 index 8727b9f103..0000000000 --- a/src/network/networkd-vlan.c +++ /dev/null @@ -1,149 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2013 Tom Gundersen - - 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 . -***/ - -#include - -#include "networkd.h" -#include "network-internal.h" -#include "list.h" - -int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; - const char *kind; - int r; - - assert(netdev); - assert(netdev->kind == NETDEV_KIND_VLAN); - assert(link); - assert(callback); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - if (link) { - r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINK attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->mtu) { - r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_MTU attribute: %s", - strerror(-r)); - return r; - } - } - - if (netdev->mac) { - r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac); - if (r < 0) { - log_error_netdev(netdev, - "Colud not append IFLA_ADDRESS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_open_container(req, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not open IFLA_LINKINFO container: %s", - strerror(-r)); - return r; - } - - kind = netdev_kind_to_string(netdev->kind); - if (!kind) { - log_error_netdev(netdev, "Invalid kind"); - return -EINVAL; - } - - r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, kind); - if (r < 0) { - log_error_netdev(netdev, - "Could not open IFLA_INFO_DATA container: %s", - strerror(-r)); - return r; - } - - if (netdev->vlanid <= VLANID_MAX) { - r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VLAN_ID attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_error_netdev(netdev, - "Could not close IFLA_INFO_DATA container %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(req); - if (r < 0) { - log_error_netdev(netdev, - "Could not close IFLA_LINKINFO container %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - link_ref(link); - - log_debug_netdev(netdev, "creating netdev"); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd-vxlan.c b/src/network/networkd-vxlan.c deleted file mode 100644 index 160459450d..0000000000 --- a/src/network/networkd-vxlan.c +++ /dev/null @@ -1,165 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 Susant Sahani - - 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 . -***/ - -#include -#include -#include - -#include "sd-rtnl.h" -#include "networkd.h" -#include "missing.h" - - -static int netdev_fill_vxlan_rtnl_message(NetDev *netdev, Link *link, sd_rtnl_message *m) { - int r; - - assert(link); - assert(link->network); - assert(m); - - r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_IFNAME, attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, - netdev_kind_to_string(netdev->kind)); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_INFO_DATA attribute: %s", - strerror(-r)); - return r; - } - - if (netdev->vlanid <= VXLAN_VID_MAX) { - r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, netdev->vxlanid); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_ID attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &netdev->group.in); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_GROUP attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_LINK attribute: %s", - strerror(-r)); - return r; - } - - if(netdev->ttl) { - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, netdev->ttl); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_TTL attribute: %s", - strerror(-r)); - return r; - } - } - - if(netdev->tos) { - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, netdev->tos); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_TOS attribute: %s", - strerror(-r)); - return r; - } - } - - r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, netdev->learning); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_VXLAN_LEARNING attribute: %s", - strerror(-r)); - return r; - } - - r = sd_rtnl_message_close_container(m); - if (r < 0) { - log_error_netdev(netdev, - "Could not append IFLA_LINKINFO attribute: %s", - strerror(-r)); - return r; - } - - return r; -} - -int netdev_create_vxlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) { - _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; - int r; - - assert(netdev); - assert(!(netdev->kind == NETDEV_KIND_VXLAN) || (link && callback)); - assert(netdev->ifname); - assert(netdev->manager); - assert(netdev->manager->rtnl); - - r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); - if (r < 0) { - log_error_netdev(netdev, - "Could not allocate RTM_NEWLINK message: %s", - strerror(-r)); - return r; - } - - r = netdev_fill_vxlan_rtnl_message(netdev, link, m); - if(r < 0) - return r; - - r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, link, 0, NULL); - if (r < 0) { - log_error_netdev(netdev, - "Could not send rtnetlink message: %s", strerror(-r)); - return r; - } - - link_ref(link); - - log_debug_netdev(netdev, "Creating vxlan netdev: %s", - netdev_kind_to_string(netdev->kind)); - - netdev->state = NETDEV_STATE_CREATING; - - return 0; -} diff --git a/src/network/networkd.h b/src/network/networkd.h index d8911772be..3f0ef5d0ec 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -41,7 +41,6 @@ #include "in-addr-util.h" #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU -#define VXLAN_VID_MAX (1u << 24) - 1 #define DHCP_ROUTE_METRIC 1024 #define IPV4LL_ROUTE_METRIC 2048 @@ -53,109 +52,6 @@ typedef struct Route Route; typedef struct Manager Manager; typedef struct AddressPool AddressPool; -typedef struct netdev_join_callback netdev_join_callback; - -struct netdev_join_callback { - sd_rtnl_message_handler_t callback; - Link *link; - - LIST_FIELDS(netdev_join_callback, callbacks); -}; - -typedef enum MacVlanMode { - NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE, - NETDEV_MACVLAN_MODE_VEPA = MACVLAN_MODE_VEPA, - NETDEV_MACVLAN_MODE_BRIDGE = MACVLAN_MODE_BRIDGE, - NETDEV_MACVLAN_MODE_PASSTHRU = MACVLAN_MODE_PASSTHRU, - _NETDEV_MACVLAN_MODE_MAX, - _NETDEV_MACVLAN_MODE_INVALID = -1 -} MacVlanMode; - -typedef enum BondMode { - NETDEV_BOND_MODE_BALANCE_RR, - NETDEV_BOND_MODE_ACTIVE_BACKUP, - NETDEV_BOND_MODE_BALANCE_XOR, - NETDEV_BOND_MODE_BROADCAST, - NETDEV_BOND_MODE_802_3AD, - NETDEV_BOND_MODE_BALANCE_TLB, - NETDEV_BOND_MODE_BALANCE_ALB, - _NETDEV_BOND_MODE_MAX, - _NETDEV_BOND_MODE_INVALID = -1 -} BondMode; - -typedef enum NetDevKind { - NETDEV_KIND_BRIDGE, - NETDEV_KIND_BOND, - NETDEV_KIND_VLAN, - NETDEV_KIND_MACVLAN, - NETDEV_KIND_VXLAN, - NETDEV_KIND_IPIP, - NETDEV_KIND_GRE, - NETDEV_KIND_SIT, - NETDEV_KIND_VETH, - NETDEV_KIND_VTI, - NETDEV_KIND_DUMMY, - NETDEV_KIND_TUN, - NETDEV_KIND_TAP, - _NETDEV_KIND_MAX, - _NETDEV_KIND_INVALID = -1 -} NetDevKind; - -typedef enum NetDevState { - NETDEV_STATE_FAILED, - NETDEV_STATE_CREATING, - NETDEV_STATE_READY, - NETDEV_STATE_LINGER, - _NETDEV_STATE_MAX, - _NETDEV_STATE_INVALID = -1, -} NetDevState; - -struct NetDev { - Manager *manager; - - int n_ref; - - char *filename; - - Condition *match_host; - Condition *match_virt; - Condition *match_kernel; - Condition *match_arch; - - char *description; - char *ifname; - char *ifname_peer; - char *user_name; - char *group_name; - size_t mtu; - struct ether_addr *mac; - struct ether_addr *mac_peer; - NetDevKind kind; - - uint64_t vlanid; - uint64_t vxlanid; - int32_t macvlan_mode; - int32_t bond_mode; - - int ifindex; - NetDevState state; - - bool tunnel_pmtudisc; - bool learning; - bool one_queue; - bool multi_queue; - bool packet_info; - - unsigned ttl; - unsigned tos; - unsigned char family; - union in_addr_union local; - union in_addr_union remote; - union in_addr_union group; - - LIST_HEAD(netdev_join_callback, callbacks); -}; - typedef enum DHCPSupport { DHCP_SUPPORT_NONE, DHCP_SUPPORT_BOTH, @@ -363,51 +259,6 @@ int manager_address_pool_acquire(Manager *m, unsigned family, unsigned prefixlen DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); #define _cleanup_manager_free_ _cleanup_(manager_freep) -/* NetDev */ - -#define VLANID_MAX 4094 - -int netdev_load(Manager *manager); -void netdev_drop(NetDev *netdev); - -NetDev *netdev_unref(NetDev *netdev); -NetDev *netdev_ref(NetDev *netdev); - -DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); -#define _cleanup_netdev_unref_ _cleanup_(netdev_unrefp) - -int netdev_get(Manager *manager, const char *name, NetDev **ret); -int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *newlink); -int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cb); -int netdev_create_tunnel(NetDev *netdev, 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_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback); -int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback); -int netdev_create_dummy(NetDev *netdev, sd_rtnl_message_handler_t callback); -int netdev_create_tuntap(NetDev *netdev); -int netdev_create_bond(NetDev *netdev, sd_rtnl_message_handler_t callback); -int netdev_create_bridge(NetDev *netdev, sd_rtnl_message_handler_t callback); - - -const char *netdev_kind_to_string(NetDevKind d) _const_; -NetDevKind netdev_kind_from_string(const char *d) _pure_; - -const char *macvlan_mode_to_string(MacVlanMode d) _const_; -MacVlanMode macvlan_mode_from_string(const char *d) _pure_; - -const char *bond_mode_to_string(BondMode d) _const_; -BondMode bond_mode_from_string(const char *d) _pure_; - -int config_parse_netdev_kind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); - -int config_parse_macvlan_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); - -int config_parse_bond_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); - -/* gperf */ -const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsigned length); - /* Network */ int network_load(Manager *manager); @@ -555,18 +406,6 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union #define log_struct_link(level, link, ...) log_struct(level, "INTERFACE=%s", link->ifname, __VA_ARGS__) -/* More macros which append INTERFACE= to the message */ - -#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__) -#define log_debug_netdev(netdev, ...) log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__) -#define log_info_netdev(netdev, ...) log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__) -#define log_notice_netdev(netdev, ...) log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__) -#define log_warning_netdev(netdev, ...) log_full_netdev(LOG_WARNING, netdev,## __VA_ARGS__) -#define log_error_netdev(netdev, ...) log_full_netdev(LOG_ERR, netdev, ##__VA_ARGS__) - -#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__) - -#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname #define ADDRESS_FMT_VAL(address) \ (address).s_addr & 0xFF, \ ((address).s_addr >> 8) & 0xFF, \ -- cgit v1.2.3-54-g00ecf