From: Yu Watanabe Date: Sun, 15 Dec 2019 13:46:19 +0000 (+0900) Subject: network: make Name= in [Match] support alternative names of interfaces X-Git-Tag: v245-rc1~263^2~3 X-Git-Url: http://git-history.diyao.me/?a=commitdiff_plain;h=572b21d96cabd5860b0670e98440b6cb99a4b749;p=systemd%2F.git network: make Name= in [Match] support alternative names of interfaces --- diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 148ddac913..ba266f9aaa 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -132,10 +132,9 @@ Name= - A whitespace-separated list of shell-style globs - matching the device name, as exposed by the udev property - INTERFACE. If the list is prefixed - with a "!", the test is inverted. + A whitespace-separated list of shell-style globs matching the device name, as exposed + by the udev property INTERFACE, or device's alternative names. 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 e370499209..7198fe4775 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -103,6 +103,18 @@ static bool net_condition_test_strv(char * const *patterns, const char *string) return has_positive_rule ? match : true; } +static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) { + if (net_condition_test_strv(patterns, ifname)) + return true; + + char * const *p; + STRV_FOREACH(p, alternative_names) + if (net_condition_test_strv(patterns, *p)) + return true; + + return false; +} + static int net_condition_test_property(char * const *match_property, sd_device *device) { char * const *p; @@ -166,6 +178,7 @@ bool net_match_config(Set *match_mac, sd_device *device, const struct ether_addr *dev_mac, const char *dev_name, + char * const *alternative_names, enum nl80211_iftype wifi_iftype, const char *ssid, const struct ether_addr *bssid) { @@ -196,7 +209,7 @@ bool net_match_config(Set *match_mac, if (!net_condition_test_strv(match_types, dev_type)) return false; - if (!net_condition_test_strv(match_names, dev_name)) + if (!net_condition_test_ifname(match_names, dev_name, alternative_names)) return false; if (!net_condition_test_property(match_property, device)) @@ -349,7 +362,7 @@ int config_parse_match_ifnames( return 0; } - if (!ifname_valid(word)) { + if (!ifname_valid_full(word, ltype)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", word); continue; diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 7875f690ee..a940b24a42 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -27,6 +27,7 @@ bool net_match_config(Set *match_mac, sd_device *device, const struct ether_addr *dev_mac, const char *dev_name, + char * const *alternative_names, enum nl80211_iftype wifi_iftype, const char *ssid, const struct ether_addr *bssid); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9ebc58f0c9..dcdab6c83e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -542,10 +542,10 @@ static int link_update_flags(Link *link, sd_netlink_message *m, bool force_updat static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { _cleanup_(link_unrefp) Link *link = NULL; - uint16_t type; const char *ifname, *kind = NULL; - int r, ifindex; unsigned short iftype; + int r, ifindex; + uint16_t type; assert(manager); assert(message); @@ -617,6 +617,10 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { if (r < 0) log_link_debug_errno(link, r, "MAC address not found for new device, continuing without"); + r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names); + if (r < 0 && r != -ENODATA) + return r; + if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0) return -ENOMEM; @@ -713,6 +717,7 @@ static Link *link_free(Link *link) { free(link->lldp_file); free(link->ifname); + strv_free(link->alternative_names); free(link->kind); free(link->ssid); @@ -2934,14 +2939,28 @@ static int link_configure_duid(Link *link) { return 0; } -int link_reconfigure(Link *link, bool force) { +static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) { Network *network; int r; if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER)) return 0; - r = network_get(link->manager, link->sd_device, link->ifname, + if (m) { + _cleanup_strv_free_ char **s = NULL; + + r = sd_netlink_message_get_errno(m); + if (r < 0) + return r; + + r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); + if (r < 0 && r != -ENODATA) + return r; + + strv_free_and_replace(link->alternative_names, s); + } + + r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names, &link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network); if (r == -ENOENT) { link_enter_unmanaged(link); @@ -2959,10 +2978,8 @@ int link_reconfigure(Link *link, bool force) { /* Dropping old .network file */ r = link_stop_clients(link, false); - if (r < 0) { - link_enter_failed(link); + if (r < 0) return r; - } if (link_dhcp4_server_enabled(link)) (void) sd_dhcp_server_stop(link->dhcp_server); @@ -3006,6 +3023,46 @@ int link_reconfigure(Link *link, bool force) { return 0; } +static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + r = link_reconfigure_internal(link, m, false); + if (r < 0) + link_enter_failed(link); + + return 1; +} + +static int link_force_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + int r; + + r = link_reconfigure_internal(link, m, true); + if (r < 0) + link_enter_failed(link); + + return 1; +} + +int link_reconfigure(Link *link, bool force) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, + link->ifindex); + if (r < 0) + return r; + + r = netlink_call_async(link->manager->rtnl, NULL, req, + force ? link_force_reconfigure_handler : link_reconfigure_handler, + link_netlink_destroy_callback, link); + if (r < 0) + return r; + + link_ref(link); + + return 0; +} + static int link_initialized_and_synced(Link *link) { Network *network; int r; @@ -3035,7 +3092,7 @@ static int link_initialized_and_synced(Link *link) { if (r < 0) return r; - r = network_get(link->manager, link->sd_device, link->ifname, + r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names, &link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network); if (r == -ENOENT) { link_enter_unmanaged(link); @@ -3080,8 +3137,23 @@ static int link_initialized_and_synced(Link *link) { } static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { + _cleanup_strv_free_ char **s = NULL; int r; + r = sd_netlink_message_get_errno(m); + if (r < 0) { + link_enter_failed(link); + return 0; + } + + r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); + if (r < 0 && r != -ENODATA) { + link_enter_failed(link); + return 0; + } + + strv_free_and_replace(link->alternative_names, s); + r = link_initialized_and_synced(link); if (r < 0) link_enter_failed(link); @@ -3414,9 +3486,11 @@ static int link_carrier_gained(Link *link) { if (r < 0) return r; if (r > 0) { - r = link_reconfigure(link, false); - if (r < 0) + r = link_reconfigure_internal(link, NULL, false); + if (r < 0) { + link_enter_failed(link); return r; + } } if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) { @@ -3520,6 +3594,7 @@ static int link_admin_state_up(Link *link) { } int link_update(Link *link, sd_netlink_message *m) { + _cleanup_strv_free_ char **s = NULL; struct ether_addr mac; const char *ifname; uint32_t mtu; @@ -3551,6 +3626,10 @@ int link_update(Link *link, sd_netlink_message *m) { return r; } + r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s); + if (r >= 0) + strv_free_and_replace(link->alternative_names, s); + r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu); if (r >= 0 && mtu > 0) { link->mtu = mtu; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 39ef475daf..172e483383 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -48,6 +48,7 @@ typedef struct Link { int ifindex; int master_ifindex; char *ifname; + char **alternative_names; char *kind; unsigned short iftype; char *state_file; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 9e0948fc2b..af51730008 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -34,7 +34,7 @@ Match.Type, config_parse_match_strv, Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype) Match.SSID, config_parse_match_strv, 0, offsetof(Network, match_ssid) Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match_bssid) -Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name) +Match.Name, config_parse_match_ifnames, 1, offsetof(Network, match_name) Match.Property, config_parse_match_property, 0, offsetof(Network, match_property) Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions) Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 181afbb4cd..e2e2999354 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -718,7 +718,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) { } int network_get(Manager *manager, sd_device *device, - const char *ifname, const struct ether_addr *address, + const char *ifname, char * const *alternative_names, const struct ether_addr *address, enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, Network **ret) { Network *network; @@ -731,7 +731,7 @@ int network_get(Manager *manager, sd_device *device, if (net_match_config(network->match_mac, 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, ifname, wlan_iftype, ssid, bssid)) { + device, address, ifname, alternative_names, wlan_iftype, ssid, bssid)) { if (network->match_name && device) { const char *attr; uint8_t name_assign_type = NET_NAME_UNKNOWN; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index aa74bb4ae7..bd3c96d972 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -297,8 +297,9 @@ 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, const struct ether_addr *mac, - enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, Network **ret); +int network_get(Manager *manager, sd_device *device, const char *ifname, char * const *alternative_names, + const struct ether_addr *mac, enum nl80211_iftype wlan_iftype, const char *ssid, + const struct ether_addr *bssid, Network **ret); int network_apply(Network *network, Link *link); void network_apply_anonymize_if_set(Network *network); diff --git a/src/network/test-network.c b/src/network/test-network.c index 873d996e4f..9c06860699 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -125,7 +125,7 @@ static void test_network_get(Manager *manager, sd_device *loopback) { /* let's assume that the test machine does not have a .network file that applies to the loopback device... */ - assert_se(network_get(manager, loopback, "lo", &mac, 0, NULL, NULL, &network) == -ENOENT); + assert_se(network_get(manager, loopback, "lo", NULL, &mac, 0, NULL, NULL, &network) == -ENOENT); assert_se(!network); } diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 6879cfee07..8d89f1af10 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -244,7 +244,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_path, link->match_driver, link->match_type, link->match_name, link->match_property, NULL, NULL, NULL, - device, NULL, NULL, 0, NULL, NULL)) { + device, NULL, NULL, NULL, 0, NULL, NULL)) { if (link->match_name && !strv_contains(link->match_name, "*")) { unsigned name_assign_type = NET_NAME_UNKNOWN;