merge: branch 'bg/reapply-more-bgo779794'

https://bugzilla.gnome.org/show_bug.cgi?id=779794
This commit is contained in:
Beniamino Galvani 2017-03-09 22:00:41 +01:00
commit 7ef2651d71
4 changed files with 200 additions and 63 deletions

View file

@ -1622,6 +1622,53 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags)
return !!nm_device_get_initial_hw_address (device);
}
static gboolean
can_reapply_change (NMDevice *device,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error)
{
NMDeviceClass *device_class;
/* Only handle wired setting here, delegate other settings to parent class */
if (nm_streq (setting_name, NM_SETTING_WIRED_SETTING_NAME)) {
return nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_WIRED_SETTING_NAME,
error,
NM_SETTING_WIRED_MTU, /* reapplied with IP config */
NM_SETTING_WIRED_SPEED,
NM_SETTING_WIRED_DUPLEX,
NM_SETTING_WIRED_AUTO_NEGOTIATE,
NM_SETTING_WIRED_WAKE_ON_LAN,
NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD);
}
device_class = NM_DEVICE_CLASS (nm_device_ethernet_parent_class);
return device_class->can_reapply_change (device,
setting_name,
s_old,
s_new,
diffs,
error);
}
static void
reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_new)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->reapply_connection (device,
con_old,
con_new);
_LOGD (LOGD_DEVICE, "reapplying wired settings");
link_negotiation_set (device);
wake_on_lan_enable (device);
}
static void
dispose (GObject *object)
{
@ -1719,6 +1766,8 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->carrier_changed = carrier_changed;
parent_class->link_changed = link_changed;
parent_class->is_available = is_available;
parent_class->can_reapply_change = can_reapply_change;
parent_class->reapply_connection = reapply_connection;
parent_class->state_changed = device_state_changed;

View file

@ -784,6 +784,33 @@ unrealize_notify (NMDevice *device)
update_properties_from_ifindex (device, 0);
}
static gboolean
can_reapply_change (NMDevice *device,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error)
{
NMDeviceClass *device_class;
/* Only handle ip-tunnel setting here, delegate other settings to parent class */
if (nm_streq (setting_name, NM_SETTING_IP_TUNNEL_SETTING_NAME)) {
return nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_IP_TUNNEL_SETTING_NAME,
error,
NM_SETTING_IP_TUNNEL_MTU); /* reapplied with IP config */
}
device_class = NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class);
return device_class->can_reapply_change (device,
setting_name,
s_old,
s_new,
diffs,
error);
}
/*****************************************************************************/
static void
@ -891,6 +918,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
object_class->set_property = set_property;
device_class->link_changed = link_changed;
device_class->can_reapply_change = can_reapply_change;
device_class->complete_connection = complete_connection;
device_class->update_connection = update_connection;
device_class->check_connection_compatible = check_connection_compatible;

View file

