1
0
mirror of https://github.com/systemd/systemd synced 2026-04-08 16:14:50 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
Topi Miettinen
788e720181 namespace: allow ProcSubset=pid with some ProtectKernel options
In case `/proc` is successfully mounted with pid tree subset only due to
`ProcSubset=pid`, the protective mounts for `ProtectKernelTunables=yes` and
`ProtectKernelLogs=yes` to non-pid `/proc` paths are failing because the paths
don't exist. But the pid only option may have failed gracefully (for example
because of ancient kernel), so let's try the mounts but it's not fatal if they
don't succeed.
2021-11-27 17:36:51 +00:00
Luca Boccassi
cab35e9672
Merge pull request #21535 from yuwata/network-netdev-verify-mac
network/netdev: verify MAC address
2021-11-27 13:48:56 +00:00
Yu Watanabe
70b0652697 network: route: route->link may be NULL
Fixes #21544.
2021-11-27 13:48:02 +00:00
Alyssa Ross
f000edf9ea docs: fix descriptions in discoverable partitions
00db9a114e ("docs: generate table from header using a script") got the
descriptions for the partition types mixed up.  After that change, the
spec claimed, for example, that the /usr partition should contain
"dm-verity integrity hash data for the matching root partition", and
that the /usr verity partition should be of type "Any native, optionally
in LUKS".  This made the spec an extremely confusing read before I
figured out what must have happened!

I've gone through the table as it existed prior to 00db9a114e, and moved
the descriptions around in the script that generates the table until
they matched up with what they used to be.  Then I regenerated the
table from the fixed script.
2021-11-27 13:46:35 +00:00
Yu Watanabe
007899f43e network/netdev: verify specified MAC address
Drop multicast bit and set local bit of the specified MAC address.

This also makes failure in generating persistent MAC address
non-critical.
2021-11-27 06:39:04 +09:00
Yu Watanabe
5e20e1e3e3 network/netdev: use "struct hw_addr_data" to store MAC address 2021-11-27 06:39:04 +09:00
Yu Watanabe
9f0cf80dd0 network/netdev: introduce .iftype to netdev vtable
And disable .generate_mac flag for non-ether interfaces.
2021-11-27 06:38:26 +09:00
Yu Watanabe
a67e0507c3 network: veth: use SYNTHETIC_ERRNO() macro or use real error cause 2021-11-27 06:37:58 +09:00
31 changed files with 196 additions and 100 deletions

View File

