wifi: merge branch 'bg/ap-isolation'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/469
This commit is contained in:
Beniamino Galvani 2020-07-01 17:47:53 +02:00
commit 76baf6e0ba
21 changed files with 339 additions and 21 deletions

View file

@ -3075,6 +3075,7 @@ EXTRA_DIST += \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Team_Infiniband_Port.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Team_Port.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_VLAN_reorder_hdr.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_AP_Mode.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Band_A.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_Hidden.cexpected \
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_WiFi_MAC_always.cexpected \

View file

@ -7492,6 +7492,9 @@ static const NMMetaPropertyInfo *const property_infos_WIRELESS[] = {
),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIRELESS_AP_ISOLATION,
.property_type = &_pt_gobject_enum,
),
NULL
};

View file

@ -4,6 +4,7 @@
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_CHANNEL N_("Channel on which the mesh network to join is located.")
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS N_("Anycast DHCP MAC address used when requesting an IP address via DHCP. The specific anycast address used determines which DHCP server class answers the request.")
#define DESCRIBE_DOC_NM_SETTING_OLPC_MESH_SSID N_("SSID of the mesh network to join.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_AP_ISOLATION N_("Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from NM_TERNARY_DEFAULT (-1) only when the interface is configured in AP mode. If set to NM_TERNARY_TRUE (1), devices are not able to communicate with each other. The increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to NM_TERNARY_FALSE (0), devices can talk to each other. When set to NM_TERNARY_DEFAULT (-1), the global default is used; in case the global default is unspecified it is assumed to be NM_TERNARY_FALSE (0).")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BAND N_("802.11 frequency band of the network. One of \"a\" for 5GHz 802.11a or \"bg\" for 2.4GHz 802.11. This will lock associations to the Wi-Fi network to the specific band, i.e. if \"a\" is specified, the device will not associate with the same network in the 2.4GHz band even if the network's settings are compatible. This setting depends on specific driver capability and may not work with all drivers.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_BSSID N_("If specified, directs the device to only associate with the given access point. This capability is highly driver dependent and not supported by all devices. Note: this property does not control the BSSID used when creating an Ad-Hoc network and is unlikely to in the future.")
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_CHANNEL N_("Wireless channel to use for the Wi-Fi connection. The device will only join (or create for Ad-Hoc networks) a Wi-Fi network on the specified channel. Because channel numbers overlap between bands, this property also requires the \"band\" property to be set.")

View file

@ -58,12 +58,12 @@ location: clients/tests/test-client.py:test_004()/7
cmd: $NMCLI connection mod con-xx1 ipv4.addresses 192.168.77.5/24 ipv4.routes '2.3.4.5/32 192.168.77.1' ipv6.addresses 1:2:3:4::6/64 ipv6.routes 1:2:3:4:5:6::5/128
lang: C
returncode: 0
size: 4464
size: 4517
location: clients/tests/test-client.py:test_004()/8
cmd: $NMCLI con s con-xx1
lang: C
returncode: 0
stdout: 4336 bytes
stdout: 4389 bytes
>>>
connection.id: con-xx1
connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA
@ -106,6 +106,7 @@ connection.wait-device-timeout: -1
802-11-wireless.hidden: no
802-11-wireless.powersave: 0 (default)
802-11-wireless.wake-on-wlan: 0x1 (default)
802-11-wireless.ap-isolation: -1 (default)
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --
@ -160,12 +161,12 @@ proxy.pac-url: --
proxy.pac-script: --
<<<
size: 4492
size: 4545
location: clients/tests/test-client.py:test_004()/9
cmd: $NMCLI con s con-xx1
lang: pl_PL.UTF-8
returncode: 0
stdout: 4354 bytes
stdout: 4407 bytes
>>>
connection.id: con-xx1
connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA
@ -208,6 +209,7 @@ connection.wait-device-timeout: -1
802-11-wireless.hidden: nie
802-11-wireless.powersave: 0 (default)
802-11-wireless.wake-on-wlan: 0x1 (default)
802-11-wireless.ap-isolation: -1 (default)
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --

View file

