]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make Type=ether match based on iftype
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 27 Feb 2020 12:56:36 +0000 (21:56 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 2 Mar 2020 07:52:18 +0000 (08:52 +0100)
This makes Type= can match the type shown in networkctl.

Closes #14952.

man/systemd.link.xml
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/network/networkctl.c
src/network/networkd-link.c
src/network/networkd-network.c
src/network/networkd-network.h
src/network/test-network.c
src/udev/net/link-config.c

index 3574dd41a129511aad1d13a994b21e7611fa5e1b..130cc786937a5e04dcffaa90d8e40425d7a66c0b 100644 (file)
       <varlistentry id='type'>
         <term><varname>Type=</varname></term>
         <listitem>
-            <para>A whitespace-separated list of shell-style globs matching the device type, as exposed by
-            the udev property <literal>DEVTYPE</literal>. If the list is prefixed with a "!", the test is
-            inverted.</para>
+          <para>A whitespace-separated list of shell-style globs matching the device type, as exposed by
+          <command>networkctl status</command>. If the list is prefixed with a "!", the test is inverted.
+          </para>
         </listitem>
       </varlistentry>
 
index 0bf0b0e5526073196eaff3145bc9d7a485a5d075..13a0a5d92957602f63b1260ed10509dbde473c63 100644 (file)
@@ -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 &&
index dff6c8831a03679458ff8c1ee8d7bd61ee977c9b..593bad223068647abd5320ffcff41475227b88bc 100644 (file)
@@ -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,
index 9c6a5d29f6e0f5f67d15e06c3d6901784ed87ae7..7387cffaa3a06adff5a2d866e8f4aee08194a983 100644 (file)
@@ -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;
index 55bc12712a0c47eaf5382b098a55bc46c8db70d4..d2d8334b2136bc509a0cb0d9d9559f8801dd6e1b 100644 (file)
@@ -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);
index 078cf1f0cf4477e9197560cb505260c329833c4f..a9390b8689a27bb78c49de6885adccbf28bb7c33 100644 (file)
@@ -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);
index 3dca043d99c1a7a145dbd81fe379ba0f4f970abc..99d4b29c31ec9cae85f196b9f5db91435f9eacfc 100644 (file)
@@ -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);
index b06ae75c058196d572689d69598fcd07aa0d2418..2e716b291e9779b761a5fa7b15e1e75a4c2670e3 100644 (file)
@@ -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;
index 66f010a7939fe4744d38673f38a34e412b7ad131..266e40cef518ab90566840212c33643533e5de6b 100644 (file)
@@ -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);
index b29523b3182fdd08b0a27ea7fc90084c8d50f6f6..e23bec76807a910bdf17f814d241ee13a7cb8529 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, 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);
index bcf9be1a0d918e33c19d65ea64f91f03cec2bb79..0332e99269c96ea0922f24874d7f456b1bb150c2 100644 (file)
@@ -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;