From a67e0507c313531957b2f061e5a0ce17576defc7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 25 Nov 2021 20:59:48 +0900 Subject: [PATCH 1/4] network: veth: use SYNTHETIC_ERRNO() macro or use real error cause --- src/network/netdev/veth.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index cdbbf39361..8236a43315 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -58,20 +58,17 @@ 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; - } + if (r < 0) + return log_netdev_warning_errno(netdev, r, + "Failed to generate predictable MAC address for %s: %m", + v->ifname_peer); } return 0; From 9f0cf80dd007491698978dbfe38158d74c1c9526 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 7 Nov 2021 16:27:33 +0900 Subject: [PATCH 2/4] network/netdev: introduce .iftype to netdev vtable And disable .generate_mac flag for non-ether interfaces. --- src/network/netdev/bareudp.c | 4 ++++ src/network/netdev/batadv.c | 3 +++ src/network/netdev/bond.c | 4 ++++ src/network/netdev/bridge.c | 2 ++ src/network/netdev/dummy.c | 3 +++ src/network/netdev/geneve.c | 3 +++ src/network/netdev/ifb.c | 3 +++ src/network/netdev/ipvlan.c | 4 ++++ src/network/netdev/macsec.c | 2 ++ src/network/netdev/macvlan.c | 4 ++++ src/network/netdev/netdev.h | 3 +++ src/network/netdev/netdevsim.c | 3 +++ src/network/netdev/nlmon.c | 3 +++ src/network/netdev/tunnel.c | 20 ++++++++++++-------- src/network/netdev/tuntap.c | 2 ++ src/network/netdev/vcan.c | 4 +++- src/network/netdev/veth.c | 3 +++ src/network/netdev/vlan.c | 2 ++ src/network/netdev/vrf.c | 3 +++ src/network/netdev/vxcan.c | 3 ++- src/network/netdev/vxlan.c | 3 +++ src/network/netdev/wireguard.c | 4 +++- src/network/netdev/xfrm.c | 5 ++++- 23 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/network/netdev/bareudp.c b/src/network/netdev/bareudp.c index 8c0c895a0d..8ff0eb1360 100644 --- a/src/network/netdev/bareudp.c +++ b/src/network/netdev/bareudp.c @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later * Copyright © 2020 VMware, Inc. */ +#include +#include + #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, }; diff --git a/src/network/netdev/batadv.c b/src/network/netdev/batadv.c index 1d12fc79cc..f42f572a36 100644 --- a/src/network/netdev/batadv.c +++ b/src/network/netdev/batadv.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include +#include #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, }; diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c index 1b66ed837c..5d94aa1d68 100644 --- a/src/network/netdev/bond.c +++ b/src/network/netdev/bond.c @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include +#include + #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, }; diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c index a4d68985b8..2d60e441ec 100644 --- a/src/network/netdev/bridge.c +++ b/src/network/netdev/bridge.c @@ -2,6 +2,7 @@ #include #include +#include #include #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, }; diff --git a/src/network/netdev/dummy.c b/src/network/netdev/dummy.c index 754ee98952..00df1d2787 100644 --- a/src/network/netdev/dummy.c +++ b/src/network/netdev/dummy.c @@ -1,10 +1,13 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #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, }; diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c index 46f5ea41c8..224c17e979 100644 --- a/src/network/netdev/geneve.c +++ b/src/network/netdev/geneve.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include +#include #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, }; diff --git a/src/network/netdev/ifb.c b/src/network/netdev/ifb.c index 16ff49d7f0..d7ff44cb9e 100644 --- a/src/network/netdev/ifb.c +++ b/src/network/netdev/ifb.c @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later * Copyright © 2019 VMware, Inc. */ +#include + #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, }; diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index 92a8f583e3..d15766cd7b 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include +#include #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, }; diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c index b50d93710d..72689742fb 100644 --- a/src/network/netdev/macsec.c +++ b/src/network/netdev/macsec.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include #include #include @@ -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, }; diff --git a/src/network/netdev/macvlan.c b/src/network/netdev/macvlan.c index c295cae2cd..c41be6e78f 100644 --- a/src/network/netdev/macvlan.c +++ b/src/network/netdev/macvlan.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include +#include #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, }; diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 10dff0177f..c47ec4306b 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -159,6 +159,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; diff --git a/src/network/netdev/netdevsim.c b/src/network/netdev/netdevsim.c index b2814284a4..15d5c132f9 100644 --- a/src/network/netdev/netdevsim.c +++ b/src/network/netdev/netdevsim.c @@ -1,10 +1,13 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #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, }; diff --git a/src/network/netdev/nlmon.c b/src/network/netdev/nlmon.c index a8faed5b24..b6e2a40579 100644 --- a/src/network/netdev/nlmon.c +++ b/src/network/netdev/nlmon.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #include "nlmon.h" static int netdev_nlmon_verify(NetDev *netdev, const char *filename) { @@ -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, }; diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index cae2ef1a90..98986f4dc6 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -2,8 +2,9 @@ #include #include -#include +#include #include +#include #include #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, }; diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c index bb5a6b0cf5..e8310f6c9a 100644 --- a/src/network/netdev/tuntap.c +++ b/src/network/netdev/tuntap.c @@ -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, }; diff --git a/src/network/netdev/vcan.c b/src/network/netdev/vcan.c index 3621d4c5d8..380547ee1e 100644 --- a/src/network/netdev/vcan.c +++ b/src/network/netdev/vcan.c @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #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, }; diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index 8236a43315..ae52ae8efd 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include "veth.h" @@ -94,5 +96,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, }; diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c index de3eb721e9..af3e77963e 100644 --- a/src/network/netdev/vlan.c +++ b/src/network/netdev/vlan.c @@ -2,6 +2,7 @@ #include #include +#include #include #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, }; diff --git a/src/network/netdev/vrf.c b/src/network/netdev/vrf.c index 1ba1916f1a..b1b6707441 100644 --- a/src/network/netdev/vrf.c +++ b/src/network/netdev/vrf.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include +#include #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, }; diff --git a/src/network/netdev/vxcan.c b/src/network/netdev/vxcan.c index e4e32ff390..a0ba048eb1 100644 --- a/src/network/netdev/vxcan.c +++ b/src/network/netdev/vxcan.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #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, }; diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c index 6829017f80..30b0855598 100644 --- a/src/network/netdev/vxlan.c +++ b/src/network/netdev/vxlan.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include +#include #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, }; diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 1e90cad2e7..3734fa51c5 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -5,6 +5,8 @@ #include #include +#include +#include #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, }; diff --git a/src/network/netdev/xfrm.c b/src/network/netdev/xfrm.c index a407c54da4..4b7e73b37a 100644 --- a/src/network/netdev/xfrm.c +++ b/src/network/netdev/xfrm.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include + #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, }; From 5e20e1e3e3a2f9f4f91240f1a0a6a46bb1689747 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 7 Nov 2021 11:23:14 +0900 Subject: [PATCH 3/4] network/netdev: use "struct hw_addr_data" to store MAC address --- src/network/netdev/netdev-gperf.gperf | 4 ++-- src/network/netdev/netdev.c | 25 +++++++++---------------- src/network/netdev/netdev.h | 5 +++-- src/network/netdev/nlmon.c | 4 ++-- src/network/netdev/tuntap.c | 2 +- src/network/netdev/veth.c | 12 ++++++------ src/network/netdev/veth.h | 2 +- 7 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 878d15d6c8..d0f493b4ef 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -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 */ diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index b3db55f199..9d17ef9ee5 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -229,7 +229,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,8 +423,7 @@ 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; +int netdev_generate_hw_addr(const char *name, struct hw_addr_data *ret) { uint64_t result; size_t l, sz; uint8_t *v; @@ -434,10 +432,6 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) { assert(ifname); assert(ret); - mac = new0(struct ether_addr, 1); - if (!mac) - return -ENOMEM; - l = strlen(ifname); sz = sizeof(sd_id128_t) + l; v = newa(uint8_t, sz); @@ -456,13 +450,12 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) { result = siphash24(v, sz, HASH_KEY.bytes); assert_cc(ETH_ALEN <= sizeof(result)); - memcpy(mac->ether_addr_octet, &result, ETH_ALEN); + ret->length = ETH_ALEN; + memcpy(ret->bytes, &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); + ret->ether.ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ + ret->ether.ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ return 0; } @@ -494,8 +487,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,8 +806,8 @@ 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 (netdev->hw_addr.length == 0 && NETDEV_VTABLE(netdev)->generate_mac) { + r = netdev_generate_hw_addr(netdev->ifname, &netdev->hw_addr); if (r < 0) return log_netdev_error_errno(netdev, r, "Failed to generate predictable MAC address: %m"); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index c47ec4306b..5de2d630a6 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -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; @@ -197,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(const char *name, struct hw_addr_data *ret); int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb); int request_process_stacked_netdev(Request *req); diff --git a/src/network/netdev/nlmon.c b/src/network/netdev/nlmon.c index b6e2a40579..ff372092e6 100644 --- a/src/network/netdev/nlmon.c +++ b/src/network/netdev/nlmon.c @@ -8,9 +8,9 @@ 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; diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c index e8310f6c9a..6f099a1448 100644 --- a/src/network/netdev/tuntap.c +++ b/src/network/netdev/tuntap.c @@ -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.", diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index ae52ae8efd..e615ddfab5 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -6,6 +6,7 @@ #include #include +#include "netlink-util.h" #include "veth.h" static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { @@ -30,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"); } @@ -65,11 +66,11 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) { "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 (v->hw_addr_peer.length == 0) { + r = netdev_generate_hw_addr(v->ifname_peer, &v->hw_addr_peer); if (r < 0) return log_netdev_warning_errno(netdev, r, - "Failed to generate predictable MAC address for %s: %m", + "Failed to generate persistent hardware address for peer '%s': %m", v->ifname_peer); } @@ -86,7 +87,6 @@ static void veth_done(NetDev *n) { assert(v); free(v->ifname_peer); - free(v->mac_peer); } const NetDevVTable veth_vtable = { diff --git a/src/network/netdev/veth.h b/src/network/netdev/veth.h index 643f737a88..e0d6fd4352 100644 --- a/src/network/netdev/veth.h +++ b/src/network/netdev/veth.h @@ -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); From 007899f43e9f897ef7f3324768423ce04465d205 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 8 Nov 2021 12:41:47 +0900 Subject: [PATCH 4/4] 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. --- src/network/netdev/netdev.c | 78 ++++++++++++--------- src/network/netdev/netdev.h | 2 +- src/network/netdev/veth.c | 10 +-- test/test-network/systemd-networkd-tests.py | 3 +- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 9d17ef9ee5..2fd2659ddb 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -2,9 +2,11 @@ #include #include +#include #include #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" @@ -423,40 +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_generate_hw_addr(const char *name, struct hw_addr_data *ret) { - 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); - l = strlen(ifname); - sz = sizeof(sd_id128_t) + l; - v = newa(uint8_t, sz); + if (hw_addr->length == 0) { + uint64_t result; - /* fetch some persistent data unique to the machine */ - r = sd_id128_get_machine((sd_id128_t*) v); + /* HardwareAddress= is not specified. */ + + 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)); - ret->length = ETH_ALEN; - memcpy(ret->bytes, &result, ETH_ALEN); - - /* see eth_random_addr in the kernel */ - ret->ether.ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ - ret->ether.ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ - + *hw_addr = a; return 0; } @@ -806,12 +821,9 @@ int netdev_load_one(Manager *manager, const char *filename) { if (!netdev->filename) return log_oom(); - if (netdev->hw_addr.length == 0 && NETDEV_VTABLE(netdev)->generate_mac) { - r = netdev_generate_hw_addr(netdev->ifname, &netdev->hw_addr); - 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) diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 5de2d630a6..d480d125a6 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -198,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_generate_hw_addr(const char *name, struct hw_addr_data *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); diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index e615ddfab5..f1c05c6205 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -66,13 +66,9 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) { "Veth NetDev without peer name configured in %s. Ignoring", filename); - if (v->hw_addr_peer.length == 0) { - r = netdev_generate_hw_addr(v->ifname_peer, &v->hw_addr_peer); - if (r < 0) - return log_netdev_warning_errno(netdev, r, - "Failed to generate persistent hardware address for peer '%s': %m", - v->ifname_peer); - } + r = netdev_generate_hw_addr(netdev, v->ifname_peer, &v->hw_addr_peer); + if (r < 0) + return r; return 0; } diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 943582afea..cf8e445b37 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -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')