@ -43,6 +43,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingWireless,
PROP_POWERSAVE,
PROP_MAC_ADDRESS_RANDOMIZATION,
PROP_WAKE_ON_WLAN,
PROP_AP_ISOLATION,
);
typedef struct {
@ -55,13 +56,14 @@ typedef struct {
char *device_mac_address;
char *cloned_mac_address;
char *generate_mac_address_mask;
NMSettingMacRandomization mac_address_randomization;
NMTernary ap_isolation;
guint32 channel;
guint32 rate;
guint32 tx_power;
guint32 mtu;
guint32 powersave;
guint32 wowl;
NMSettingMacRandomization mac_address_randomization;
bool hidden:1;
} NMSettingWirelessPrivate;
@ -739,6 +741,22 @@ _to_dbus_fcn_seen_bssids (const NMSettInfoSetting *sett_info,
return g_variant_new_strv ((const char *const*) priv->seen_bssids->pdata, priv->seen_bssids->len);
}
/**
* nm_setting_wireless_get_ap_isolation:
* @setting: the #NMSettingWireless
*
* Returns: the #NMSettingWireless:ap-isolation property of the setting
*
* Since: 1.28
*/
NMTernary
nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NM_TERNARY_DEFAULT);
return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ap_isolation;
}
/*****************************************************************************/
static gboolean
@ -934,6 +952,17 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if ( priv->ap_isolation != NM_TERNARY_DEFAULT
&& !nm_streq0 (priv->mode, NM_SETTING_WIRELESS_MODE_AP)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("AP isolation can be set only in AP mode"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_AP_ISOLATION);
return FALSE;
}
/* from here on, check for NM_SETTING_VERIFY_NORMALIZABLE conditions. */
if (priv->cloned_mac_address) {
@ -1094,6 +1123,9 @@ get_property (GObject *object, guint prop_id,
case PROP_WAKE_ON_WLAN:
g_value_set_uint (value, nm_setting_wireless_get_wake_on_wlan (setting));
break;
case PROP_AP_ISOLATION:
g_value_set_enum (value, priv->ap_isolation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1203,6 +1235,9 @@ set_property (GObject *object, guint prop_id,
case PROP_WAKE_ON_WLAN:
priv->wowl = g_value_get_uint (value);
break;
case PROP_AP_ISOLATION:
priv->ap_isolation = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1221,6 +1256,7 @@ nm_setting_wireless_init (NMSettingWireless *setting)
g_array_set_clear_func (priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item);
priv->wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT;
priv->ap_isolation = NM_TERNARY_DEFAULT;
}
/**
@ -1769,6 +1805,44 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingWireless:ap-isolation
*
* Configures AP isolation, which prevents communication between
* wireless devices connected to this AP. This property can be set
* to a value different from %NM_TERNARY_DEFAULT only when the
* interface is configured in AP mode.
*
* If set to %NM_TERNARY_TRUE, devices are not able to communicate
* with each other. The increases security because it protects
* devices against attacks from other clients in the network. At
* the same time, it prevents devices to access resources on the
* same wireless networks as file shares, printers, etc.
*
* If set to %NM_TERNARY_FALSE, devices can talk to each other.
*
* When set to %NM_TERNARY_DEFAULT, the global default is used; in
* case the global default is unspecified it is assumed to be
* %NM_TERNARY_FALSE.
*
* Since: 1.28
**/
/* ---ifcfg-rh---
* property: ap-isolation
* variable: AP_ISOLATION(+)
* values: "yes", "no"
* default: missing variable means global default
* description: Whether AP isolation is enabled
* ---end---
*/
obj_properties[PROP_AP_ISOLATION] =
g_param_spec_enum (NM_SETTING_WIRELESS_AP_ISOLATION, "", "",
NM_TYPE_TERNARY,
NM_TERNARY_DEFAULT,
NM_SETTING_PARAM_FUZZY_IGNORE |
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_WIRELESS,

View file

@ -84,6 +84,7 @@ typedef enum { /*< flags >*/
#define NM_SETTING_WIRELESS_POWERSAVE "powersave"
#define NM_SETTING_WIRELESS_MAC_ADDRESS_RANDOMIZATION "mac-address-randomization"
#define NM_SETTING_WIRELESS_WAKE_ON_WLAN "wake-on-wlan"
#define NM_SETTING_WIRELESS_AP_ISOLATION "ap-isolation"
/**
* NM_SETTING_WIRELESS_MODE_ADHOC:
@ -205,6 +206,9 @@ gboolean nm_setting_wireless_ap_security_compatible (NMSettingWireless
NM_AVAILABLE_IN_1_12
NMSettingWirelessWakeOnWLan nm_setting_wireless_get_wake_on_wlan (NMSettingWireless *setting);
NM_AVAILABLE_IN_1_28
NMTernary nm_setting_wireless_get_ap_isolation (NMSettingWireless *setting);
G_END_DECLS
#endif /* __NM_SETTING_WIRELESS_H__ */

View file

@ -1741,3 +1741,8 @@ global:
nm_setting_option_set_boolean;
nm_setting_option_set_uint32;
} libnm_1_24_0;
libnm_1_28_0 {
global:
nm_setting_wireless_get_ap_isolation;
} libnm_1_26_0;

View file

@ -805,6 +805,10 @@ ipv6.ip6-privacy=0
<term><varname>vpn.timeout</varname></term>
<listitem><para>If left unspecified, default value of 60 seconds is used.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi.ap-isolation</varname></term>
<listitem><para>If left unspecified, AP isolation is disabled.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi.cloned-mac-address</varname></term>
<listitem><para>If left unspecified, it defaults to "preserve".</para></listitem>

View file

@ -18330,6 +18330,7 @@ nm_device_class_init (NMDeviceClass *klass)
/* Connection defaults from plugins */
NM_CON_DEFAULT_NOP ("cdma.mtu");
NM_CON_DEFAULT_NOP ("gsm.mtu");
NM_CON_DEFAULT_NOP ("wifi.ap-isolation");
NM_CON_DEFAULT_NOP ("wifi.powersave");
NM_CON_DEFAULT_NOP ("wifi.wake-on-wlan");
NM_CON_DEFAULT_NOP ("wifi-sec.pmf");

View file

@ -2810,6 +2810,7 @@ build_supplicant_config (NMDeviceWifi *self,
NMSettingWirelessSecurity *s_wireless_sec;
NMSettingWirelessSecurityPmf pmf;
NMSettingWirelessSecurityFils fils;
NMTernary ap_isolation;
g_return_val_if_fail (priv->sup_iface, NULL);
@ -2837,6 +2838,17 @@ build_supplicant_config (NMDeviceWifi *self,
goto error;
}
ap_isolation = nm_setting_wireless_get_ap_isolation (s_wireless);
if (ap_isolation == NM_TERNARY_DEFAULT) {
ap_isolation = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA,
"wifi.ap-isolation",
NM_DEVICE (self),
NM_TERNARY_FALSE,
NM_TERNARY_TRUE,
NM_TERNARY_FALSE);
}
nm_supplicant_config_set_ap_isolation (config, ap_isolation == NM_TERNARY_TRUE);
s_wireless_sec = nm_connection_get_setting_wireless_security (connection);
if (s_wireless_sec) {
NMSetting8021x *s_8021x;

View file

@ -4021,6 +4021,7 @@ make_wireless_setting (shvarFile *ifcfg,
gint64 chan = 0;
NMSettingMacRandomization mac_randomization;
NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
NMTernary ternary;
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
@ -4224,6 +4225,14 @@ make_wireless_setting (shvarFile *ifcfg,
mac_randomization,
NULL);
ternary = svGetValueTernary (ifcfg, "AP_ISOLATION");
if (ternary != NM_TERNARY_DEFAULT) {
g_object_set (s_wireless,
NM_SETTING_WIRELESS_AP_ISOLATION,
ternary,
NULL);
}
return NM_SETTING (s_wireless);
error:

View file

@ -805,6 +805,7 @@ nms_ifcfg_rh_utils_is_numbered_tag_impl (const char *key,
const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = {
_KEY_TYPE ("ACD_TIMEOUT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ADDRESS", NMS_IFCFG_KEY_TYPE_IS_NUMBERED ),
_KEY_TYPE ("AP_ISOLATION", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("ARPING_WAIT", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTH_RETRIES", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),
_KEY_TYPE ("AUTOCONNECT_PRIORITY", NMS_IFCFG_KEY_TYPE_IS_PLAIN ),

View file

@ -33,7 +33,7 @@ typedef struct {
NMSIfcfgKeyTypeFlags key_flags;
} NMSIfcfgKeyTypeInfo;
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[240];
extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[241];
const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info (const char *key, gssize *out_idx);

View file

@ -953,6 +953,8 @@ write_wireless_setting (NMConnection *connection,
break;
}
svSetValueTernary (ifcfg, "AP_ISOLATION", nm_setting_wireless_get_ap_isolation (s_wireless));
svSetValueStr (ifcfg, "TYPE", TYPE_WIRELESS);
return TRUE;

View file

@ -1214,6 +1214,20 @@ svGetValueBoolean (shvarFile *s, const char *key, int fallback)
return svParseBoolean (value, fallback);
}
/* svGetValueTernary:
* @s: fhe file
* @key: the name of the key to read
*
* Reads a value @key and converts it to a NMTernary value.
*
* Returns: the parsed NMTernary
*/
NMTernary
svGetValueTernary (shvarFile *s, const char *key)
{
return svGetValueBoolean (s, key, NM_TERNARY_DEFAULT);
}
/* svGetValueInt64:
* @s: fhe file
* @key: the name of the key to read
@ -1428,6 +1442,15 @@ svSetValueBoolean (shvarFile *s, const char *key, gboolean value)
return svSetValue (s, key, value ? "yes" : "no");
}
gboolean
svSetValueTernary (shvarFile *s, const char *key, NMTernary value)
{
if (NM_IN_SET (value, NM_TERNARY_TRUE, NM_TERNARY_FALSE))
return svSetValueBoolean (s, key, (gboolean) value);
else
return svUnsetValue (s, key);
}
gboolean
svSetValueBoolean_cond_true (shvarFile *s, const char *key, gboolean value)
{

View file

@ -66,6 +66,8 @@ const char **svGetKeysSorted (shvarFile *s,
*/
int svGetValueBoolean (shvarFile *s, const char *key, int def);
NMTernary svGetValueTernary (shvarFile *s, const char *key);
gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback);
gboolean svGetValueEnum (shvarFile *s, const char *key,
@ -84,6 +86,7 @@ gboolean svSetValueBoolean_cond_true (shvarFile *s, const char *key, gboolean va
gboolean svSetValueInt64 (shvarFile *s, const char *key, gint64 value);
gboolean svSetValueInt64_cond (shvarFile *s, const char *key, gboolean do_set, gint64 value);
gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value);
gboolean svSetValueTernary (shvarFile *s, const char *key, NMTernary value);
gboolean svUnsetValue (shvarFile *s, const char *key);
gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type);

View file

@ -0,0 +1,19 @@
ESSID=MySSID
MODE=Ap
CHANNEL=196
MAC_ADDRESS_RANDOMIZATION=default
AP_ISOLATION=yes
TYPE=Wireless
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME="Test Write Wi-Fi AP Mode"
UUID=${UUID}
ONBOOT=yes

View file

@ -3966,6 +3966,54 @@ test_write_wifi_band_a (void)
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
}
static void
test_write_wifi_ap_mode (void)
{
nmtst_auto_unlinkfile char *testfile = NULL;
gs_unref_object NMConnection *connection = NULL;
gs_unref_object NMConnection *reread = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
gs_unref_bytes GBytes *ssid = NULL;
connection = nm_simple_connection_new ();
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
nm_connection_add_setting (connection, NM_SETTING (s_con));
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Write Wi-Fi AP Mode",
NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
/* Wifi setting */
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
ssid = g_bytes_new ("MySSID", NM_STRLEN ("MySSID"));
g_object_set (s_wifi,
NM_SETTING_WIRELESS_SSID, ssid,
NM_SETTING_WIRELESS_MODE, "ap",
NM_SETTING_WIRELESS_BAND, "a",
NM_SETTING_WIRELESS_CHANNEL, (guint) 196,
NM_SETTING_WIRELESS_AP_ISOLATION, NM_TERNARY_TRUE,
NULL);
nmtst_assert_connection_verifies (connection);
_writer_new_connec_exp (connection,
TEST_SCRATCH_DIR,
TEST_IFCFG_DIR"/ifcfg-Test_Write_WiFi_AP_Mode.cexpected",
&testfile);
reread = _connection_from_file (testfile, NULL, TYPE_WIRELESS, NULL);
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
}
static void
test_read_wifi_band_a_channel_mismatch (void)
{
@ -10645,6 +10693,7 @@ int main (int argc, char **argv)
g_test_add_func (TPATH "wifi/write-wpa-then-wep-with-perms", test_write_wifi_wpa_then_wep_with_perms);
g_test_add_func (TPATH "wifi/write-hidden", test_write_wifi_hidden);
g_test_add_func (TPATH "wifi/write-band-a", test_write_wifi_band_a);
g_test_add_func (TPATH "wifi/write-ap-mode", test_write_wifi_ap_mode);
g_test_add_func (TPATH "s390/read-qeth-static", test_read_wired_qeth_static);
g_test_add_func (TPATH "s390/write-qeth-dhcp", test_write_wired_qeth_dhcp);

View file

@ -34,6 +34,7 @@ typedef struct {
guint32 ap_scan;
bool fast_required:1;
bool dispose_has_run:1;
bool ap_isolation:1;
} NMSupplicantConfigPrivate;
struct _NMSupplicantConfig {
@ -1521,3 +1522,14 @@ nm_supplicant_config_add_no_security (NMSupplicantConfig *self, GError **error)
return nm_supplicant_config_add_option (self, "key_mgmt", "NONE", -1, NULL, error);
}
gboolean
nm_supplicant_config_get_ap_isolation (NMSupplicantConfig *self)
{
return self->_priv.ap_isolation;
}
void
nm_supplicant_config_set_ap_isolation (NMSupplicantConfig *self, gboolean ap_isolation)
{
self->_priv.ap_isolation = ap_isolation;
}

View file

@ -69,4 +69,8 @@ gboolean nm_supplicant_config_add_setting_macsec (NMSupplicantConfig *self,
gboolean nm_supplicant_config_enable_pmf_akm (NMSupplicantConfig *self,
GError **error);
void nm_supplicant_config_set_ap_isolation (NMSupplicantConfig *self, gboolean ap_isolation);
gboolean nm_supplicant_config_get_ap_isolation (NMSupplicantConfig *self);
#endif /* __NETWORKMANAGER_SUPPLICANT_CONFIG_H__ */

View file

@ -44,6 +44,7 @@ typedef struct {
gpointer user_data;
guint fail_on_idle_id;
guint blobs_left;
guint calls_left;
struct _AddNetworkData *add_network_data;
} AssocData;
@ -157,6 +158,8 @@ typedef struct _NMSupplicantInterfacePrivate {
bool prop_scan_active:1;
bool prop_scan_ssid:1;
bool ap_isolate_supported:1;
bool ap_isolate_needs_reset:1;
} NMSupplicantInterfacePrivate;
struct _NMSupplicantInterfaceClass {
@ -436,6 +439,20 @@ _remove_network (NMSupplicantInterface *self)
g_variant_new ("(o)", net_path),
G_VARIANT_TYPE ("()"),
"remove-network");
if ( priv->ap_isolate_supported
&& priv->ap_isolate_needs_reset) {
_dbus_connection_call_simple (self,
DBUS_INTERFACE_PROPERTIES,
"Set",
g_variant_new ("(ssv)",
NM_WPAS_DBUS_IFACE_INTERFACE,
"ApIsolate",
g_variant_new_string ("0")),
G_VARIANT_TYPE ("()"),
"reset-ap-isolation");
}
priv->ap_isolate_needs_reset = FALSE;
}
/*****************************************************************************/
@ -1868,6 +1885,9 @@ _properties_changed_main (NMSupplicantInterface *self,
}
}
if (nm_g_variant_lookup (properties, "ApIsolate", "&s", &v_s))
priv->ap_isolate_supported = TRUE;
if (do_log_driver_info) {
_LOGD ("supplicant interface for ifindex=%d, ifname=%s%s%s, driver=%s%s%s (requested %s)",
priv->ifindex,
@ -2227,27 +2247,13 @@ assoc_add_network_cb (GObject *source, GAsyncResult *result, gpointer user_data)
}
static void
assoc_set_ap_scan_cb (GVariant *ret, GError *error, gpointer user_data)
add_network (NMSupplicantInterface *self)
{
NMSupplicantInterface *self;
NMSupplicantInterfacePrivate *priv;
AddNetworkData *add_network_data;
if (nm_utils_error_is_cancelled (error))
return;
self = NM_SUPPLICANT_INTERFACE (user_data);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (error) {
assoc_return (self, error, "failure to set AP scan mode");
return;
}
_LOGT ("assoc["NM_HASH_OBFUSCATE_PTR_FMT"]: interface ap_scan set to %d",
NM_HASH_OBFUSCATE_PTR (priv->assoc_data),
nm_supplicant_config_get_ap_scan (priv->assoc_data->cfg));
/* the association does not keep @self alive. We want to be able to remove
* the network again, even if @self is already gone. Hence, track the data
* separately.
@ -2276,6 +2282,62 @@ assoc_set_ap_scan_cb (GVariant *ret, GError *error, gpointer user_data)
add_network_data);
}
static void
assoc_set_ap_isolation (GVariant *ret, GError *error, gpointer user_data)
{
NMSupplicantInterface *self;
NMSupplicantInterfacePrivate *priv;
gboolean value;
if (nm_utils_error_is_cancelled (error))
return;
self = NM_SUPPLICANT_INTERFACE (user_data);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (error) {
assoc_return (self, error, "failure to set AP isolation");
return;
}
value = nm_supplicant_config_get_ap_isolation (priv->assoc_data->cfg);
_LOGT ("assoc["NM_HASH_OBFUSCATE_PTR_FMT"]: interface AP isolation set to %d",
NM_HASH_OBFUSCATE_PTR (priv->assoc_data),
value);
priv->ap_isolate_needs_reset = value;
nm_assert (priv->assoc_data->calls_left > 0);
if (--priv->assoc_data->calls_left == 0)
add_network (self);
}
static void
assoc_set_ap_scan_cb (GVariant *ret, GError *error, gpointer user_data)
{
NMSupplicantInterface *self;
NMSupplicantInterfacePrivate *priv;
if (nm_utils_error_is_cancelled (error))
return;
self = NM_SUPPLICANT_INTERFACE (user_data);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
if (error) {
assoc_return (self, error, "failure to set AP scan mode");
return;
}
_LOGT ("assoc["NM_HASH_OBFUSCATE_PTR_FMT"]: interface ap_scan set to %d",
NM_HASH_OBFUSCATE_PTR (priv->assoc_data),
nm_supplicant_config_get_ap_scan (priv->assoc_data->cfg));
nm_assert (priv->assoc_data->calls_left > 0);
if (--priv->assoc_data->calls_left == 0)
add_network (self);
}
static gboolean
assoc_fail_on_idle_cb (gpointer user_data)
{
@ -2312,6 +2374,7 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self,
{
NMSupplicantInterfacePrivate *priv;
AssocData *assoc_data;
gboolean ap_isolation;
g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self));
g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (cfg));
@ -2343,6 +2406,7 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self,
}
assoc_data->cancellable = g_cancellable_new();
assoc_data->calls_left++;
nm_dbus_connection_call_set (priv->dbus_connection,
priv->name_owner->str,
priv->object_path->str,
@ -2353,6 +2417,31 @@ nm_supplicant_interface_assoc (NMSupplicantInterface *self,
assoc_data->cancellable,
assoc_set_ap_scan_cb,
self);
ap_isolation = nm_supplicant_config_get_ap_isolation (priv->assoc_data->cfg);
if (!priv->ap_isolate_supported) {
if (ap_isolation) {
_LOGW ("assoc["NM_HASH_OBFUSCATE_PTR_FMT"]: requested AP isolation but the supplicant doesn't support it",
NM_HASH_OBFUSCATE_PTR (assoc_data));
}
} else {
assoc_data->calls_left++;
/* It would be smarter to change the property only when necessary.
* However, wpa_supplicant doesn't send the PropertiesChanged
* signal for ApIsolate, and so to know the current value we would
* need first a Get call. It seems simpler to just set the value
* we want. */
nm_dbus_connection_call_set (priv->dbus_connection,
priv->name_owner->str,
priv->object_path->str,
NM_WPAS_DBUS_IFACE_INTERFACE,
"ApIsolate",
g_variant_new_string (ap_isolation ? "1" : "0"),
DBUS_TIMEOUT_MSEC,
assoc_data->cancellable,
assoc_set_ap_isolation,
self);
}
}
/*****************************************************************************/