summaryrefslogtreecommitdiff
path: root/src/network/networkd-netdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/networkd-netdev.c')
-rw-r--r--src/network/networkd-netdev.c59
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);