From daf0f8ca87284b847c40102dbaca0890fec2f971 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 23 May 2019 11:27:12 +0900 Subject: [PATCH 1/3] network: add NetDevVTable::generate_mac flag --- src/network/netdev/bond.c | 1 + src/network/netdev/dummy.c | 1 + src/network/netdev/geneve.c | 1 + src/network/netdev/ipvlan.c | 2 ++ src/network/netdev/macsec.c | 1 + src/network/netdev/macvlan.c | 2 ++ src/network/netdev/netdev.c | 2 +- src/network/netdev/netdev.h | 3 +++ src/network/netdev/netdevsim.c | 1 + src/network/netdev/tunnel.c | 10 ++++++++++ src/network/netdev/vcan.c | 1 + src/network/netdev/veth.c | 1 + src/network/netdev/vrf.c | 1 + src/network/netdev/vxcan.c | 1 + src/network/netdev/vxlan.c | 1 + src/network/netdev/wireguard.c | 1 + 16 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c index 240cfe34e2..a85c9e33ec 100644 --- a/src/network/netdev/bond.c +++ b/src/network/netdev/bond.c @@ -592,4 +592,5 @@ const NetDevVTable bond_vtable = { .sections = "Match\0NetDev\0Bond\0", .fill_message_create = netdev_bond_fill_message_create, .create_type = NETDEV_CREATE_MASTER, + .generate_mac = true, }; diff --git a/src/network/netdev/dummy.c b/src/network/netdev/dummy.c index aded1c589f..091a54ff39 100644 --- a/src/network/netdev/dummy.c +++ b/src/network/netdev/dummy.c @@ -6,4 +6,5 @@ const NetDevVTable dummy_vtable = { .object_size = sizeof(Dummy), .sections = "Match\0NetDev\0", .create_type = NETDEV_CREATE_INDEPENDENT, + .generate_mac = true, }; diff --git a/src/network/netdev/geneve.c b/src/network/netdev/geneve.c index 3dc8f083cc..611f9b2f6d 100644 --- a/src/network/netdev/geneve.c +++ b/src/network/netdev/geneve.c @@ -355,4 +355,5 @@ const NetDevVTable geneve_vtable = { .create = netdev_geneve_create, .create_type = NETDEV_CREATE_INDEPENDENT, .config_verify = netdev_geneve_verify, + .generate_mac = true, }; diff --git a/src/network/netdev/ipvlan.c b/src/network/netdev/ipvlan.c index f48cb0231a..45dfe17777 100644 --- a/src/network/netdev/ipvlan.c +++ b/src/network/netdev/ipvlan.c @@ -77,6 +77,7 @@ const NetDevVTable ipvlan_vtable = { .sections = "Match\0NetDev\0IPVLAN\0", .fill_message_create = netdev_ipvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .generate_mac = true, }; const NetDevVTable ipvtap_vtable = { @@ -85,6 +86,7 @@ const NetDevVTable ipvtap_vtable = { .sections = "Match\0NetDev\0IPVTAP\0", .fill_message_create = netdev_ipvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .generate_mac = true, }; IPVlanMode link_get_ipvlan_mode(Link *link) { diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c index c82a6fd0ac..740d885339 100644 --- a/src/network/netdev/macsec.c +++ b/src/network/netdev/macsec.c @@ -1246,4 +1246,5 @@ const NetDevVTable macsec_vtable = { .done = macsec_done, .create_type = NETDEV_CREATE_STACKED, .config_verify = netdev_macsec_verify, + .generate_mac = true, }; diff --git a/src/network/netdev/macvlan.c b/src/network/netdev/macvlan.c index 871f0201a8..e13c3af9fd 100644 --- a/src/network/netdev/macvlan.c +++ b/src/network/netdev/macvlan.c @@ -61,6 +61,7 @@ const NetDevVTable macvtap_vtable = { .sections = "Match\0NetDev\0MACVTAP\0", .fill_message_create = netdev_macvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .generate_mac = true, }; const NetDevVTable macvlan_vtable = { @@ -69,4 +70,5 @@ const NetDevVTable macvlan_vtable = { .sections = "Match\0NetDev\0MACVLAN\0", .fill_message_create = netdev_macvlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, + .generate_mac = true, }; diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 3968ab5495..1c307a3125 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -734,7 +734,7 @@ int netdev_load_one(Manager *manager, const char *filename) { if (!netdev->filename) return log_oom(); - if (!netdev->mac && !IN_SET(netdev->kind, NETDEV_KIND_VLAN, NETDEV_KIND_BRIDGE)) { + 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, diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index dcf072ce94..8295ba1966 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -131,6 +131,9 @@ typedef struct NetDevVTable { /* verify that compulsory configuration options were specified */ int (*config_verify)(NetDev *netdev, const char *filename); + + /* Generate MAC address or not When MACAddress= is not specified. */ + bool generate_mac; } NetDevVTable; extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX]; diff --git a/src/network/netdev/netdevsim.c b/src/network/netdev/netdevsim.c index 8caba67600..3b9d875183 100644 --- a/src/network/netdev/netdevsim.c +++ b/src/network/netdev/netdevsim.c @@ -7,4 +7,5 @@ const NetDevVTable netdevsim_vtable = { .object_size = sizeof(NetDevSim), .sections = "Match\0NetDev\0", .create_type = NETDEV_CREATE_INDEPENDENT, + .generate_mac = true, }; diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index e69a009c31..1572836b69 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -778,6 +778,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, }; const NetDevVTable sit_vtable = { @@ -787,6 +788,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, }; const NetDevVTable vti_vtable = { @@ -796,6 +798,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, }; const NetDevVTable vti6_vtable = { @@ -805,6 +808,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, }; const NetDevVTable gre_vtable = { @@ -814,6 +818,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, }; const NetDevVTable gretap_vtable = { @@ -823,6 +828,7 @@ const NetDevVTable gretap_vtable = { .fill_message_create = netdev_gre_erspan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, .config_verify = netdev_tunnel_verify, + .generate_mac = true, }; const NetDevVTable ip6gre_vtable = { @@ -832,6 +838,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, }; const NetDevVTable ip6gretap_vtable = { @@ -841,6 +848,7 @@ const NetDevVTable ip6gretap_vtable = { .fill_message_create = netdev_ip6gre_fill_message_create, .create_type = NETDEV_CREATE_STACKED, .config_verify = netdev_tunnel_verify, + .generate_mac = true, }; const NetDevVTable ip6tnl_vtable = { @@ -850,6 +858,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, }; const NetDevVTable erspan_vtable = { @@ -859,4 +868,5 @@ const NetDevVTable erspan_vtable = { .fill_message_create = netdev_gre_erspan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, .config_verify = netdev_tunnel_verify, + .generate_mac = true, }; diff --git a/src/network/netdev/vcan.c b/src/network/netdev/vcan.c index 574d1cad31..f6a4dbb098 100644 --- a/src/network/netdev/vcan.c +++ b/src/network/netdev/vcan.c @@ -6,4 +6,5 @@ const NetDevVTable vcan_vtable = { .object_size = sizeof(VCan), .sections = "Match\0NetDev\0", .create_type = NETDEV_CREATE_INDEPENDENT, + .generate_mac = true, }; diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c index a0a0b8e39e..e996b49b0a 100644 --- a/src/network/netdev/veth.c +++ b/src/network/netdev/veth.c @@ -92,4 +92,5 @@ const NetDevVTable veth_vtable = { .fill_message_create = netdev_veth_fill_message_create, .create_type = NETDEV_CREATE_INDEPENDENT, .config_verify = netdev_veth_verify, + .generate_mac = true, }; diff --git a/src/network/netdev/vrf.c b/src/network/netdev/vrf.c index 5efab537cc..596a91453c 100644 --- a/src/network/netdev/vrf.c +++ b/src/network/netdev/vrf.c @@ -30,4 +30,5 @@ const NetDevVTable vrf_vtable = { .sections = "Match\0NetDev\0VRF\0", .fill_message_create = netdev_vrf_fill_message_create, .create_type = NETDEV_CREATE_MASTER, + .generate_mac = true, }; diff --git a/src/network/netdev/vxcan.c b/src/network/netdev/vxcan.c index c5dd5df51c..79f47690ad 100644 --- a/src/network/netdev/vxcan.c +++ b/src/network/netdev/vxcan.c @@ -70,4 +70,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, }; diff --git a/src/network/netdev/vxlan.c b/src/network/netdev/vxlan.c index e24537083b..bba58e8aaf 100644 --- a/src/network/netdev/vxlan.c +++ b/src/network/netdev/vxlan.c @@ -380,4 +380,5 @@ const NetDevVTable vxlan_vtable = { .fill_message_create = netdev_vxlan_fill_message_create, .create_type = NETDEV_CREATE_STACKED, .config_verify = netdev_vxlan_verify, + .generate_mac = true, }; diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 91fcee1401..154ca3b7a4 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -978,4 +978,5 @@ const NetDevVTable wireguard_vtable = { .done = wireguard_done, .create_type = NETDEV_CREATE_INDEPENDENT, .config_verify = wireguard_verify, + .generate_mac = true, }; From d61e4c5b6e312020b22aca5acd3765df1ce61f27 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 23 May 2019 11:36:25 +0900 Subject: [PATCH 2/3] network: add nlmon support nlmon is a Netlink monitor device. --- man/systemd.netdev.xml | 5 ++++- src/libsystemd/sd-netlink/netlink-types.c | 1 + src/libsystemd/sd-netlink/netlink-types.h | 1 + src/network/meson.build | 2 ++ src/network/netdev/netdev.c | 3 +++ src/network/netdev/netdev.h | 1 + src/network/netdev/nlmon.c | 22 ++++++++++++++++++++++ src/network/netdev/nlmon.h | 14 ++++++++++++++ src/network/networkd-link.c | 7 +++++-- 9 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/network/netdev/nlmon.c create mode 100644 src/network/netdev/nlmon.h diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 26a5dbbd1e..066793c6e6 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -171,7 +171,10 @@ WireGuard Secure Network Tunnel. netdevsim - A simulator. This simulated networking device is used for testing various networking APIs and at this time is particularly focused on testing hardware offloading related interfaces. + A simulator. This simulated networking device is used for testing various networking APIs and at this time is particularly focused on testing hardware offloading related interfaces. + + nlmon + A Netlink monitor device. Use an nlmon device when you want to monitor system Netlink messages. fou Foo-over-UDP tunneling. diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 7fd3efbd35..35ca843569 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -357,6 +357,7 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_NETDEVSIM] = "netdevsim", [NL_UNION_LINK_INFO_DATA_CAN] = "can", [NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec", + [NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 8585280463..fed43ae43c 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -82,6 +82,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_NETDEVSIM, NL_UNION_LINK_INFO_DATA_CAN, NL_UNION_LINK_INFO_DATA_MACSEC, + NL_UNION_LINK_INFO_DATA_NLMON, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; diff --git a/src/network/meson.build b/src/network/meson.build index 0bcf7f4a81..feeb98cb07 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -13,6 +13,8 @@ sources = files(''' netdev/macvlan.h netdev/netdev.c netdev/netdev.h + netdev/nlmon.c + netdev/nlmon.h netdev/tunnel.c netdev/tunnel.h netdev/tuntap.c diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 1c307a3125..5429237603 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -19,6 +19,7 @@ #include "netdev/macvlan.h" #include "netdev/netdev.h" #include "netdev/netdevsim.h" +#include "netdev/nlmon.h" #include "netdev/tunnel.h" #include "netdev/tuntap.h" #include "netdev/vcan.h" @@ -70,6 +71,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_ERSPAN] = &erspan_vtable, [NETDEV_KIND_L2TP] = &l2tptnl_vtable, [NETDEV_KIND_MACSEC] = &macsec_vtable, + [NETDEV_KIND_NLMON] = &nlmon_vtable, }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -104,6 +106,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_ERSPAN] = "erspan", [NETDEV_KIND_L2TP] = "l2tp", [NETDEV_KIND_MACSEC] = "macsec", + [NETDEV_KIND_NLMON] = "nlmon", }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 8295ba1966..57fabbef40 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -49,6 +49,7 @@ typedef enum NetDevKind { NETDEV_KIND_ERSPAN, NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, + NETDEV_KIND_NLMON, _NETDEV_KIND_MAX, _NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */ _NETDEV_KIND_INVALID = -1 diff --git a/src/network/netdev/nlmon.c b/src/network/netdev/nlmon.c new file mode 100644 index 0000000000..c58a6b51ca --- /dev/null +++ b/src/network/netdev/nlmon.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "netdev/nlmon.h" + +static int netdev_nlmon_verify(NetDev *netdev, const char *filename) { + assert(netdev); + assert(filename); + + if (netdev->mac) { + log_netdev_warning(netdev, "%s: MACAddress= is not supported. Ignoring", filename); + netdev->mac = mfree(netdev->mac); + } + + return 0; +} + +const NetDevVTable nlmon_vtable = { + .object_size = sizeof(NLMon), + .sections = "Match\0NetDev\0", + .create_type = NETDEV_CREATE_INDEPENDENT, + .config_verify = netdev_nlmon_verify, +}; diff --git a/src/network/netdev/nlmon.h b/src/network/netdev/nlmon.h new file mode 100644 index 0000000000..590b62d863 --- /dev/null +++ b/src/network/netdev/nlmon.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +typedef struct NLMon NLMon; + +#include "netdev/netdev.h" + +struct NLMon { + NetDev meta; +}; + +DEFINE_NETDEV_CAST(NLMON, NLMon); + +extern const NetDevVTable nlmon_vtable; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 924cc8ce6a..9486329b9a 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -132,7 +132,7 @@ bool link_ipv4ll_enabled(Link *link, AddressFamilyBoolean mask) { if (!link->network) return false; - if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "ip6gre", "ip6tnl", "sit", "vti", "vti6", "can", "vcan", "vxcan")) + if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "ip6gre", "ip6tnl", "sit", "vti", "vti6", "can", "vcan", "vxcan", "nlmon")) return false; /* L3 or L3S mode do not support ARP. */ @@ -142,6 +142,9 @@ bool link_ipv4ll_enabled(Link *link, AddressFamilyBoolean mask) { if (link->network->bond) return false; + if (link->network->bond) + return false; + return link->network->link_local & mask; } @@ -157,7 +160,7 @@ static bool link_ipv6ll_enabled(Link *link) { if (!link->network) return false; - if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "can", "vcan", "vxcan")) + if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "sit", "vti", "can", "vcan", "vxcan", "nlmon")) return false; if (link->network->bond) From 811f33d0b164f282b3dc8b4b811464210b579fd8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 23 May 2019 11:37:53 +0900 Subject: [PATCH 3/3] test-network: add a basic test for nlmon --- test/test-network/conf/25-nlmon.netdev | 3 +++ test/test-network/conf/25-nlmon.network | 6 ++++++ test/test-network/systemd-networkd-tests.py | 8 ++++++++ 3 files changed, 17 insertions(+) create mode 100644 test/test-network/conf/25-nlmon.netdev create mode 100644 test/test-network/conf/25-nlmon.network diff --git a/test/test-network/conf/25-nlmon.netdev b/test/test-network/conf/25-nlmon.netdev new file mode 100644 index 0000000000..2ae6b12425 --- /dev/null +++ b/test/test-network/conf/25-nlmon.netdev @@ -0,0 +1,3 @@ +[NetDev] +Kind=nlmon +Name=nlmon99 diff --git a/test/test-network/conf/25-nlmon.network b/test/test-network/conf/25-nlmon.network new file mode 100644 index 0000000000..8247f65307 --- /dev/null +++ b/test/test-network/conf/25-nlmon.network @@ -0,0 +1,6 @@ +[Match] +Name=nlmon99 + +[Network] +LinkLocalAddressing=yes +IPv6AcceptRA=no diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 2eda211285..4d5099d8a7 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -248,6 +248,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): 'isataptun99', 'macvlan99', 'macvtap99', + 'nlmon99', 'sittun96', 'sittun97', 'sittun98', @@ -318,6 +319,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): '25-macsec.key', '25-macsec.netdev', '25-macsec.network', + '25-nlmon.netdev', + '25-nlmon.network', '25-sit-tunnel-local-any.netdev', '25-sit-tunnel-remote-any.netdev', '25-sit-tunnel.netdev', @@ -975,6 +978,11 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): self.assertRegex(output, 'RXSC: 8c16456c83a90002, state on') self.assertRegex(output, '0: PN [0-9]*, state off, key 02030400000000000000000000000000') + def test_nlmon(self): + self.copy_unit_to_networkd_unit_path('25-nlmon.netdev', '25-nlmon.network') + self.start_networkd() + + self.wait_online(['nlmon99:carrier']) class NetworkdL2TPTests(unittest.TestCase, Utilities):