@ -342,6 +342,7 @@ typedef struct _NMDevicePrivate {
NMDhcp4Config * config;
guint restart_id;
guint num_tries_left;
char * pac_url;
} dhcp4;
struct {
@ -452,7 +453,7 @@ G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT)
/*****************************************************************************/
static void nm_device_set_proxy_config (NMDevice *self, GHashTable *options);
static void nm_device_set_proxy_config (NMDevice *self, const char *pac_url);
static gboolean nm_device_set_ip4_config (NMDevice *self,
NMIP4Config *config,
@ -4285,6 +4286,43 @@ act_stage2_config (NMDevice *self, NMDeviceStateReason *out_failure_reason)
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static void
lldp_init (NMDevice *self, gboolean restart)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->ifindex > 0 && lldp_rx_enabled (self)) {
gs_free_error GError *error = NULL;
gconstpointer addr;
size_t addr_length;
if (priv->lldp_listener) {
if (restart && nm_lldp_listener_is_running (priv->lldp_listener))
nm_lldp_listener_stop (priv->lldp_listener);
} else {
priv->lldp_listener = nm_lldp_listener_new ();
g_signal_connect (priv->lldp_listener,
"notify::" NM_LLDP_LISTENER_NEIGHBORS,
G_CALLBACK (lldp_neighbors_changed),
self);
}
if (!nm_lldp_listener_is_running (priv->lldp_listener)) {
addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error))
_LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener);
else {
_LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s",
priv->lldp_listener, error->message);
}
}
} else {
if (priv->lldp_listener)
nm_lldp_listener_stop (priv->lldp_listener);
}
}
/*
* activate_stage2_device_config
*
@ -4337,31 +4375,7 @@ activate_stage2_device_config (NMDevice *self)
nm_device_queue_recheck_assume (info->slave);
}
if (lldp_rx_enabled (self) && priv->ifindex > 0) {
gs_free_error GError *error = NULL;
gconstpointer addr;
size_t addr_length;
if (priv->lldp_listener)
nm_lldp_listener_stop (priv->lldp_listener);
else {
priv->lldp_listener = nm_lldp_listener_new ();
g_signal_connect (priv->lldp_listener,
"notify::" NM_LLDP_LISTENER_NEIGHBORS,
G_CALLBACK (lldp_neighbors_changed),
self);
}
addr = nm_platform_link_get_address (NM_PLATFORM_GET, priv->ifindex, &addr_length);
if (nm_lldp_listener_start (priv->lldp_listener, nm_device_get_ifindex (self), &error))
_LOGD (LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener);
else {
_LOGD (LOGD_DEVICE, "LLDP listener %p could not be started: %s",
priv->lldp_listener, error->message);
}
}
lldp_init (self, TRUE);
nm_device_activate_schedule_stage3_ip_config_start (self);
}
@ -4992,6 +5006,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release)
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
nm_clear_g_source (&priv->dhcp4.restart_id);
g_clear_pointer (&priv->dhcp4.pac_url, g_free);
if (priv->dhcp4.client) {
/* Stop any ongoing DHCP transaction on this device */
@ -5328,7 +5343,9 @@ dhcp4_state_changed (NMDhcpClient *client,
break;
}
nm_device_set_proxy_config (self, options);
g_free (priv->dhcp4.pac_url);
priv->dhcp4.pac_url = g_strdup (g_hash_table_lookup (options, "wpad"));
nm_device_set_proxy_config (self, priv->dhcp4.pac_url);
nm_dhcp4_config_set_options (priv->dhcp4.config, options);
_notify (self, PROP_DHCP4_CONFIG);
@ -8471,15 +8488,52 @@ nm_device_reactivate_ip6_config (NMDevice *self,
}
}
static void
reactivate_proxy_config (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
nm_pacrunner_manager_remove (priv->pacrunner_manager,
nm_device_get_ip_iface (self));
nm_device_set_proxy_config (self, priv->dhcp4.pac_url);
nm_pacrunner_manager_send (priv->pacrunner_manager,
nm_device_get_ip_iface (self),
priv->proxy_config,
priv->ip4_config,
priv->ip6_config);
}
static gboolean
can_reapply_change (NMDevice *self, const char *setting_name,
NMSetting *s_old, NMSetting *s_new,
GHashTable *diffs, GError **error)
{
if (!NM_IN_STRSET (setting_name,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_CONNECTION_SETTING_NAME)) {
if (nm_streq (setting_name, NM_SETTING_CONNECTION_SETTING_NAME)) {
/* Whitelist allowed properties from "connection" setting which are
* allowed to differ.
*
* This includes UUID, there is no principal problem with reapplying a
* connection and changing it's UUID. In fact, disallowing it makes it
* cumbersome for the user to reapply any connection but the original
* settings-connection. */
return nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_CONNECTION_SETTING_NAME,
error,
NM_SETTING_CONNECTION_ID,
NM_SETTING_CONNECTION_UUID,
NM_SETTING_CONNECTION_STABLE_ID,
NM_SETTING_CONNECTION_AUTOCONNECT,
NM_SETTING_CONNECTION_ZONE,
NM_SETTING_CONNECTION_METERED,
NM_SETTING_CONNECTION_LLDP);
} else if (NM_IN_STRSET (setting_name,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_PROXY_SETTING_NAME)) {
/* accept all */
return TRUE;
} else {
g_set_error (error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
@ -8487,25 +8541,6 @@ can_reapply_change (NMDevice *self, const char *setting_name,
setting_name);
return FALSE;
}
/* whitelist allowed properties from "connection" setting which are allowed to differ.
*
* This includes UUID, there is no principal problem with reapplying a connection
* and changing it's UUID. In fact, disallowing it makes it cumbersome for the user
* to reapply any connection but the original settings-connection. */
if ( nm_streq0 (setting_name, NM_SETTING_CONNECTION_SETTING_NAME)
&& !nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_CONNECTION_SETTING_NAME,
error,
NM_SETTING_CONNECTION_ID,
NM_SETTING_CONNECTION_UUID,
NM_SETTING_CONNECTION_STABLE_ID,
NM_SETTING_CONNECTION_AUTOCONNECT,
NM_SETTING_CONNECTION_ZONE,
NM_SETTING_CONNECTION_METERED))
return FALSE;
return TRUE;
}
static void
@ -8645,6 +8680,7 @@ check_and_reapply_connection (NMDevice *self,
nm_device_update_firewall_zone (self);
nm_device_update_metered (self);
lldp_init (self, FALSE);
s_ip4_old = nm_connection_get_setting_ip4_config (con_old);
s_ip4_new = nm_connection_get_setting_ip4_config (con_new);
@ -8654,6 +8690,8 @@ check_and_reapply_connection (NMDevice *self,
nm_device_reactivate_ip4_config (self, s_ip4_old, s_ip4_new);
nm_device_reactivate_ip6_config (self, s_ip6_old, s_ip6_new);
reactivate_proxy_config (self);
return TRUE;
}
@ -9162,12 +9200,11 @@ nm_device_get_proxy_config (NMDevice *self)
}
static void
nm_device_set_proxy_config (NMDevice *self, GHashTable *options)
nm_device_set_proxy_config (NMDevice *self, const char *pac_url)
{
NMDevicePrivate *priv;
NMConnection *connection;
NMSettingProxy *s_proxy = NULL;
char *pac = NULL;
g_return_if_fail (NM_IS_DEVICE (self));
@ -9176,17 +9213,12 @@ nm_device_set_proxy_config (NMDevice *self, GHashTable *options)
g_clear_object (&priv->proxy_config);
priv->proxy_config = nm_proxy_config_new ();
if (options) {
pac = g_hash_table_lookup (options, "wpad");
if (pac) {
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
nm_proxy_config_set_pac_url (priv->proxy_config, pac);
_LOGD (LOGD_PROXY, "proxy: PAC url \"%s\"", pac);
} else {
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
_LOGD (LOGD_PROXY, "proxy: PAC url not obtained from DHCP server");
}
}
if (pac_url) {
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
nm_proxy_config_set_pac_url (priv->proxy_config, pac_url);
_LOGD (LOGD_PROXY, "proxy: PAC url \"%s\"", pac_url);
} else
nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
connection = nm_device_get_applied_connection (self);
if (connection)

View file

@ -3067,6 +3067,33 @@ set_enabled (NMDevice *device, gboolean enabled)
}
}
static gboolean
can_reapply_change (NMDevice *device,
const char *setting_name,
NMSetting *s_old,
NMSetting *s_new,
GHashTable *diffs,
GError **error)
{
NMDeviceClass *device_class;
/* Only handle wireless setting here, delegate other settings to parent class */
if (nm_streq (setting_name, NM_SETTING_WIRELESS_SETTING_NAME)) {
return nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_WIRELESS_SETTING_NAME,
error,
NM_SETTING_WIRELESS_MTU); /* reapplied with IP config */
}
device_class = NM_DEVICE_CLASS (nm_device_wifi_parent_class);
return device_class->can_reapply_change (device,
setting_name,
s_old,
s_new,
diffs,
error);
}
/*****************************************************************************/
static void
@ -3232,6 +3259,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->deactivate = deactivate;
parent_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr;
parent_class->unmanaged_on_quit = unmanaged_on_quit;
parent_class->can_reapply_change = can_reapply_change;
parent_class->state_changed = device_state_changed;