summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-07-24 15:32:24 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-10-15 01:59:56 +0900
commit277ba8d1ab968f4c699c623a6bb17bd3b5fd17eb (patch)
tree1e2e6e50e94ef5b232d5bb62bc29e2cc7025190c
parent0894cfe41c9edacc560c109f1a115922d0a045f3 (diff)
downloadsystemd-277ba8d1ab968f4c699c623a6bb17bd3b5fd17eb.tar.gz
network: add support matching based on BSSID=
-rw-r--r--man/systemd.network.xml10
-rw-r--r--src/libsystemd-network/network-internal.c7
-rw-r--r--src/libsystemd-network/network-internal.h4
-rw-r--r--src/network/networkd-link.c4
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c7
-rw-r--r--src/network/networkd-network.h4
-rw-r--r--src/network/test-network.c2
-rw-r--r--src/udev/net/link-config.c4
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network1
10 files changed, 33 insertions, 11 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 03c488d7dc..3863f3d004 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -162,6 +162,16 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>BSSID=</varname></term>
+ <listitem>
+ <para>A whitespace-separated list of hardware address of the currently connected wireless
+ LAN. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example in
+ <varname>MACAddress=</varname>. This option may appear more than one, in which case the
+ lists are merged. If the empty string is assigned to this option, the list of BSSID defined
+ prior to this is reset.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Host=</varname></term>
<listitem>
<para>Matches against the hostname or machine ID of the host. See
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index 08c756788e..a8cb4ea286 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -143,10 +143,12 @@ bool net_match_config(Set *match_mac,
char * const *match_names,
char * const *match_property,
char * const *match_ssid,
+ Set *match_bssid,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
- const char *ssid) {
+ const char *ssid,
+ const struct ether_addr *bssid) {
const char *dev_path = NULL, *dev_driver = NULL, *dev_type = NULL, *mac_str;
@@ -183,6 +185,9 @@ bool net_match_config(Set *match_mac,
if (!net_condition_test_strv(match_ssid, ssid))
return false;
+ if (match_bssid && (!bssid || !set_contains(match_bssid, bssid)))
+ return false;
+
return true;
}
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 71aec1a99b..f40ad6b1dd 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -21,10 +21,12 @@ bool net_match_config(Set *match_mac,
char * const *match_name,
char * const *match_property,
char * const *match_ssid,
+ Set *match_bssid,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
- const char *ssid);
+ const char *ssid,
+ const struct ether_addr *bssid);
CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 1c0ae0184c..5fedd3765c 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2865,7 +2865,7 @@ int link_reconfigure(Link *link) {
return 0;
r = network_get(link->manager, link->sd_device, link->ifname,
- &link->mac, link->ssid, &network);
+ &link->mac, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
return 0;
@@ -2959,7 +2959,7 @@ static int link_initialized_and_synced(Link *link) {
return r;
r = network_get(link->manager, link->sd_device, link->ifname,
- &link->mac, link->ssid, &network);
+ &link->mac, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
return 0;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 95d3331222..832303aaa7 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -30,6 +30,7 @@ Match.Path, config_parse_match_strv,
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
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.Property, config_parse_match_property, 0, offsetof(Network, match_property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index b3bc598c44..7a2ee5ff85 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -548,6 +548,7 @@ static Network *network_free(Network *network) {
strv_free(network->match_name);
strv_free(network->match_property);
strv_free(network->match_ssid);
+ set_free_free(network->match_bssid);
condition_free_list(network->conditions);
free(network->description);
@@ -654,7 +655,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 *ssid, Network **ret) {
+ const char *ssid, const struct ether_addr *bssid, Network **ret) {
Network *network;
Iterator i;
@@ -664,8 +665,8 @@ int network_get(Manager *manager, sd_device *device,
ORDERED_HASHMAP_FOREACH(network, manager->networks, i)
if (net_match_config(network->match_mac, network->match_path, network->match_driver,
network->match_type, network->match_name, network->match_property,
- network->match_ssid,
- device, address, ifname, ssid)) {
+ network->match_ssid, network->match_bssid,
+ device, address, ifname, 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 883f0fab6e..fd98d88d6a 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -64,6 +64,7 @@ struct Network {
char **match_name;
char **match_property;
char **match_ssid;
+ Set *match_bssid;
LIST_HEAD(Condition, conditions);
char *description;
@@ -286,7 +287,8 @@ int network_load_one(Manager *manager, const char *filename);
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, const char *ssid, Network **ret);
+int network_get(Manager *manager, sd_device *device, const char *ifname, const struct ether_addr *mac,
+ 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 50b5cc047c..130adcbca8 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, NULL, &network) == -ENOENT);
+ assert_se(network_get(manager, loopback, "lo", &mac, NULL, NULL, &network) == -ENOENT);
assert_se(!network);
}
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 62974b7c95..b84caaf459 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -242,8 +242,8 @@ 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,
- device, NULL, NULL, NULL)) {
+ link->match_type, link->match_name, link->match_property, NULL, NULL,
+ device, NULL, NULL, NULL, NULL)) {
if (link->match_name && !strv_contains(link->match_name, "*")) {
unsigned name_assign_type = NET_NAME_UNKNOWN;
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 8f3153079b..22fe2b4e33 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -20,6 +20,7 @@ Driver=
Architecture=
Path=
SSID=
+BSSID=
Name=
Property=
Virtualization=