diff options
Diffstat (limited to 'src/network/networkd-netdev.c')
-rw-r--r-- | src/network/networkd-netdev.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 6949b403c8..a210ba1242 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -21,19 +19,26 @@ #include <net/if.h> -#include "networkd-netdev.h" -#include "networkd-link.h" -#include "network-internal.h" +#include "alloc-util.h" #include "conf-files.h" #include "conf-parser.h" +#include "fd-util.h" #include "list.h" +#include "netlink-util.h" +#include "network-internal.h" +#include "networkd-netdev.h" +#include "networkd.h" #include "siphash24.h" +#include "stat-util.h" +#include "string-table.h" +#include "string-util.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_MACVTAP] = &macvtap_vtable, [NETDEV_KIND_IPVLAN] = &ipvlan_vtable, [NETDEV_KIND_VXLAN] = &vxlan_vtable, [NETDEV_KIND_IPIP] = &ipip_vtable, @@ -49,6 +54,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, + [NETDEV_KIND_VCAN] = &vcan_vtable, }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -56,6 +63,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_BOND] = "bond", [NETDEV_KIND_VLAN] = "vlan", [NETDEV_KIND_MACVLAN] = "macvlan", + [NETDEV_KIND_MACVTAP] = "macvtap", [NETDEV_KIND_IPVLAN] = "ipvlan", [NETDEV_KIND_VXLAN] = "vxlan", [NETDEV_KIND_IPIP] = "ipip", @@ -71,13 +79,15 @@ 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", + [NETDEV_KIND_VCAN] = "vcan", }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind"); static void netdev_cancel_callbacks(NetDev *netdev) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; netdev_join_callback *callback; if (!netdev) @@ -184,14 +194,14 @@ static int netdev_enter_failed(NetDev *netdev) { } static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_handler_t callback) { - _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; assert(netdev); 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); @@ -240,6 +250,9 @@ static int netdev_enter_ready(NetDev *netdev) { free(callback); } + if (NETDEV_VTABLE(netdev)->post_create) + NETDEV_VTABLE(netdev)->post_create(netdev, NULL, NULL); + return 0; } @@ -271,14 +284,14 @@ 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); if (r < 0) return r; } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; r = rtnl_message_new_synthetic_error(-ENODEV, 0, &m); if (r >= 0) @@ -399,7 +412,7 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) { int netdev_get_mac(const char *ifname, struct ether_addr **ret) { _cleanup_free_ struct ether_addr *mac = NULL; - uint8_t result[8]; + uint64_t result; size_t l, sz; uint8_t *v; int r; @@ -426,10 +439,10 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) { /* Let's hash the host machine ID plus the container name. We * use a fixed, but originally randomly created hash key here. */ - siphash24(result, v, sz, HASH_KEY.bytes); + result = siphash24(v, sz, HASH_KEY.bytes); assert_cc(ETH_ALEN <= sizeof(result)); - memcpy(mac->ether_addr_octet, result, ETH_ALEN); + memcpy(mac->ether_addr_octet, &result, ETH_ALEN); /* see eth_random_addr in the kernel */ mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ @@ -458,7 +471,7 @@ static int netdev_create(NetDev *netdev, Link *link, log_netdev_debug(netdev, "Created"); } else { - _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0); if (r < 0) @@ -502,7 +515,7 @@ static int netdev_create(NetDev *netdev, Link *link, r = sd_netlink_message_close_container(m); if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); r = sd_netlink_message_close_container(m); if (r < 0) @@ -563,6 +576,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { _cleanup_netdev_unref_ NetDev *netdev = NULL; _cleanup_free_ NetDev *netdev_raw = NULL; _cleanup_fclose_ FILE *file = NULL; + const char *dropin_dirname; int r; assert(manager); @@ -586,11 +600,12 @@ static int netdev_load_one(Manager *manager, const char *filename) { return log_oom(); netdev_raw->kind = _NETDEV_KIND_INVALID; + dropin_dirname = strjoina(basename(filename), ".d"); - r = config_parse(NULL, filename, file, - "Match\0NetDev\0", - config_item_perf_lookup, network_netdev_gperf_lookup, - true, false, true, netdev_raw); + r = config_parse_many(filename, network_dirs, dropin_dirname, + "Match\0NetDev\0", + config_item_perf_lookup, network_netdev_gperf_lookup, + true, netdev_raw); if (r < 0) return r; @@ -605,8 +620,8 @@ static int netdev_load_one(Manager *manager, const char *filename) { NULL, NULL, NULL, NULL, NULL, NULL) <= 0) return 0; - if (!NETDEV_VTABLE(netdev_raw)) { - log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename); + if (netdev_raw->kind == _NETDEV_KIND_INVALID) { + log_warning("NetDev has no Kind configured in %s. Ignoring", filename); return 0; } @@ -646,7 +661,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { if (!netdev->filename) return log_oom(); - if (!netdev->mac) { + if (!netdev->mac && netdev->kind != NETDEV_KIND_VLAN) { r = netdev_get_mac(netdev->ifname, &netdev->mac); if (r < 0) return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname); |