mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
network: support matching based on wifi interfece type
This commit is contained in:
parent
df7c4eb62a
commit
78404d22cc
@ -153,6 +153,18 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>WirelessType=</varname></term>
|
||||
<listitem>
|
||||
<para>A whitespace-separated list of wireless network type. Supported values are
|
||||
<literal>ad-hoc</literal>, <literal>station</literal>, <literal>ap</literal>,
|
||||
<literal>ap-vlan</literal>, <literal>wds</literal>, <literal>monitor</literal>,
|
||||
<literal>mesh-point</literal>, <literal>p2p-client</literal>, <literal>p2p-go</literal>,
|
||||
<literal>p2p-device</literal>, <literal>ocb</literal>, and <literal>nan</literal>. If the
|
||||
list is prefixed with a "!", the test is inverted.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>SSID=</varname></term>
|
||||
<listitem>
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "siphash24.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
@ -136,17 +137,36 @@ static int net_condition_test_property(char * const *match_property, sd_device *
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
|
||||
[NL80211_IFTYPE_ADHOC] = "ad-hoc",
|
||||
[NL80211_IFTYPE_STATION] = "station",
|
||||
[NL80211_IFTYPE_AP] = "ap",
|
||||
[NL80211_IFTYPE_AP_VLAN] = "ap-vlan",
|
||||
[NL80211_IFTYPE_WDS] = "wds",
|
||||
[NL80211_IFTYPE_MONITOR] = "monitor",
|
||||
[NL80211_IFTYPE_MESH_POINT] = "mesh-point",
|
||||
[NL80211_IFTYPE_P2P_CLIENT] = "p2p-client",
|
||||
[NL80211_IFTYPE_P2P_GO] = "p2p-go",
|
||||
[NL80211_IFTYPE_P2P_DEVICE] = "p2p-device",
|
||||
[NL80211_IFTYPE_OCB] = "ocb",
|
||||
[NL80211_IFTYPE_NAN] = "nan",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
|
||||
|
||||
bool net_match_config(Set *match_mac,
|
||||
char * const *match_paths,
|
||||
char * const *match_drivers,
|
||||
char * const *match_types,
|
||||
char * const *match_names,
|
||||
char * const *match_property,
|
||||
char * const *match_wifi_iftype,
|
||||
char * const *match_ssid,
|
||||
Set *match_bssid,
|
||||
sd_device *device,
|
||||
const struct ether_addr *dev_mac,
|
||||
const char *dev_name,
|
||||
enum nl80211_iftype wifi_iftype,
|
||||
const char *ssid,
|
||||
const struct ether_addr *bssid) {
|
||||
|
||||
@ -182,6 +202,9 @@ 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)))
|
||||
return false;
|
||||
|
||||
if (!net_condition_test_strv(match_ssid, ssid))
|
||||
return false;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
@ -20,11 +21,13 @@ bool net_match_config(Set *match_mac,
|
||||
char * const *match_type,
|
||||
char * const *match_name,
|
||||
char * const *match_property,
|
||||
char * const *match_wifi_iftype,
|
||||
char * const *match_ssid,
|
||||
Set *match_bssid,
|
||||
sd_device *device,
|
||||
const struct ether_addr *dev_mac,
|
||||
const char *dev_name,
|
||||
enum nl80211_iftype wifi_iftype,
|
||||
const char *ssid,
|
||||
const struct ether_addr *bssid);
|
||||
|
||||
|
@ -993,6 +993,7 @@ static const NLType genl_nl80211_types[] = {
|
||||
[NL80211_ATTR_IFINDEX] = { .type = NETLINK_TYPE_U32 },
|
||||
[NL80211_ATTR_MAC] = { .type = NETLINK_TYPE_ETHER_ADDR },
|
||||
[NL80211_ATTR_SSID] = { .type = NETLINK_TYPE_STRING },
|
||||
[NL80211_ATTR_IFTYPE] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
static const NLTypeSystem genl_nl80211_type_system = {
|
||||
|
@ -167,6 +167,7 @@ typedef struct LinkInfo {
|
||||
NetDevPort port;
|
||||
|
||||
/* wlan info */
|
||||
enum nl80211_iftype wlan_iftype;
|
||||
char *ssid;
|
||||
struct ether_addr bssid;
|
||||
|
||||
@ -384,7 +385,7 @@ static void acquire_ether_link_info(int *fd, LinkInfo *link) {
|
||||
static void acquire_wlan_link_info(LinkInfo *link) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL;
|
||||
const char *type = NULL;
|
||||
int r, k;
|
||||
int r, k = 0;
|
||||
|
||||
if (link->sd_device)
|
||||
(void) sd_device_get_devtype(link->sd_device, &type);
|
||||
@ -399,13 +400,15 @@ static void acquire_wlan_link_info(LinkInfo *link) {
|
||||
|
||||
(void) sd_netlink_inc_rcvbuf(genl, RCVBUF_SIZE);
|
||||
|
||||
r = wifi_get_ssid(genl, link->ifindex, &link->ssid);
|
||||
r = wifi_get_interface(genl, link->ifindex, &link->wlan_iftype, &link->ssid);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "%s: failed to query ssid: %m", link->name);
|
||||
|
||||
k = wifi_get_bssid(genl, link->ifindex, &link->bssid);
|
||||
if (k < 0)
|
||||
log_debug_errno(k, "%s: failed to query bssid: %m", link->name);
|
||||
if (link->iftype == NL80211_IFTYPE_STATION) {
|
||||
k = wifi_get_station(genl, link->ifindex, &link->bssid);
|
||||
if (k < 0)
|
||||
log_debug_errno(k, "%s: failed to query bssid: %m", link->name);
|
||||
}
|
||||
|
||||
link->has_wlan_link_info = r > 0 || k > 0;
|
||||
}
|
||||
|
@ -2865,7 +2865,7 @@ int link_reconfigure(Link *link, bool force) {
|
||||
return 0;
|
||||
|
||||
r = network_get(link->manager, link->sd_device, link->ifname,
|
||||
&link->mac, link->ssid, &link->bssid, &network);
|
||||
&link->mac, link->wlan_iftype, 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, &link->bssid, &network);
|
||||
&link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
|
||||
if (r == -ENOENT) {
|
||||
link_enter_unmanaged(link);
|
||||
return 0;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <endian.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-device.h"
|
||||
@ -56,6 +57,7 @@ typedef struct Link {
|
||||
sd_device *sd_device;
|
||||
|
||||
/* wlan */
|
||||
enum nl80211_iftype wlan_iftype;
|
||||
char *ssid;
|
||||
struct ether_addr bssid;
|
||||
|
||||
|
@ -29,6 +29,7 @@ Match.MACAddress, config_parse_hwaddrs,
|
||||
Match.Path, config_parse_match_strv, 0, offsetof(Network, match_path)
|
||||
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
|
||||
Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
|
||||
Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype)
|
||||
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)
|
||||
|
@ -595,6 +595,7 @@ static Network *network_free(Network *network) {
|
||||
strv_free(network->match_type);
|
||||
strv_free(network->match_name);
|
||||
strv_free(network->match_property);
|
||||
strv_free(network->match_wlan_iftype);
|
||||
strv_free(network->match_ssid);
|
||||
set_free_free(network->match_bssid);
|
||||
condition_free_list(network->conditions);
|
||||
@ -701,7 +702,8 @@ 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, const struct ether_addr *bssid, Network **ret) {
|
||||
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
|
||||
Network **ret) {
|
||||
Network *network;
|
||||
Iterator i;
|
||||
|
||||
@ -711,8 +713,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, network->match_bssid,
|
||||
device, address, ifname, ssid, bssid)) {
|
||||
network->match_wlan_iftype, network->match_ssid, network->match_bssid,
|
||||
device, address, ifname, wlan_iftype, ssid, bssid)) {
|
||||
if (network->match_name && device) {
|
||||
const char *attr;
|
||||
uint8_t name_assign_type = NET_NAME_UNKNOWN;
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-device.h"
|
||||
|
||||
@ -64,6 +66,7 @@ struct Network {
|
||||
char **match_type;
|
||||
char **match_name;
|
||||
char **match_property;
|
||||
char **match_wlan_iftype;
|
||||
char **match_ssid;
|
||||
Set *match_bssid;
|
||||
LIST_HEAD(Condition, conditions);
|
||||
@ -291,7 +294,7 @@ 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, 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);
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
int wifi_get_info(Link *link) {
|
||||
const char *type;
|
||||
int r, s;
|
||||
int r, s = 0;
|
||||
|
||||
assert(link);
|
||||
|
||||
@ -33,24 +33,26 @@ int wifi_get_info(Link *link) {
|
||||
return 0;
|
||||
|
||||
_cleanup_free_ char *ssid = NULL;
|
||||
r = wifi_get_ssid(link->manager->genl, link->ifindex, &ssid);
|
||||
r = wifi_get_interface(link->manager->genl, link->ifindex, &link->wlan_iftype, &ssid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0 && streq_ptr(link->ssid, ssid))
|
||||
r = 0;
|
||||
free_and_replace(link->ssid, ssid);
|
||||
|
||||
struct ether_addr old_bssid = link->bssid;
|
||||
s = wifi_get_bssid(link->manager->genl, link->ifindex, &link->bssid);
|
||||
if (s < 0)
|
||||
return s;
|
||||
if (s > 0 && memcmp(&old_bssid, &link->bssid, sizeof old_bssid) == 0)
|
||||
s = 0;
|
||||
if (link->wlan_iftype == NL80211_IFTYPE_STATION) {
|
||||
struct ether_addr old_bssid = link->bssid;
|
||||
s = wifi_get_station(link->manager->genl, link->ifindex, &link->bssid);
|
||||
if (s < 0)
|
||||
return s;
|
||||
if (s > 0 && memcmp(&old_bssid, &link->bssid, sizeof old_bssid) == 0)
|
||||
s = 0;
|
||||
}
|
||||
|
||||
if (r > 0 || s > 0) {
|
||||
char buf[ETHER_ADDR_TO_STRING_MAX];
|
||||
|
||||
if (link->ssid)
|
||||
if (link->wlan_iftype == NL80211_IFTYPE_STATION && link->ssid)
|
||||
log_link_info(link, "Connected WiFi access point: %s (%s)",
|
||||
link->ssid, ether_addr_to_string(&link->bssid, buf));
|
||||
return 1;
|
||||
|
@ -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, NULL, &network) == -ENOENT);
|
||||
assert_se(network_get(manager, loopback, "lo", &mac, 0, NULL, NULL, &network) == -ENOENT);
|
||||
assert_se(!network);
|
||||
}
|
||||
|
||||
|
6552
src/shared/linux/nl80211.h
Normal file
6552
src/shared/linux/nl80211.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
#include "netlink-util.h"
|
||||
#include "wifi-util.h"
|
||||
|
||||
int wifi_get_ssid(sd_netlink *genl, int ifindex, char **ssid) {
|
||||
int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
|
||||
sd_genl_family family;
|
||||
int r;
|
||||
@ -40,14 +40,25 @@ int wifi_get_ssid(sd_netlink *genl, int ifindex, char **ssid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m");
|
||||
if (iftype) {
|
||||
uint32_t t;
|
||||
|
||||
r = sd_netlink_message_read_u32(reply, NL80211_ATTR_IFTYPE, &t);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get NL80211_ATTR_IFTYPE attribute: %m");
|
||||
*iftype = t;
|
||||
}
|
||||
|
||||
if (ssid) {
|
||||
r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m");
|
||||
}
|
||||
|
||||
return r == -ENODATA ? 0 : 1;
|
||||
}
|
||||
|
||||
int wifi_get_bssid(sd_netlink *genl, int ifindex, struct ether_addr *bssid) {
|
||||
int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *reply = NULL;
|
||||
sd_genl_family family;
|
||||
int r;
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include "netlink-util.h"
|
||||
|
||||
int wifi_get_ssid(sd_netlink *genl, int ifindex, char **ssid);
|
||||
int wifi_get_bssid(sd_netlink *genl, int ifindex, struct ether_addr *bssid);
|
||||
int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid);
|
||||
int wifi_get_station(sd_netlink *genl, int ifindex, struct ether_addr *bssid);
|
||||
|
@ -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, NULL,
|
||||
device, NULL, NULL, NULL, NULL)) {
|
||||
link->match_type, link->match_name, link->match_property, NULL, NULL, NULL,
|
||||
device, NULL, NULL, 0, NULL, NULL)) {
|
||||
if (link->match_name && !strv_contains(link->match_name, "*")) {
|
||||
unsigned name_assign_type = NET_NAME_UNKNOWN;
|
||||
|
||||
|
@ -19,6 +19,7 @@ Type=
|
||||
Driver=
|
||||
Architecture=
|
||||
Path=
|
||||
WLANInterfaceType=
|
||||
SSID=
|
||||
BSSID=
|
||||
Name=
|
||||
|
Loading…
Reference in New Issue
Block a user