From ef62949a23a2d6dc722659cc527f6e0006135dc9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 27 Feb 2020 21:56:36 +0900 Subject: network: make Type=ether match based on iftype This makes Type= can match the type shown in networkctl. Closes #14952. --- man/systemd.link.xml | 6 +++--- src/libsystemd-network/network-internal.c | 30 +++++++++++++++++++++++++++--- src/libsystemd-network/network-internal.h | 2 ++ src/libsystemd/sd-netlink/netlink-util.c | 23 +++++++++++++++++++++++ src/libsystemd/sd-netlink/netlink-util.h | 1 + src/network/networkctl.c | 23 +---------------------- src/network/networkd-link.c | 4 ++-- src/network/networkd-network.c | 4 ++-- src/network/networkd-network.h | 2 +- src/network/test-network.c | 2 +- src/udev/net/link-config.c | 13 +++++++++++-- 11 files changed, 74 insertions(+), 36 deletions(-) diff --git a/man/systemd.link.xml b/man/systemd.link.xml index 3574dd41a1..130cc78693 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -121,9 +121,9 @@ Type= - A whitespace-separated list of shell-style globs matching the device type, as exposed by - the udev property DEVTYPE. If the list is prefixed with a "!", the test is - inverted. + A whitespace-separated list of shell-style globs matching the device type, as exposed by + networkctl status. If the list is prefixed with a "!", the test is inverted. + diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 0bf0b0e552..13a0a5d929 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -8,6 +8,7 @@ #include "sd-ndisc.h" #include "alloc-util.h" +#include "arphrd-list.h" #include "condition.h" #include "conf-parser.h" #include "device-util.h" @@ -166,6 +167,27 @@ static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype); +char *link_get_type_string(unsigned short iftype, sd_device *device) { + const char *t, *devtype; + char *p; + + if (device && + sd_device_get_devtype(device, &devtype) >= 0 && + !isempty(devtype)) + return strdup(devtype); + + t = arphrd_to_name(iftype); + if (!t) + return NULL; + + p = strdup(t); + if (!p) + return NULL; + + ascii_strlower(p); + return p; +} + bool net_match_config(Set *match_mac, Set *match_permanent_mac, char * const *match_paths, @@ -176,6 +198,7 @@ bool net_match_config(Set *match_mac, char * const *match_wifi_iftype, char * const *match_ssid, Set *match_bssid, + unsigned short iftype, sd_device *device, const struct ether_addr *dev_mac, const struct ether_addr *dev_permanent_mac, @@ -185,13 +208,14 @@ bool net_match_config(Set *match_mac, const char *ssid, const struct ether_addr *bssid) { - const char *dev_path = NULL, *dev_driver = NULL, *dev_type = NULL, *mac_str; + const char *dev_path = NULL, *dev_driver = NULL, *mac_str; + _cleanup_free_ char *dev_type; + + dev_type = link_get_type_string(iftype, device); if (device) { (void) sd_device_get_property_value(device, "ID_PATH", &dev_path); (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &dev_driver); - (void) sd_device_get_devtype(device, &dev_type); - if (!dev_name) (void) sd_device_get_sysname(device, &dev_name); if (!dev_mac && diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index dff6c8831a..593bad2230 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -15,6 +15,7 @@ #define LINK_BRIDGE_PORT_PRIORITY_INVALID 128 #define LINK_BRIDGE_PORT_PRIORITY_MAX 63 +char *link_get_type_string(unsigned short iftype, sd_device *device); bool net_match_config(Set *match_mac, Set *match_permanent_mac, char * const *match_path, @@ -25,6 +26,7 @@ bool net_match_config(Set *match_mac, char * const *match_wifi_iftype, char * const *match_ssid, Set *match_bssid, + unsigned short iftype, sd_device *device, const struct ether_addr *dev_mac, const struct ether_addr *dev_permanent_mac, diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 9c6a5d29f6..7387cffaa3 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -203,6 +203,29 @@ int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name) { return ret; } +int rtnl_get_link_iftype(sd_netlink **rtnl, int ifindex, unsigned short *ret) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL; + int r; + + if (!*rtnl) { + r = sd_netlink_open(rtnl); + if (r < 0) + return r; + } + + r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex); + if (r < 0) + return r; + + r = sd_netlink_call(*rtnl, message, 0, &reply); + if (r == -EINVAL) + return -ENODEV; /* The device does not exist */ + if (r < 0) + return r; + + return sd_rtnl_message_link_get_type(reply, ret); +} + int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) { struct nlmsgerr *err; int r; diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 55bc12712a..d2d8334b21 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -52,6 +52,7 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names); int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names); int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name); +int rtnl_get_link_iftype(sd_netlink **rtnl, int ifindex, unsigned short *ret); int rtnl_log_parse_error(int r); int rtnl_log_create_error(int r); diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 078cf1f0cf..a9390b8689 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -16,7 +16,6 @@ #include "sd-network.h" #include "alloc-util.h" -#include "arphrd-list.h" #include "bus-common-errors.h" #include "bus-error.h" #include "bus-util.h" @@ -35,6 +34,7 @@ #include "macro.h" #include "main-func.h" #include "netlink-util.h" +#include "network-internal.h" #include "pager.h" #include "parse-util.h" #include "pretty-print.h" @@ -66,27 +66,6 @@ static bool arg_stats = false; static bool arg_full = false; static unsigned arg_lines = 10; -static char *link_get_type_string(unsigned short iftype, sd_device *d) { - const char *t, *devtype; - char *p; - - if (d && - sd_device_get_devtype(d, &devtype) >= 0 && - !isempty(devtype)) - return strdup(devtype); - - t = arphrd_to_name(iftype); - if (!t) - return NULL; - - p = strdup(t); - if (!p) - return NULL; - - ascii_strlower(p); - return p; -} - static void operational_state_to_color(const char *name, const char *state, const char **on, const char **off) { assert(on); assert(off); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 3dca043d99..99d4b29c31 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3041,7 +3041,7 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for strv_free_and_replace(link->alternative_names, s); } - r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names, + r = network_get(link->manager, link->iftype, link->sd_device, link->ifname, link->alternative_names, &link->mac, &link->permanent_mac, link->wlan_iftype, link->ssid, &link->bssid, &network); if (r == -ENOENT) { link_enter_unmanaged(link); @@ -3177,7 +3177,7 @@ static int link_initialized_and_synced(Link *link) { if (r < 0) return r; - r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names, + r = network_get(link->manager, link->iftype, link->sd_device, link->ifname, link->alternative_names, &link->mac, &link->permanent_mac, link->wlan_iftype, link->ssid, &link->bssid, &network); if (r == -ENOENT) { link_enter_unmanaged(link); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index b06ae75c05..2e716b291e 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -730,7 +730,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) { return 0; } -int network_get(Manager *manager, sd_device *device, +int network_get(Manager *manager, unsigned short iftype, sd_device *device, const char *ifname, char * const *alternative_names, const struct ether_addr *address, const struct ether_addr *permanent_address, enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, @@ -746,7 +746,7 @@ int network_get(Manager *manager, sd_device *device, network->match_path, network->match_driver, network->match_type, network->match_name, network->match_property, network->match_wlan_iftype, network->match_ssid, network->match_bssid, - device, address, permanent_address, + iftype, device, address, permanent_address, ifname, alternative_names, wlan_iftype, ssid, bssid)) { if (network->match_name && device) { const char *attr; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 66f010a793..266e40cef5 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -303,7 +303,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi int network_verify(Network *network); int network_get_by_name(Manager *manager, const char *name, Network **ret); -int network_get(Manager *manager, sd_device *device, const char *ifname, char * const *alternative_names, +int network_get(Manager *manager, unsigned short iftype, sd_device *device, const char *ifname, char * const *alternative_names, const struct ether_addr *mac, const struct ether_addr *permanent_mac, enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, Network **ret); diff --git a/src/network/test-network.c b/src/network/test-network.c index b29523b318..e23bec7680 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -126,7 +126,7 @@ static void test_network_get(Manager *manager, sd_device *loopback) { /* Let's hope that the test machine does not have a .network file that applies to loopback deviceā€¦ * But it is still possible, so let's allow that case too. */ - r = network_get(manager, loopback, "lo", NULL, &mac, &mac, 0, NULL, NULL, &network); + r = network_get(manager, 0, loopback, "lo", NULL, &mac, &mac, 0, NULL, NULL, &network); if (r == -ENOENT) /* The expected case */ assert_se(!network); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index bcf9be1a0d..0332e99269 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -236,9 +236,10 @@ bool link_config_should_reload(link_config_ctx *ctx) { int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) { struct ether_addr permanent_mac = {}; + unsigned short iftype = 0; link_config *link; const char *name; - int r; + int ifindex, r; assert(ctx); assert(device); @@ -248,6 +249,14 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) if (r < 0) return r; + r = sd_device_get_ifindex(device, &ifindex); + if (r < 0) + return r; + + r = rtnl_get_link_iftype(&ctx->rtnl, ifindex, &iftype); + if (r < 0) + return r; + r = ethtool_get_permanent_macaddr(&ctx->ethtool_fd, name, &permanent_mac); if (r < 0) log_device_debug_errno(device, r, "Failed to get permanent MAC address, ignoring: %m"); @@ -255,7 +264,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) LIST_FOREACH(links, link, ctx->links) { if (net_match_config(link->match_mac, link->match_permanent_mac, link->match_path, link->match_driver, link->match_type, link->match_name, link->match_property, NULL, NULL, NULL, - device, NULL, &permanent_mac, NULL, NULL, 0, NULL, NULL)) { + iftype, device, NULL, &permanent_mac, NULL, NULL, 0, NULL, NULL)) { if (link->match_name && !strv_contains(link->match_name, "*")) { unsigned name_assign_type = NET_NAME_UNKNOWN; -- cgit v1.2.1