network: add support matching based on BSSID=

This commit is contained in:
Yu Watanabe 2019-07-24 15:32:24 +09:00
parent 0894cfe41c
commit 277ba8d1ab
10 changed files with 33 additions and 11 deletions

View File

@ -161,6 +161,16 @@
</para>
</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>

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -20,6 +20,7 @@ Driver=
Architecture=
Path=
SSID=
BSSID=
Name=
Property=
Virtualization=