diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/networkd-ipv4ll.c | 2 | ||||
-rw-r--r-- | src/network/networkd-link.c | 25 | ||||
-rw-r--r-- | src/network/networkd-netdev-gperf.gperf | 5 | ||||
-rw-r--r-- | src/network/networkd-netdev-tunnel.c | 79 | ||||
-rw-r--r-- | src/network/networkd-netdev-tunnel.h | 9 | ||||
-rw-r--r-- | src/network/networkd-netdev-vrf.c | 50 | ||||
-rw-r--r-- | src/network/networkd-netdev-vrf.h | 33 | ||||
-rw-r--r-- | src/network/networkd-netdev.c | 8 | ||||
-rw-r--r-- | src/network/networkd-netdev.h | 1 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
-rw-r--r-- | src/network/networkd-network.c | 6 | ||||
-rw-r--r-- | src/network/networkd-network.h | 1 | ||||
-rw-r--r-- | src/network/networkd-route.c | 13 | ||||
-rw-r--r-- | src/network/networkd.h | 1 |
14 files changed, 221 insertions, 13 deletions
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 735c231a4c..2d81311e81 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -138,7 +138,7 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) { ll_addr->family = AF_INET; ll_addr->in_addr.in = address; ll_addr->prefixlen = 16; - ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen); + ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen); ll_addr->scope = RT_SCOPE_LINK; r = address_configure(ll_addr, link, ipv4ll_address_handler, false); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 0302f57f26..1842685180 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1600,7 +1600,7 @@ static int link_up(Link *link) { return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); /* set it free if not enslaved with networkd */ - if (!link->network->bridge && !link->network->bond) { + if (!link->network->bridge && !link->network->bond && !link->network->vrf) { r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0); if (r < 0) return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m"); @@ -2005,7 +2005,7 @@ static int link_joined(Link *link) { log_link_error_errno(link, r, "Could not set bridge message: %m"); } - if (link->network->bridge || streq("bridge", link->kind)) { + if (link->network->bridge || streq_ptr("bridge", link->kind)) { r = link_set_bridge_vlan(link); if (r < 0) log_link_error_errno(link, r, "Could not set bridge vlan: %m"); @@ -2055,6 +2055,7 @@ static int link_enter_join_netdev(Link *link) { if (!link->network->bridge && !link->network->bond && + !link->network->vrf && hashmap_isempty(link->network->stacked_netdevs)) return link_joined(link); @@ -2101,6 +2102,26 @@ static int link_enter_join_netdev(Link *link) { link->enslaving++; } + if (link->network->vrf) { + log_struct(LOG_DEBUG, + LOG_LINK_INTERFACE(link), + LOG_NETDEV_INTERFACE(link->network->vrf), + LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname), + NULL); + r = netdev_join(link->network->vrf, link, netdev_join_handler); + if (r < 0) { + log_struct_errno(LOG_WARNING, r, + LOG_LINK_INTERFACE(link), + LOG_NETDEV_INTERFACE(link->network->vrf), + LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname), + NULL); + link_enter_failed(link); + return r; + } + + link->enslaving++; + } + HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) { log_struct(LOG_DEBUG, diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index a9512cd77b..9d69f61376 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -11,6 +11,7 @@ #include "networkd-netdev-veth.h" #include "networkd-netdev-vlan.h" #include "networkd-netdev-vxlan.h" +#include "networkd-netdev-vrf.h" #include "networkd-netdev.h" #include "vlan-util.h" %} @@ -42,6 +43,9 @@ Tunnel.Local, config_parse_tunnel_address, 0, Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote) Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos) Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) +Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key) +Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey) +Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey) Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel) @@ -102,3 +106,4 @@ Bridge.ForwardDelaySec, config_parse_sec, 0, Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) +VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table_id) diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c index 7aaa041ba3..77a4734df8 100644 --- a/src/network/networkd-netdev-tunnel.c +++ b/src/network/networkd-netdev-tunnel.c @@ -35,7 +35,7 @@ #include "util.h" #define DEFAULT_TNL_HOP_LIMIT 64 -#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF) +#define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF) static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = { [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6", @@ -200,6 +200,33 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl return r; } +static int netdev_vti_fill_message_key(NetDev *netdev, Link *link, sd_netlink_message *m) { + Tunnel *t = VTI(netdev); + uint32_t ikey, okey; + int r; + + assert(link); + assert(m); + assert(t); + + if (t->key != 0) + ikey = okey = htobe32(t->key); + else { + ikey = htobe32(t->ikey); + okey = htobe32(t->okey); + } + + r = sd_netlink_message_append_u32(m, IFLA_VTI_IKEY, ikey); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_IKEY attribute: %m"); + + r = sd_netlink_message_append_u32(m, IFLA_VTI_OKEY, okey); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_OKEY attribute: %m"); + + return 0; +} + static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { Tunnel *t = VTI(netdev); int r; @@ -214,6 +241,10 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m"); + r = netdev_vti_fill_message_key(netdev, link, m); + if (r < 0) + return r; + r = sd_netlink_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m"); @@ -239,6 +270,10 @@ static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_netlin if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m"); + r = netdev_vti_fill_message_key(netdev, link, m); + if (r < 0) + return r; + r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m"); @@ -413,6 +448,46 @@ int config_parse_tunnel_address(const char *unit, return 0; } +int config_parse_tunnel_key(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) { + union in_addr_union buffer; + Tunnel *t = userdata; + uint32_t k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = in_addr_from_string(AF_INET, rvalue, &buffer); + if (r < 0) { + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse tunnel key ignoring assignment: %s", rvalue); + return 0; + } + } else + k = be32toh(buffer.in.s_addr); + + if (streq(lvalue, "Key")) + t->key = k; + else if (streq(lvalue, "InputKey")) + t->ikey = k; + else + t->okey = k; + + return 0; +} + int config_parse_ipv6_flowlabel(const char* unit, const char *filename, unsigned line, @@ -444,7 +519,7 @@ int config_parse_ipv6_flowlabel(const char* unit, if (k > 0xFFFFF) log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue); else { - *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL; + *ipv6_flowlabel = htobe32(k) & IP6_FLOWINFO_FLOWLABEL; t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; } } diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h index 7d31e7b687..32a46bd82f 100644 --- a/src/network/networkd-netdev-tunnel.h +++ b/src/network/networkd-netdev-tunnel.h @@ -49,6 +49,10 @@ typedef struct Tunnel { unsigned tos; unsigned flags; + uint32_t key; + uint32_t ikey; + uint32_t okey; + union in_addr_union local; union in_addr_union remote; @@ -108,3 +112,8 @@ int config_parse_encap_limit(const char *unit, const char *filename, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_tunnel_key(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-vrf.c b/src/network/networkd-netdev-vrf.c new file mode 100644 index 0000000000..89bd142e8c --- /dev/null +++ b/src/network/networkd-netdev-vrf.c @@ -0,0 +1,50 @@ +/*** + This file is part of systemd. + + Copyright 2016 Andreas Rammhold <andreas@rammhold.de> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <net/if.h> + +#include "sd-netlink.h" +#include "missing.h" +#include "networkd-netdev-vrf.h" + +static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { + Vrf *v; + int r; + + assert(netdev); + assert(!link); + assert(m); + + v = VRF(netdev); + + assert(v); + + r = sd_netlink_message_append_u32(m, IFLA_VRF_TABLE, v->table_id); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IPLA_VRF_TABLE attribute: %m"); + + return r; +} + +const NetDevVTable vrf_vtable = { + .object_size = sizeof(Vrf), + .sections = "NetDev\0VRF\0", + .fill_message_create = netdev_vrf_fill_message_create, + .create_type = NETDEV_CREATE_MASTER, +}; diff --git a/src/network/networkd-netdev-vrf.h b/src/network/networkd-netdev-vrf.h new file mode 100644 index 0000000000..3d92a26a4d --- /dev/null +++ b/src/network/networkd-netdev-vrf.h @@ -0,0 +1,33 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Andreas Rammhold <andreas@rammhold.de> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +typedef struct Vrf Vrf; + +#include "networkd-netdev.h" + +struct Vrf { + NetDev meta; + + uint32_t table_id; +}; + +DEFINE_NETDEV_CAST(VRF, Vrf); +extern const NetDevVTable vrf_vtable; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 851a36290c..b192884fd9 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -55,6 +55,8 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TUN] = &tun_vtable, [NETDEV_KIND_TAP] = &tap_vtable, [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable, + [NETDEV_KIND_VRF] = &vrf_vtable, + }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -78,6 +80,8 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TUN] = "tun", [NETDEV_KIND_TAP] = "tap", [NETDEV_KIND_IP6TNL] = "ip6tnl", + [NETDEV_KIND_VRF] = "vrf", + }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); @@ -198,7 +202,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h assert(netdev->state == NETDEV_STATE_READY); assert(netdev->manager); assert(netdev->manager->rtnl); - assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND)); + assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF)); assert(link); assert(callback); @@ -281,7 +285,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call assert(netdev); assert(netdev->manager); assert(netdev->manager->rtnl); - assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND)); + assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF)); if (netdev->state == NETDEV_STATE_READY) { r = netdev_enslave_ready(netdev, link, callback); diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index 20244c0309..b92a973b85 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -55,6 +55,7 @@ typedef enum NetDevKind { NETDEV_KIND_DUMMY, NETDEV_KIND_TUN, NETDEV_KIND_TAP, + NETDEV_KIND_VRF, _NETDEV_KIND_MAX, _NETDEV_KIND_INVALID = -1 } NetDevKind; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 0b0aa58f67..affc0d00e9 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -37,6 +37,7 @@ Network.MACVTAP, config_parse_netdev, Network.IPVLAN, config_parse_netdev, 0, 0 Network.VXLAN, config_parse_netdev, 0, 0 Network.Tunnel, config_parse_tunnel, 0, 0 +Network.VRF, config_parse_netdev, 0, 0 Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 84bdf75b38..2b764d4f24 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -244,8 +244,8 @@ void network_free(Network *network) { strv_free(network->bind_carrier); netdev_unref(network->bridge); - netdev_unref(network->bond); + netdev_unref(network->vrf); HASHMAP_FOREACH(netdev, network->stacked_netdevs, i) { hashmap_remove(network->stacked_netdevs, netdev->ifname); @@ -471,6 +471,10 @@ int config_parse_netdev(const char *unit, network->bond = netdev; break; + case NETDEV_KIND_VRF: + network->vrf = netdev; + + break; case NETDEV_KIND_VLAN: case NETDEV_KIND_MACVLAN: case NETDEV_KIND_MACVTAP: diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 38688cc400..08ee939faa 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -104,6 +104,7 @@ struct Network { NetDev *bridge; NetDev *bond; + NetDev *vrf; Hashmap *stacked_netdevs; /* DHCP Client Support */ diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 52037f9c6d..cedaf47cf8 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -795,6 +795,7 @@ int config_parse_route_priority(const char *unit, void *userdata) { Network *network = userdata; _cleanup_route_free_ Route *n = NULL; + uint32_t k; int r; assert(filename); @@ -807,12 +808,14 @@ int config_parse_route_priority(const char *unit, if (r < 0) return r; - r = config_parse_uint32(unit, filename, line, section, - section_line, lvalue, ltype, - rvalue, &n->priority, userdata); - if (r < 0) - return r; + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Could not parse route priority \"%s\", ignoring assignment: %m", rvalue); + return 0; + } + n->priority = k; n = NULL; return 0; diff --git a/src/network/networkd.h b/src/network/networkd.h index ab512f0d08..c4bd712147 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -41,6 +41,7 @@ #include "networkd-netdev-tuntap.h" #include "networkd-netdev-veth.h" #include "networkd-netdev-vlan.h" +#include "networkd-netdev-vrf.h" #include "networkd-netdev-vxlan.h" #include "networkd-network.h" #include "networkd-util.h" |