mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 14:40:08 +01:00
supplicant,device: support AP isolation
Support setting the ApIsolate property of the supplicant interface during association and resetting it to zero during disconnection.
This commit is contained in:
parent
dbfe219d5b
commit
4db4801038
4 changed files with 132 additions and 15 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue