summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-02-27 21:56:36 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-03-02 08:52:18 +0100
commitef62949a23a2d6dc722659cc527f6e0006135dc9 (patch)
tree1419f37b0e27d5e52ca29882135f46522f7eeb41
parented87ce1d5d93e10fb712e3839606248a7d20a1ce (diff)
downloadsystemd-ef62949a23a2d6dc722659cc527f6e0006135dc9.tar.gz
network: make Type=ether match based on iftype
This makes Type= can match the type shown in networkctl. Closes #14952.
-rw-r--r--man/systemd.link.xml6
-rw-r--r--src/libsystemd-network/network-internal.c30
-rw-r--r--src/libsystemd-network/network-internal.h2
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.c23
-rw-r--r--src/libsystemd/sd-netlink/netlink-util.h1
-rw-r--r--src/network/networkctl.c23
-rw-r--r--src/network/networkd-link.c4
-rw-r--r--src/network/networkd-network.c4
-rw-r--r--src/network/networkd-network.h2
-rw-r--r--src/network/test-network.c2
-rw-r--r--src/udev/net/link-config.c13
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 @@
<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>
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;