@ -60,7 +60,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| _Root Partition (TILE-Gx)_ | `c50cdd70-3862-4cc3-90e1-809a8c93ee2c` | ditto | ditto |
| _Root Partition (x86)_ | `44479540-f297-41b2-9af7-d131d5f0458a` | ditto | ditto |
| _Root Partition (amd64/x86_64)_ | `4f68bce3-e8cd-4db1-96e7-fbcaf984b709` | ditto | ditto |
| _`/usr/` Partition (Alpha)_ | `e18cf08c-33ec-4c0d-8246-c6c6fb3da024` | A dm-verity superblock followed by hash data | Contains dm-verity integrity hash data for the matching root partition. If this feature is used the partition UUID of the root partition should be the first 128 bits of the root hash of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the final 128 bits of it, so that the root partition and its Verity partition can be discovered easily, simply by specifying the root hash. |
| _`/usr/` Partition (Alpha)_ | `e18cf08c-33ec-4c0d-8246-c6c6fb3da024` | Any native, optionally in LUKS | Similar semantics to root partition, but just the `/usr/` partition. |
| _`/usr/` Partition (ARC)_ | `7978a683-6316-4922-bbee-38bff5a2fecc` | ditto | ditto |
| _`/usr/` Partition (32-bit ARM)_ | `7d0359a3-02b3-4f0a-865c-654403e70625` | ditto | ditto |
| _`/usr/` Partition (64-bit ARM/AArch64)_ | `b0e01050-ee5f-4390-949a-9101b17104e9` | ditto | ditto |
@ -78,7 +78,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| _`/usr/` Partition (TILE-Gx)_ | `55497029-c7c1-44cc-aa39-815ed1558630` | ditto | ditto |
| _`/usr/` Partition (x86)_ | `75250d76-8cc6-458e-bd66-bd47cc81a812` | ditto | ditto |
| _`/usr/` Partition (amd64/x86_64)_ | `8484680c-9521-48c6-9c11-b0720656f69e` | ditto | ditto |
| _Root Verity Partition (Alpha)_ | `fc56d9e9-e6e5-4c06-be32-e74407ce09a5` | A serialized JSON object, see below | Contains a root hash and a PKCS#7 signature for it, permitting signed dm-verity GPT images. |
| _Root Verity Partition (Alpha)_ | `fc56d9e9-e6e5-4c06-be32-e74407ce09a5` | A dm-verity superblock followed by hash data | Contains dm-verity integrity hash data for the matching root partition. If this feature is used the partition UUID of the root partition should be the first 128 bits of the root hash of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the final 128 bits of it, so that the root partition and its Verity partition can be discovered easily, simply by specifying the root hash. |
| _Root Verity Partition (ARC)_ | `24b2d975-0f97-4521-afa1-cd531e421b8d` | ditto | ditto |
| _Root Verity Partition (32-bit ARM)_ | `7386cdf2-203c-47a9-a498-f2ecce45a2d6` | ditto | ditto |
| _Root Verity Partition (64-bit ARM/AArch64)_ | `df3300ce-d69f-4c92-978c-9bfb0f38d820` | ditto | ditto |
@ -96,7 +96,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| _Root Verity Partition (TILE-Gx)_ | `966061ec-28e4-4b2e-b4a5-1f0a825a1d84` | ditto | ditto |
| _Root Verity Partition (amd64/x86_64)_ | `2c7357ed-ebd2-46d9-aec1-23d437ec2bf5` | ditto | ditto |
| _Root Verity Partition (x86)_ | `d13c5d3b-b5d1-422a-b29f-9454fdc89d76` | ditto | ditto |
| _`/usr/` Verity Partition (Alpha)_ | `8cce0d25-c0d0-4a44-bd87-46331bf1df67` | Any native, optionally in LUKS | Similar semantics to root partition, but just the `/usr/` partition. |
| _`/usr/` Verity Partition (Alpha)_ | `8cce0d25-c0d0-4a44-bd87-46331bf1df67` | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. |
| _`/usr/` Verity Partition (ARC)_ | `fca0598c-d880-4591-8c16-4eda05c7347c` | ditto | ditto |
| _`/usr/` Verity Partition (32-bit ARM)_ | `c215d751-7bcd-4649-be90-6627490a4c05` | ditto | ditto |
| _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | ditto | ditto |
@ -114,7 +114,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| _`/usr/` Verity Partition (TILE-Gx)_ | `2fb4bf56-07fa-42da-8132-6b139f2026ae` | ditto | ditto |
| _`/usr/` Verity Partition (amd64/x86_64)_ | `77ff5f63-e7b6-4633-acf4-1565b864c0e6` | ditto | ditto |
| _`/usr/` Verity Partition (x86)_ | `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | ditto | ditto |
| _Root Verity Signature Partition (Alpha)_ | `d46495b7-a053-414f-80f7-700c99921ef8` | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. |
| _Root Verity Signature Partition (Alpha)_ | `d46495b7-a053-414f-80f7-700c99921ef8` | A serialized JSON object, see below | Contains a root hash and a PKCS#7 signature for it, permitting signed dm-verity GPT images. |
| _Root Verity Signature Partition (ARC)_ | `143a70ba-cbd3-4f06-919f-6c05683a78bc` | ditto | ditto |
| _Root Verity Signature Partition (32-bit ARM)_ | `42b0455f-eb11-491d-98d3-56145ba9d037` | ditto | ditto |
| _Root Verity Signature Partition (64-bit ARM/AArch64)_ | `6db69de6-29f4-4758-a7a5-962190f00ce3` | ditto | ditto |

View File

@ -101,7 +101,7 @@ static const MountEntry apivfs_table[] = {
};
/* ProtectKernelTunables= option and the related filesystem APIs */
static const MountEntry protect_kernel_tunables_table[] = {
static const MountEntry protect_kernel_tunables_proc_table[] = {
{ "/proc/acpi", READONLY, true },
{ "/proc/apm", READONLY, true }, /* Obsolete API, there's no point in permitting access to this, ever */
{ "/proc/asound", READONLY, true },
@ -116,6 +116,9 @@ static const MountEntry protect_kernel_tunables_table[] = {
{ "/proc/sys", READONLY, true },
{ "/proc/sysrq-trigger", READONLY, true },
{ "/proc/timer_stats", READONLY, true },
};
static const MountEntry protect_kernel_tunables_sys_table[] = {
{ "/sys", READONLY, false },
{ "/sys/fs/bpf", READONLY, true },
{ "/sys/fs/cgroup", READWRITE_IMPLICIT, false }, /* READONLY is set by ProtectControlGroups= option */
@ -133,8 +136,11 @@ static const MountEntry protect_kernel_modules_table[] = {
};
/* ProtectKernelLogs= option */
static const MountEntry protect_kernel_logs_table[] = {
static const MountEntry protect_kernel_logs_proc_table[] = {
{ "/proc/kmsg", INACCESSIBLE, true },
};
static const MountEntry protect_kernel_logs_dev_table[] = {
{ "/dev/kmsg", INACCESSIBLE, true },
};
@ -1554,9 +1560,11 @@ static size_t namespace_calculate_mounts(
(n_extension_images > 0 ? n_hierarchies + n_extension_images : 0) + /* Mount each image plus an overlay per hierarchy */
n_temporary_filesystems +
ns_info->private_dev +
(ns_info->protect_kernel_tunables ? ELEMENTSOF(protect_kernel_tunables_table) : 0) +
(ns_info->protect_kernel_tunables ?
ELEMENTSOF(protect_kernel_tunables_proc_table) + ELEMENTSOF(protect_kernel_tunables_sys_table) : 0) +
(ns_info->protect_kernel_modules ? ELEMENTSOF(protect_kernel_modules_table) : 0) +
(ns_info->protect_kernel_logs ? ELEMENTSOF(protect_kernel_logs_table) : 0) +
(ns_info->protect_kernel_logs ?
ELEMENTSOF(protect_kernel_logs_proc_table) + ELEMENTSOF(protect_kernel_logs_dev_table) : 0) +
(ns_info->protect_control_groups ? 1 : 0) +
protect_home_cnt + protect_system_cnt +
(ns_info->protect_hostname ? 2 : 0) +
@ -2079,10 +2087,21 @@ int setup_namespace(
.flags = DEV_MOUNT_OPTIONS,
};
/* In case /proc is successfully mounted with pid tree subset only (ProcSubset=pid), the
protective mounts to non-pid /proc paths would fail. But the pid only option may have
failed gracefully, so let's try the mounts but it's not fatal if they don't succeed. */
bool ignore_protect_proc = ns_info->ignore_protect_paths || ns_info->proc_subset == PROC_SUBSET_PID;
if (ns_info->protect_kernel_tunables) {
r = append_static_mounts(&m,
protect_kernel_tunables_table,
ELEMENTSOF(protect_kernel_tunables_table),
protect_kernel_tunables_proc_table,
ELEMENTSOF(protect_kernel_tunables_proc_table),
ignore_protect_proc);
if (r < 0)
goto finish;
r = append_static_mounts(&m,
protect_kernel_tunables_sys_table,
ELEMENTSOF(protect_kernel_tunables_sys_table),
ns_info->ignore_protect_paths);
if (r < 0)
goto finish;
@ -2099,8 +2118,15 @@ int setup_namespace(
if (ns_info->protect_kernel_logs) {
r = append_static_mounts(&m,
protect_kernel_logs_table,
ELEMENTSOF(protect_kernel_logs_table),
protect_kernel_logs_proc_table,
ELEMENTSOF(protect_kernel_logs_proc_table),
ignore_protect_proc);
if (r < 0)
goto finish;
r = append_static_mounts(&m,
protect_kernel_logs_dev_table,
ELEMENTSOF(protect_kernel_logs_dev_table),
ns_info->ignore_protect_paths);
if (r < 0)
goto finish;

View File

@ -1,6 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright © 2020 VMware, Inc. */
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "bareudp.h"
#include "netlink-util.h"
#include "networkd-manager.h"
@ -79,4 +82,5 @@ const NetDevVTable bare_udp_vtable = {
.config_verify = netdev_bare_udp_verify,
.fill_message_create = netdev_bare_udp_fill_message_create,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_NONE,
};

View File

@ -1,7 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <inttypes.h>
#include <netinet/in.h>
#include <linux/genetlink.h>
#include <linux/if_arp.h>
#include "batadv.h"
#include "fileio.h"
@ -200,4 +202,5 @@ const NetDevVTable batadv_vtable = {
.fill_message_create = netdev_batadv_fill_message_create,
.post_create = netdev_batadv_post_create,
.create_type = NETDEV_CREATE_MASTER,
.iftype = ARPHRD_ETHER,
};

View File

@ -1,5 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "alloc-util.h"
#include "bond.h"
#include "bond-util.h"
@ -449,5 +452,6 @@ const NetDevVTable bond_vtable = {
.sections = NETDEV_COMMON_SECTIONS "Bond\0",
.fill_message_create = netdev_bond_fill_message_create,
.create_type = NETDEV_CREATE_MASTER,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -2,6 +2,7 @@
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include <linux/if_bridge.h>
#include "bridge.h"
@ -276,4 +277,5 @@ const NetDevVTable bridge_vtable = {
.sections = NETDEV_COMMON_SECTIONS "Bridge\0",
.post_create = netdev_bridge_post_create,
.create_type = NETDEV_CREATE_MASTER,
.iftype = ARPHRD_ETHER,
};

View File

@ -1,10 +1,13 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "dummy.h"
const NetDevVTable dummy_vtable = {
.object_size = sizeof(Dummy),
.sections = NETDEV_COMMON_SECTIONS,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "alloc-util.h"
#include "conf-parser.h"
@ -292,5 +294,6 @@ const NetDevVTable geneve_vtable = {
.fill_message_create = netdev_geneve_fill_message_create,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_geneve_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,11 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright © 2019 VMware, Inc. */
#include <linux/if_arp.h>
#include "ifb.h"
const NetDevVTable ifb_vtable = {
.object_size = sizeof(IntermediateFunctionalBlock),
.sections = NETDEV_COMMON_SECTIONS,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "conf-parser.h"
#include "ipvlan.h"
@ -63,6 +65,7 @@ const NetDevVTable ipvlan_vtable = {
.sections = NETDEV_COMMON_SECTIONS "IPVLAN\0",
.fill_message_create = netdev_ipvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@ -72,6 +75,7 @@ const NetDevVTable ipvtap_vtable = {
.sections = NETDEV_COMMON_SECTIONS "IPVTAP\0",
.fill_message_create = netdev_ipvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <netinet/in.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_macsec.h>
#include <linux/genetlink.h>
@ -1230,5 +1231,6 @@ const NetDevVTable macsec_vtable = {
.done = macsec_done,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_macsec_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "conf-parser.h"
#include "macvlan.h"
@ -153,6 +155,7 @@ const NetDevVTable macvtap_vtable = {
.sections = NETDEV_COMMON_SECTIONS "MACVTAP\0",
.fill_message_create = netdev_macvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@ -163,5 +166,6 @@ const NetDevVTable macvlan_vtable = {
.sections = NETDEV_COMMON_SECTIONS "MACVLAN\0",
.fill_message_create = netdev_macvlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -49,7 +49,7 @@ NetDev.Description, config_parse_string,
NetDev.Name, config_parse_ifname, 0, offsetof(NetDev, ifname)
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
NetDev.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_ether_addr, 0, offsetof(NetDev, mac)
NetDev.MACAddress, config_parse_hw_addr, ETH_ALEN, offsetof(NetDev, hw_addr)
VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
VLAN.Protocol, config_parse_vlanprotocol, 0, offsetof(VLan, protocol)
VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp)
@ -111,7 +111,7 @@ L2TPSession.PeerSessionId, config_parse_l2tp_session_id,
L2TPSession.Layer2SpecificHeader, config_parse_l2tp_session_l2spec, 0, 0
L2TPSession.Name, config_parse_l2tp_session_name, 0, 0
Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
Peer.MACAddress, config_parse_ether_addr, 0, offsetof(Veth, mac_peer)
Peer.MACAddress, config_parse_hw_addr, ETH_ALEN, offsetof(Veth, hw_addr_peer)
VXCAN.Peer, config_parse_ifname, 0, offsetof(VxCan, ifname_peer)
VXLAN.VNI, config_parse_uint32, 0, offsetof(VxLan, vni)
VXLAN.Id, config_parse_uint32, 0, offsetof(VxLan, vni) /* deprecated */

View File

@ -2,9 +2,11 @@
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include <unistd.h>
#include "alloc-util.h"
#include "arphrd-util.h"
#include "bareudp.h"
#include "batadv.h"
#include "bond.h"
@ -23,6 +25,7 @@
#include "macvlan.h"
#include "netdev.h"
#include "netdevsim.h"
#include "netif-util.h"
#include "netlink-util.h"
#include "networkd-manager.h"
#include "networkd-queue.h"
@ -229,7 +232,6 @@ static NetDev *netdev_free(NetDev *netdev) {
free(netdev->description);
free(netdev->ifname);
free(netdev->mac);
condition_free_list(netdev->conditions);
/* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
@ -424,46 +426,52 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
_cleanup_free_ struct ether_addr *mac = NULL;
uint64_t result;
size_t l, sz;
uint8_t *v;
int netdev_generate_hw_addr(NetDev *netdev, const char *name, struct hw_addr_data *hw_addr) {
bool warn_invalid = false;
struct hw_addr_data a;
int r;
assert(ifname);
assert(ret);
assert(netdev);
assert(name);
assert(hw_addr);
mac = new0(struct ether_addr, 1);
if (!mac)
return -ENOMEM;
if (hw_addr->length == 0) {
uint64_t result;
l = strlen(ifname);
sz = sizeof(sd_id128_t) + l;
v = newa(uint8_t, sz);
/* HardwareAddress= is not specified. */
/* fetch some persistent data unique to the machine */
r = sd_id128_get_machine((sd_id128_t*) v);
if (!NETDEV_VTABLE(netdev)->generate_mac)
return 0;
if (NETDEV_VTABLE(netdev)->iftype != ARPHRD_ETHER)
return 0;
r = net_get_unique_predictable_data_from_name(name, &HASH_KEY, &result);
if (r < 0) {
log_netdev_warning_errno(netdev, r,
"Failed to generate persistent MAC address, ignoring: %m");
return 0;
}
a.length = arphrd_to_hw_addr_len(NETDEV_VTABLE(netdev)->iftype);
assert(a.length <= sizeof(result));
memcpy(a.bytes, &result, a.length);
if (ether_addr_is_null(&a.ether) || ether_addr_is_broadcast(&a.ether)) {
log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"Failed to generate persistent MAC address, ignoring: %m");
return 0;
}
} else {
a = *hw_addr;
warn_invalid = true;
}
r = net_verify_hardware_address(name, warn_invalid, NETDEV_VTABLE(netdev)->iftype, NULL, &a);
if (r < 0)
return r;
/* combine with some data unique (on this machine) to this
* netdev */
memcpy(v + sizeof(sd_id128_t), ifname, l);
/* Let's hash the host machine ID plus the container name. We
* use a fixed, but originally randomly created hash key here. */
result = siphash24(v, sz, HASH_KEY.bytes);
assert_cc(ETH_ALEN <= sizeof(result));
memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
/* see eth_random_addr in the kernel */
mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
*ret = TAKE_PTR(mac);
*hw_addr = a;
return 0;
}
@ -494,8 +502,8 @@ static int netdev_create(NetDev *netdev, Link *link, link_netlink_message_handle
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
if (netdev->mac) {
r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
if (netdev->hw_addr.length > 0) {
r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &netdev->hw_addr);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
}
@ -813,12 +821,9 @@ int netdev_load_one(Manager *manager, const char *filename) {
if (!netdev->filename)
return log_oom();
if (!netdev->mac && NETDEV_VTABLE(netdev)->generate_mac) {
r = netdev_get_mac(netdev->ifname, &netdev->mac);
if (r < 0)
return log_netdev_error_errno(netdev, r,
"Failed to generate predictable MAC address: %m");
}
r = netdev_generate_hw_addr(netdev, netdev->ifname, &netdev->hw_addr);
if (r < 0)
return r;
r = hashmap_ensure_put(&netdev->manager->netdevs, &string_hash_ops, netdev->ifname, netdev);
if (r == -ENOMEM)

View File

@ -4,6 +4,7 @@
#include "sd-netlink.h"
#include "conf-parser.h"
#include "ether-addr-util.h"
#include "list.h"
#include "log-link.h"
#include "networkd-link.h"
@ -118,7 +119,7 @@ typedef struct NetDev {
NetDevKind kind;
char *description;
char *ifname;
struct ether_addr *mac;
struct hw_addr_data hw_addr;
uint32_t mtu;
int ifindex;
} NetDev;
@ -159,6 +160,9 @@ typedef struct NetDevVTable {
/* verify that compulsory configuration options were specified */
int (*config_verify)(NetDev *netdev, const char *filename);
/* expected iftype, e.g. ARPHRD_ETHER. */
uint16_t iftype;
/* Generate MAC address when MACAddress= is not specified. */
bool generate_mac;
} NetDevVTable;
@ -194,7 +198,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
bool netdev_is_managed(NetDev *netdev);
int netdev_get(Manager *manager, const char *name, NetDev **ret);
int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
int netdev_get_mac(const char *ifname, struct ether_addr **ret);
int netdev_generate_hw_addr(NetDev *netdev, const char *name, struct hw_addr_data *hw_addr);
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb);
int request_process_stacked_netdev(Request *req);

View File

@ -1,10 +1,13 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "netdevsim.h"
const NetDevVTable netdevsim_vtable = {
.object_size = sizeof(NetDevSim),
.sections = NETDEV_COMMON_SECTIONS,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,14 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "nlmon.h"
static int netdev_nlmon_verify(NetDev *netdev, const char *filename) {
assert(netdev);
assert(filename);
if (netdev->mac) {
if (netdev->hw_addr.length > 0) {
log_netdev_warning(netdev, "%s: MACAddress= is not supported. Ignoring", filename);
netdev->mac = mfree(netdev->mac);
netdev->hw_addr = HW_ADDR_NULL;
}
return 0;
@ -19,4 +21,5 @@ const NetDevVTable nlmon_vtable = {
.sections = NETDEV_COMMON_SECTIONS,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_nlmon_verify,
.iftype = ARPHRD_NETLINK,
};

View File

@ -2,8 +2,9 @@
#include <netinet/in.h>
#include <linux/fou.h>
#include <linux/ip.h>
#include <linux/if_arp.h>
#include <linux/if_tunnel.h>
#include <linux/ip.h>
#include <linux/ip6_tunnel.h>
#include "conf-parser.h"
@ -817,7 +818,7 @@ const NetDevVTable ipip_vtable = {
.fill_message_create = netdev_ipip_sit_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_TUNNEL,
};
const NetDevVTable sit_vtable = {
@ -827,7 +828,7 @@ const NetDevVTable sit_vtable = {
.fill_message_create = netdev_ipip_sit_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_SIT,
};
const NetDevVTable vti_vtable = {
@ -837,7 +838,7 @@ const NetDevVTable vti_vtable = {
.fill_message_create = netdev_vti_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_TUNNEL,
};
const NetDevVTable vti6_vtable = {
@ -847,7 +848,7 @@ const NetDevVTable vti6_vtable = {
.fill_message_create = netdev_vti_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_TUNNEL6,
};
const NetDevVTable gre_vtable = {
@ -857,7 +858,7 @@ const NetDevVTable gre_vtable = {
.fill_message_create = netdev_gre_erspan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_IPGRE,
};
const NetDevVTable gretap_vtable = {
@ -867,6 +868,7 @@ const NetDevVTable gretap_vtable = {
.fill_message_create = netdev_gre_erspan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@ -877,7 +879,7 @@ const NetDevVTable ip6gre_vtable = {
.fill_message_create = netdev_ip6gre_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_IP6GRE,
};
const NetDevVTable ip6gretap_vtable = {
@ -887,6 +889,7 @@ const NetDevVTable ip6gretap_vtable = {
.fill_message_create = netdev_ip6gre_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};
@ -897,7 +900,7 @@ const NetDevVTable ip6tnl_vtable = {
.fill_message_create = netdev_ip6tnl_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.generate_mac = true,
.iftype = ARPHRD_TUNNEL6,
};
const NetDevVTable erspan_vtable = {
@ -907,5 +910,6 @@ const NetDevVTable erspan_vtable = {
.fill_message_create = netdev_gre_erspan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -136,7 +136,7 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
"Please set it in the corresponding .network file.",
netdev_kind_to_string(netdev->kind), filename);
if (netdev->mac)
if (netdev->hw_addr.length > 0)
log_netdev_warning(netdev,
"MACAddress= configured for %s device in %s will be ignored.\n"
"Please set it in the corresponding .network file.",
@ -152,6 +152,7 @@ const NetDevVTable tun_vtable = {
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_NONE,
};
const NetDevVTable tap_vtable = {
@ -161,4 +162,5 @@ const NetDevVTable tap_vtable = {
.done = tuntap_done,
.create = netdev_create_tuntap,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_ETHER,
};

View File

@ -1,10 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "vcan.h"
const NetDevVTable vcan_vtable = {
.object_size = sizeof(VCan),
.sections = NETDEV_COMMON_SECTIONS,
.create_type = NETDEV_CREATE_INDEPENDENT,
.generate_mac = true,
.iftype = ARPHRD_CAN,
};

View File

@ -2,8 +2,11 @@
#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include <linux/veth.h>
#include "netlink-util.h"
#include "veth.h"
static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
@ -28,8 +31,8 @@ static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlin
return log_netdev_error_errno(netdev, r, "Failed to add netlink interface name: %m");
}
if (v->mac_peer) {
r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer);
if (v->hw_addr_peer.length > 0) {
r = netlink_message_append_hw_addr(m, IFLA_ADDRESS, &v->hw_addr_peer);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
}
@ -58,21 +61,14 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) {
assert(v);
if (!v->ifname_peer) {
log_netdev_warning(netdev, "Veth NetDev without peer name configured in %s. Ignoring",
filename);
return -EINVAL;
}
if (!v->ifname_peer)
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"Veth NetDev without peer name configured in %s. Ignoring",
filename);
if (!v->mac_peer) {
r = netdev_get_mac(v->ifname_peer, &v->mac_peer);
if (r < 0) {
log_netdev_warning(netdev,
"Failed to generate predictable MAC address for %s. Ignoring",
v->ifname_peer);
return -EINVAL;
}
}
r = netdev_generate_hw_addr(netdev, v->ifname_peer, &v->hw_addr_peer);
if (r < 0)
return r;
return 0;
}
@ -87,7 +83,6 @@ static void veth_done(NetDev *n) {
assert(v);
free(v->ifname_peer);
free(v->mac_peer);
}
const NetDevVTable veth_vtable = {
@ -97,5 +92,6 @@ const NetDevVTable veth_vtable = {
.fill_message_create = netdev_veth_fill_message_create,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_veth_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -9,7 +9,7 @@ struct Veth {
NetDev meta;
char *ifname_peer;
struct ether_addr *mac_peer;
struct hw_addr_data hw_addr_peer;
};
DEFINE_NETDEV_CAST(VETH, Veth);

View File

@ -2,6 +2,7 @@
#include <errno.h>
#include <net/if.h>
#include <linux/if_arp.h>
#include <linux/if_vlan.h>
#include "parse-util.h"
@ -229,4 +230,5 @@ const NetDevVTable vlan_vtable = {
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vlan_verify,
.done = vlan_done,
.iftype = ARPHRD_ETHER,
};

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "vrf.h"
@ -28,5 +30,6 @@ const NetDevVTable vrf_vtable = {
.sections = NETDEV_COMMON_SECTIONS "VRF\0",
.fill_message_create = netdev_vrf_fill_message_create,
.create_type = NETDEV_CREATE_MASTER,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/can/vxcan.h>
#include <linux/if_arp.h>
#include "vxcan.h"
@ -70,5 +71,5 @@ const NetDevVTable vxcan_vtable = {
.fill_message_create = netdev_vxcan_fill_message_create,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_vxcan_verify,
.generate_mac = true,
.iftype = ARPHRD_CAN,
};

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "conf-parser.h"
#include "alloc-util.h"
@ -394,5 +396,6 @@ const NetDevVTable vxlan_vtable = {
.fill_message_create = netdev_vxlan_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vxlan_verify,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

View File

@ -5,6 +5,8 @@
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "sd-resolve.h"
@ -937,5 +939,5 @@ const NetDevVTable wireguard_vtable = {
.done = wireguard_done,
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = wireguard_verify,
.generate_mac = true,
.iftype = ARPHRD_NONE,
};

View File

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "missing_network.h"
#include "xfrm.h"
@ -29,5 +31,6 @@ const NetDevVTable xfrm_vtable = {
.object_size = sizeof(Xfrm),
.sections = NETDEV_COMMON_SECTIONS "Xfrm\0",
.fill_message_create = xfrm_fill_message_create,
.create_type = NETDEV_CREATE_STACKED
.create_type = NETDEV_CREATE_STACKED,
.iftype = ARPHRD_NONE,
};

View File

@ -981,15 +981,19 @@ void link_foreignize_routes(Link *link) {
static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) {
Route *route = userdata;
Link *link;
int r;
assert(route);
assert(route->link);
assert(route->manager || (route->link && route->link->manager));
link = route->link; /* This may be NULL. */
r = route_remove(route);
if (r < 0) {
log_link_warning_errno(route->link, r, "Could not remove route: %m");
link_enter_failed(route->link);
log_link_warning_errno(link, r, "Could not remove route: %m");
if (link)
link_enter_failed(link);
}
return 1;

View File

@ -1082,7 +1082,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('ip link show dropin-test')
print(output)
self.assertRegex(output, '00:50:56:c0:00:28')
# 00:50:56:c0:00:28 was requested, and the local bit is set by networkd.
self.assertRegex(output, '02:50:56:c0:00:28')
def test_match_udev_property(self):
copy_unit_to_networkd_unit_path('12-dummy.netdev', '13-not-match-udev-property.network', '14-match-udev-property.network')

View File

@ -58,21 +58,21 @@ DESCRIPTIONS = {
'If the partition is encrypted with LUKS or has dm-verity integrity data (see below), the '
'device mapper file will be named `/dev/mapper/root`.'),
'USR': (
'Any native, optionally in LUKS',
'Similar semantics to root partition, but just the `/usr/` partition.'),
'ROOT_VERITY': (
'A dm-verity superblock followed by hash data',
'Contains dm-verity integrity hash data for the matching root partition. If this feature is '
'used the partition UUID of the root partition should be the first 128 bits of the root hash '
'of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the '
'final 128 bits of it, so that the root partition and its Verity partition can be discovered '
'easily, simply by specifying the root hash.'),
'ROOT_VERITY': (
'A serialized JSON object, see below',
'Contains a root hash and a PKCS#7 signature for it, permitting signed dm-verity GPT images.'),
'USR_VERITY': (
'Any native, optionally in LUKS',
'Similar semantics to root partition, but just the `/usr/` partition.'),
'ROOT_VERITY_SIG': (
'A dm-verity superblock followed by hash data',
'Similar semantics to root Verity partition, but just for the `/usr/` partition.'),
'ROOT_VERITY_SIG': (
'A serialized JSON object, see below',
'Contains a root hash and a PKCS#7 signature for it, permitting signed dm-verity GPT images.'),
'USR_VERITY_SIG': (
'A serialized JSON object, see below',
'Similar semantics to root Verity signature partition, but just for the `/usr/` partition.'),