]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: read driver name from ethtool
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 3 Jun 2020 07:19:29 +0000 (16:19 +0900)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Jun 2020 16:25:37 +0000 (18:25 +0200)
To make Driver= in [Match] section work in containers.

Note that ID_NET_DRIVER= property in udev database is set with the
result of the ethtool. So, this should not change anything for
non-container cases.

Closes #15678.

src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-network.c
src/network/networkd-network.h
src/network/test-network.c
src/udev/net/link-config.c

index 3bdabd99fbd875a9a06548c58723cf5a63f8b386..459d13ad7dfe299d825d0e57e1d81755f12877a1 100644 (file)
@@ -192,30 +192,34 @@ bool net_match_config(Set *match_mac,
                       Set *match_permanent_mac,
                       char * const *match_paths,
                       char * const *match_drivers,
-                      char * const *match_types,
+                      char * const *match_iftypes,
                       char * const *match_names,
                       char * const *match_property,
                       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,
+                      const char *dev_driver,
+                      unsigned short dev_iftype,
                       const char *dev_name,
                       char * const *alternative_names,
-                      enum nl80211_iftype wifi_iftype,
-                      const char *ssid,
-                      const struct ether_addr *bssid) {
+                      enum nl80211_iftype dev_wifi_iftype,
+                      const char *dev_ssid,
+                      const struct ether_addr *dev_bssid) {
 
-        const char *dev_path = NULL, *dev_driver = NULL, *mac_str;
-        _cleanup_free_ char *dev_type;
+        _cleanup_free_ char *dev_iftype_str;
+        const char *dev_path = NULL;
 
-        dev_type = link_get_type_string(iftype, device);
+        dev_iftype_str = link_get_type_string(dev_iftype, device);
 
         if (device) {
+                const char *mac_str;
+
                 (void) sd_device_get_property_value(device, "ID_PATH", &dev_path);
-                (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &dev_driver);
+                if (!dev_driver)
+                        (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &dev_driver);
                 if (!dev_name)
                         (void) sd_device_get_sysname(device, &dev_name);
                 if (!dev_mac &&
@@ -238,7 +242,7 @@ bool net_match_config(Set *match_mac,
         if (!net_condition_test_strv(match_drivers, dev_driver))
                 return false;
 
-        if (!net_condition_test_strv(match_types, dev_type))
+        if (!net_condition_test_strv(match_iftypes, dev_iftype_str))
                 return false;
 
         if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
@@ -247,13 +251,13 @@ bool net_match_config(Set *match_mac,
         if (!net_condition_test_property(match_property, device))
                 return false;
 
-        if (!net_condition_test_strv(match_wifi_iftype, wifi_iftype_to_string(wifi_iftype)))
+        if (!net_condition_test_strv(match_wifi_iftype, wifi_iftype_to_string(dev_wifi_iftype)))
                 return false;
 
-        if (!net_condition_test_strv(match_ssid, ssid))
+        if (!net_condition_test_strv(match_ssid, dev_ssid))
                 return false;
 
-        if (match_bssid && (!bssid || !set_contains(match_bssid, bssid)))
+        if (match_bssid && (!dev_bssid || !set_contains(match_bssid, dev_bssid)))
                 return false;
 
         return true;
index c413afc7d5d4fd32c203b937668418fbbb33e3cc..aa61bc2614dbf3b4471b5353c3b28d0bffbf5830 100644 (file)
 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,
-                      char * const *match_driver,
-                      char * const *match_type,
-                      char * const *match_name,
+                      char * const *match_paths,
+                      char * const *match_drivers,
+                      char * const *match_iftypes,
+                      char * const *match_names,
                       char * const *match_property,
                       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,
+                      const char *dev_driver,
+                      unsigned short dev_iftype,
                       const char *dev_name,
                       char * const *alternative_names,
-                      enum nl80211_iftype wifi_iftype,
-                      const char *ssid,
-                      const struct ether_addr *bssid);
+                      enum nl80211_iftype dev_wifi_iftype,
+                      const char *dev_ssid,
+                      const struct ether_addr *dev_bssid);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
 CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
index 214604cd9b93d41eddf6ba314301914968d5b646..6ca6bfa8e40454b82fab59ffc998391ee2ccb217 100644 (file)
@@ -618,10 +618,14 @@ 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 = ethtool_get_permanent_macaddr(NULL, link->ifname, &link->permanent_mac);
+        r = ethtool_get_permanent_macaddr(&manager->ethtool_fd, link->ifname, &link->permanent_mac);
         if (r < 0)
                 log_link_debug_errno(link, r, "Permanent MAC address not found for new device, continuing without: %m");
 
+        r = ethtool_get_driver(&manager->ethtool_fd, link->ifname, &link->driver);
+        if (r < 0)
+                log_link_debug_errno(link, r, "Failed to get driver, continuing without: %m");
+
         r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names);
         if (r < 0 && r != -ENODATA)
                 return r;
@@ -725,6 +729,7 @@ static Link *link_free(Link *link) {
         strv_free(link->alternative_names);
         free(link->kind);
         free(link->ssid);
+        free(link->driver);
 
         (void) unlink(link->state_file);
         free(link->state_file);
@@ -3139,8 +3144,10 @@ 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->iftype, link->sd_device, link->ifname, link->alternative_names,
-                        &link->mac, &link->permanent_mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
+        r = network_get(link->manager, link->iftype, link->sd_device,
+                        link->ifname, link->alternative_names, link->driver,
+                        &link->mac, &link->permanent_mac,
+                        link->wlan_iftype, link->ssid, &link->bssid, &network);
         if (r == -ENOENT) {
                 link_enter_unmanaged(link);
                 return 0;
@@ -3275,8 +3282,10 @@ static int link_initialized_and_synced(Link *link) {
                 if (r < 0)
                         return r;
 
-                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);
+                r = network_get(link->manager, link->iftype, link->sd_device,
+                                link->ifname, link->alternative_names, link->driver,
+                                &link->mac, &link->permanent_mac,
+                                link->wlan_iftype, link->ssid, &link->bssid, &network);
                 if (r == -ENOENT) {
                         link_enter_unmanaged(link);
                         return 0;
index c793a37df74bc276c7b02f1366c5bcc5d310df97..b1a8c432aa32453a805445e3695bbd2a306a1703 100644 (file)
@@ -66,6 +66,7 @@ typedef struct Link {
         struct in6_addr ipv6ll_address;
         uint32_t mtu;
         sd_device *sd_device;
+        char *driver;
 
         /* wlan */
         enum nl80211_iftype wlan_iftype;
index 3142f6ae868fb692680e1467a68902a38cce5dad..0f67c106c3efb11409fe196287a4b13414d5d95e 100644 (file)
@@ -1790,6 +1790,7 @@ int manager_new(Manager **ret) {
         *m = (Manager) {
                 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
                 .manage_foreign_routes = true,
+                .ethtool_fd = -1,
         };
 
         m->state_file = strdup("/run/systemd/netif/state");
@@ -1900,6 +1901,8 @@ void manager_free(Manager *m) {
         free(m->dynamic_timezone);
         free(m->dynamic_hostname);
 
+        safe_close(m->ethtool_fd);
+
         free(m);
 }
 
index 6ee023353749f5d76a1df2e669a37926d7e59aa5..0b3ce911c8c439da76f0b21c283e27c6e5d2de14 100644 (file)
@@ -26,6 +26,7 @@ struct Manager {
         sd_bus *bus;
         sd_device_monitor *device_monitor;
         Hashmap *polkit_registry;
+        int ethtool_fd;
 
         bool enumerating:1;
         bool dirty:1;
index 50e50fd945b44a6b1707876601ddf4e427132b40..2fdaafd040d657b68f72c5102e01b3f0918d6a06 100644 (file)
@@ -776,8 +776,8 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) {
 }
 
 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,
+                const char *ifname, char * const *alternative_names, const char *driver,
+                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) {
         Network *network;
@@ -791,7 +791,7 @@ int network_get(Manager *manager, unsigned short iftype, 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,
-                                     iftype, device, address, permanent_address,
+                                     device, mac, permanent_mac, driver, iftype,
                                      ifname, alternative_names, wlan_iftype, ssid, bssid)) {
                         if (network->match_name && device) {
                                 const char *attr;
index 95e4d58b974430fd1adf6c0d3314f36849a4b294..934a33ac94357ab840de3ad8cbae0e9473657e94 100644 (file)
@@ -346,10 +346,11 @@ 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, unsigned short iftype, 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 char *driver,
                 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);
+                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);
 
index 16009662838d07013256d7ae46603d1e5b5a952b..2ac47e72f523b4d4f1fb6fc4c06a6ee67c54d64a 100644 (file)
@@ -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, 0, loopback, "lo", NULL, &mac, &mac, 0, NULL, NULL, &network);
+        r = network_get(manager, 0, loopback, "lo", NULL, NULL, &mac, &mac, 0, NULL, NULL, &network);
         if (r == -ENOENT)
                 /* The expected case */
                 assert_se(!network);
index abe1276dfa17c1ccc3cc51b8fa5cfb0318017b75..39bdfb73dd7a7ddbe43ee29a08ca51fb14507bde 100644 (file)
@@ -270,7 +270,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,
-                                     iftype, device, NULL, &permanent_mac, NULL, NULL, 0, NULL, NULL)) {
+                                     device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL)) {
                         if (link->match_name && !strv_contains(link->match_name, "*")) {
                                 unsigned name_assign_type = NET_NAME_UNKNOWN;