mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-07 00:31:11 +00:00
2008-03-07 Dan Williams <dcbw@redhat.com>
First pass of multiple active device support. Expect bugs. * src/nm-ip4-config.c src/nm-ip4-config.h - (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove; there are better ways to do this in the named manager * src/nm-device.c src/nm-device.h - (nm_device_can_activate): return whether the device can activate a connection right now; taking into account things like carrier state and rfkill state - (nm_device_get_best_auto_connection): renamed from nm_device_get_best_connection - (real_act_stage4_get_ip4_config): MTU stuff is now handled in the device subclasses themselves, so that each device can override the MTU from it's NMSetting subclass if needed - (nm_device_set_ip4_config): set MTU when setting up routes and stuff in NetworkManagerSystem.c, not here * src/named-manager/nm-named-manager.c src/named-manager/nm-named-manager.h - (nm_named_manager_name_owner_changed, nm_named_manager_dbus_connection_changed): fix for changes to rewrite_resolv_conf() - (compute_nameservers): don't need the NMNamedManager at all, remove from parameter list - (merge_one_ip4_config): new function; merge ip4 configs together - (rewrite_resolv_conf): write out resolv.conf from all the stored ip4 configs; the VPN config takes precedence, then the best device config, then the rest of the configs - (get_domain_for_config): take the NMNamedManager as an argument to check whether the config is the VPN config - (add_ip4_config_to_named): fixups for removal of the 'secondary' attribute from ip4 configs - (add_all_ip4_configs_to_named): add all the configs in priority order - (remove_ip4_config_from_named): fix for changes to get_domain_for_config() - (nm_named_manager_add_ip4_config): assign the config to the right slot based on its type; callers must pass in the type now - (get_last_default_domain): remove, unused - (nm_named_manager_remove_ip4_config): handle config slots correctly * src/nm-device-802-11-wireless.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): handle MTU override * src/nm-device-802-3-ethernet.c - (real_can_activate): new function - (real_get_best_auto_connection): renamed from real_get_best_connection - (real_act_stage4_get_ip4_config): new function; handle MTU override * src/vpn-manager/nm-vpn-connection.c - (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary' attribute on the ip4 config * src/NetworkManagerPolicy.c - (nm_policy_auto_get_best_device): remove - (nm_policy_device_change_check): remove - (update_default_route): new function; set the default route via the specified device - (get_device_priority): new function; return the priority number of a device type WRT which one should have the default route. Order is (highest to lowest) wired, wireless, GSM, CDMA. - (update_routing_and_dns): new function; determine which device should have the default route, then update the routing table and DNS - (maybe_auto_activate_device): new function; if a device is now available for activation, find out what connection it would like to activate and do it - (schedule_activate_check): new function; if a device can be activated now, schedule the activation. Each device may have only one pending activation at a given time. - (device_state_changed): if activation was canceled, try again, possibly with another connection; if the device was activated, update routing and DNS; if the device was deactivated, try again with another connection - (device_carrier_changed): if there is no carrier, deactivate the device; otherwise schedule an activation check for the device - (wireless_networks_changed): schedule an activation check for the device - (device_added): keep track of the signal handler IDs so they can be removed when the device goes away - (device_removed): remove any signal handlers that might be attached to the device; update routing and DNS - (schedule_activate_all): new function - (connections_added, connection_added, connection_updated): when connections change, schedule all devices for an activation check - (connection_removed): when a device is deactivated because its connection was removed, schedule another activation check for it - (nm_policy_destroy): destroy pending activations and disconnect all device signal handlers * src/nm-manager.c - (nm_manager_activate_device): if the device was already actived, deactivate it - (deactivate_old_device): remove - (connection_added_default_handler, impl_manager_activate_device): don't deactivate other devices when activating this one * src/backends/NetworkManagerGentoo.c src/backends/NetworkManagerFrugalware.c src/backends/NetworkManagerPaldo.c src/backends/NetworkManagerRedHat.c src/backends/NetworkManagerSlackware.c src/backends/NetworkManagerArch.c src/backends/NetworkManagerSuSE.c src/backends/NetworkManagerDebian.c - (nm_system_get_mtu): remove; MTU should be provided through the distro's system settings service plugin instead - (nm_system_device_add_default_route_via_device): remove - (nm_system_device_add_default_route_via_device_with_iface): remove - (nm_system_device_replace_default_route): new function; call generic implementation * src/backends/NetworkManagerGeneric.c src/backends/NetworkManagerGeneric.h - (nm_generic_device_add_default_route_via_device, nm_generic_device_add_default_route_via_device_with_iface): remove - (nm_generic_device_replace_default_route): replace the default route with the given route via some gateway * src/NetworkManagerSystem.c src/NetworkManagerSystem.h - (nm_system_device_set_from_ip4_config): let the policy handle updates to routing and DNS; but set the MTU here - (nm_system_vpn_device_set_from_ip4_config): set the route with the ip_iface of the active device; use the standard MTU setting function - (nm_system_set_mtu): remove - (nm_system_device_set_mtu): consolidate MTU setting code in one place git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
d84a51a145
commit
3fec481414
133
ChangeLog
133
ChangeLog
|
@ -1,3 +1,136 @@
|
|||
2008-03-07 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
First pass of multiple active device support. Expect bugs.
|
||||
|
||||
* src/nm-ip4-config.c
|
||||
src/nm-ip4-config.h
|
||||
- (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove;
|
||||
there are better ways to do this in the named manager
|
||||
|
||||
* src/nm-device.c
|
||||
src/nm-device.h
|
||||
- (nm_device_can_activate): return whether the device can activate a
|
||||
connection right now; taking into account things like carrier state
|
||||
and rfkill state
|
||||
- (nm_device_get_best_auto_connection): renamed from
|
||||
nm_device_get_best_connection
|
||||
- (real_act_stage4_get_ip4_config): MTU stuff is now handled in the
|
||||
device subclasses themselves, so that each device can override the
|
||||
MTU from it's NMSetting subclass if needed
|
||||
- (nm_device_set_ip4_config): set MTU when setting up routes and stuff
|
||||
in NetworkManagerSystem.c, not here
|
||||
|
||||
* src/named-manager/nm-named-manager.c
|
||||
src/named-manager/nm-named-manager.h
|
||||
- (nm_named_manager_name_owner_changed,
|
||||
nm_named_manager_dbus_connection_changed): fix for changes to
|
||||
rewrite_resolv_conf()
|
||||
- (compute_nameservers): don't need the NMNamedManager at all, remove
|
||||
from parameter list
|
||||
- (merge_one_ip4_config): new function; merge ip4 configs together
|
||||
- (rewrite_resolv_conf): write out resolv.conf from all the stored
|
||||
ip4 configs; the VPN config takes precedence, then the best
|
||||
device config, then the rest of the configs
|
||||
- (get_domain_for_config): take the NMNamedManager as an argument
|
||||
to check whether the config is the VPN config
|
||||
- (add_ip4_config_to_named): fixups for removal of the 'secondary'
|
||||
attribute from ip4 configs
|
||||
- (add_all_ip4_configs_to_named): add all the configs in priority order
|
||||
- (remove_ip4_config_from_named): fix for changes to
|
||||
get_domain_for_config()
|
||||
- (nm_named_manager_add_ip4_config): assign the config to the right slot
|
||||
based on its type; callers must pass in the type now
|
||||
- (get_last_default_domain): remove, unused
|
||||
- (nm_named_manager_remove_ip4_config): handle config slots correctly
|
||||
|
||||
* src/nm-device-802-11-wireless.c
|
||||
- (real_can_activate): new function
|
||||
- (real_get_best_auto_connection): renamed from real_get_best_connection
|
||||
- (real_act_stage4_get_ip4_config): handle MTU override
|
||||
|
||||
* src/nm-device-802-3-ethernet.c
|
||||
- (real_can_activate): new function
|
||||
- (real_get_best_auto_connection): renamed from real_get_best_connection
|
||||
- (real_act_stage4_get_ip4_config): new function; handle MTU override
|
||||
|
||||
* src/vpn-manager/nm-vpn-connection.c
|
||||
- (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary'
|
||||
attribute on the ip4 config
|
||||
|
||||
* src/NetworkManagerPolicy.c
|
||||
- (nm_policy_auto_get_best_device): remove
|
||||
- (nm_policy_device_change_check): remove
|
||||
- (update_default_route): new function; set the default route via
|
||||
the specified device
|
||||
- (get_device_priority): new function; return the priority number of
|
||||
a device type WRT which one should have the default route. Order is
|
||||
(highest to lowest) wired, wireless, GSM, CDMA.
|
||||
- (update_routing_and_dns): new function; determine which device should
|
||||
have the default route, then update the routing table and DNS
|
||||
- (maybe_auto_activate_device): new function; if a device is now
|
||||
available for activation, find out what connection it would like to
|
||||
activate and do it
|
||||
- (schedule_activate_check): new function; if a device can be activated
|
||||
now, schedule the activation. Each device may have only one
|
||||
pending activation at a given time.
|
||||
- (device_state_changed): if activation was canceled, try again,
|
||||
possibly with another connection; if the device was activated,
|
||||
update routing and DNS; if the device was deactivated, try again
|
||||
with another connection
|
||||
- (device_carrier_changed): if there is no carrier, deactivate the
|
||||
device; otherwise schedule an activation check for the device
|
||||
- (wireless_networks_changed): schedule an activation check for the
|
||||
device
|
||||
- (device_added): keep track of the signal handler IDs so they can
|
||||
be removed when the device goes away
|
||||
- (device_removed): remove any signal handlers that might be attached
|
||||
to the device; update routing and DNS
|
||||
- (schedule_activate_all): new function
|
||||
- (connections_added, connection_added, connection_updated): when
|
||||
connections change, schedule all devices for an activation check
|
||||
- (connection_removed): when a device is deactivated because its
|
||||
connection was removed, schedule another activation check for it
|
||||
- (nm_policy_destroy): destroy pending activations and disconnect
|
||||
all device signal handlers
|
||||
|
||||
* src/nm-manager.c
|
||||
- (nm_manager_activate_device): if the device was already actived,
|
||||
deactivate it
|
||||
- (deactivate_old_device): remove
|
||||
- (connection_added_default_handler, impl_manager_activate_device):
|
||||
don't deactivate other devices when activating this one
|
||||
|
||||
* src/backends/NetworkManagerGentoo.c
|
||||
src/backends/NetworkManagerFrugalware.c
|
||||
src/backends/NetworkManagerPaldo.c
|
||||
src/backends/NetworkManagerRedHat.c
|
||||
src/backends/NetworkManagerSlackware.c
|
||||
src/backends/NetworkManagerArch.c
|
||||
src/backends/NetworkManagerSuSE.c
|
||||
src/backends/NetworkManagerDebian.c
|
||||
- (nm_system_get_mtu): remove; MTU should be provided through the
|
||||
distro's system settings service plugin instead
|
||||
- (nm_system_device_add_default_route_via_device): remove
|
||||
- (nm_system_device_add_default_route_via_device_with_iface): remove
|
||||
- (nm_system_device_replace_default_route): new function; call
|
||||
generic implementation
|
||||
|
||||
* src/backends/NetworkManagerGeneric.c
|
||||
src/backends/NetworkManagerGeneric.h
|
||||
- (nm_generic_device_add_default_route_via_device,
|
||||
nm_generic_device_add_default_route_via_device_with_iface): remove
|
||||
- (nm_generic_device_replace_default_route): replace the default route
|
||||
with the given route via some gateway
|
||||
|
||||
* src/NetworkManagerSystem.c
|
||||
src/NetworkManagerSystem.h
|
||||
- (nm_system_device_set_from_ip4_config): let the policy handle updates
|
||||
to routing and DNS; but set the MTU here
|
||||
- (nm_system_vpn_device_set_from_ip4_config): set the route with the
|
||||
ip_iface of the active device; use the standard MTU setting function
|
||||
- (nm_system_set_mtu): remove
|
||||
- (nm_system_device_set_mtu): consolidate MTU setting code in one place
|
||||
|
||||
2008-03-07 Tambet Ingo <tambet@gmail.com>
|
||||
|
||||
Rework the interaction between ppp manager and pppd plugin. Register a well
|
||||
|
|
|
@ -3,3 +3,5 @@
|
|||
# Please keep this file sorted alphabetically.
|
||||
src/nm-netlink-monitor.c
|
||||
src/NetworkManager.c
|
||||
src/named-manager/nm-named-manager.c
|
||||
|
||||
|
|
|
@ -35,22 +35,28 @@
|
|||
#include "nm-activation-request.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-device-interface.h"
|
||||
#include "nm-device.h"
|
||||
#include "nm-device-802-11-wireless.h"
|
||||
#include "nm-device-802-3-ethernet.h"
|
||||
#include "nm-gsm-device.h"
|
||||
#include "nm-cdma-device.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "NetworkManagerSystem.h"
|
||||
#include "nm-named-manager.h"
|
||||
|
||||
struct NMPolicy {
|
||||
NMManager *manager;
|
||||
guint update_state_id;
|
||||
GSList *pending_activation_checks;
|
||||
GSList *signal_ids;
|
||||
GSList *dev_signal_ids;
|
||||
|
||||
NMDevice *default_device;
|
||||
};
|
||||
|
||||
#define INVALID_TAG "invalid"
|
||||
|
||||
static void schedule_change_check (NMPolicy *policy);
|
||||
|
||||
static const char *
|
||||
get_connection_id (NMConnection *connection)
|
||||
{
|
||||
|
@ -64,362 +70,149 @@ get_connection_id (NMConnection *connection)
|
|||
return s_con->id;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_policy_auto_get_best_device
|
||||
*
|
||||
* Find the best device to use, regardless of whether we are
|
||||
* "locked" on one device at this time.
|
||||
*
|
||||
*/
|
||||
static NMDevice *
|
||||
nm_policy_auto_get_best_device (NMPolicy *policy,
|
||||
NMConnection **connection,
|
||||
char **specific_object)
|
||||
static void
|
||||
update_default_route (NMPolicy *policy, NMDevice *new)
|
||||
{
|
||||
GSList *connections;
|
||||
GSList * elt;
|
||||
NMDevice8023Ethernet * best_wired_dev = NULL;
|
||||
guint best_wired_prio = 0;
|
||||
NMConnection * best_wired_connection = NULL;
|
||||
char * best_wired_specific_object = NULL;
|
||||
NMDevice80211Wireless * best_wireless_dev = NULL;
|
||||
guint best_wireless_prio = 0;
|
||||
NMConnection * best_wireless_connection = NULL;
|
||||
char * best_wireless_specific_object = NULL;
|
||||
NMDevice * highest_priority_dev = NULL;
|
||||
const char *ip_iface;
|
||||
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
g_return_val_if_fail (*connection == NULL, NULL);
|
||||
g_return_val_if_fail (specific_object != NULL, NULL);
|
||||
g_return_val_if_fail (*specific_object == NULL, NULL);
|
||||
/* FIXME: Not sure if the following makes any sense. */
|
||||
/* If iface and ip_iface are the same, it's a regular network device and we
|
||||
treat it as such. However, if they differ, it's most likely something like
|
||||
a serial device with ppp interface, so route all the traffic to it. */
|
||||
ip_iface = nm_device_get_ip_iface (new);
|
||||
if (strcmp (ip_iface, nm_device_get_iface (new))) {
|
||||
nm_system_device_replace_default_route (ip_iface, 0, 0);
|
||||
} else {
|
||||
NMIP4Config *config;
|
||||
|
||||
if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
|
||||
return NULL;
|
||||
config = nm_device_get_ip4_config (new);
|
||||
nm_system_device_replace_default_route (ip_iface, nm_ip4_config_get_gateway (config),
|
||||
nm_ip4_config_get_mss (config));
|
||||
}
|
||||
}
|
||||
|
||||
static guint32
|
||||
get_device_priority (NMDevice *dev)
|
||||
{
|
||||
if (NM_IS_CDMA_DEVICE (dev))
|
||||
return 2;
|
||||
|
||||
if (NM_IS_GSM_DEVICE (dev))
|
||||
return 3;
|
||||
|
||||
if (NM_IS_DEVICE_802_11_WIRELESS (dev))
|
||||
return 4;
|
||||
|
||||
if (NM_IS_DEVICE_802_3_ETHERNET (dev))
|
||||
return 5;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
update_routing_and_dns (NMPolicy *policy)
|
||||
{
|
||||
NMDevice *best = NULL;
|
||||
guint32 best_prio = 0;
|
||||
GSList *devices, *iter;
|
||||
NMNamedManager *named_mgr;
|
||||
NMIP4Config *config;
|
||||
|
||||
devices = nm_manager_get_devices (policy->manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *dev = NM_DEVICE (iter->data);
|
||||
guint32 prio;
|
||||
|
||||
if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED)
|
||||
continue;
|
||||
|
||||
prio = get_device_priority (dev);
|
||||
if (prio > best_prio) {
|
||||
best = dev;
|
||||
best_prio = prio;
|
||||
}
|
||||
}
|
||||
|
||||
if (!best)
|
||||
goto out;
|
||||
|
||||
update_default_route (policy, best);
|
||||
|
||||
named_mgr = nm_named_manager_get ();
|
||||
config = nm_device_get_ip4_config (best);
|
||||
nm_named_manager_add_ip4_config (named_mgr, config, NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
out:
|
||||
policy->default_device = best;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMPolicy *policy;
|
||||
NMDevice *device;
|
||||
guint id;
|
||||
} ActivateData;
|
||||
|
||||
static gboolean
|
||||
auto_activate_device (gpointer user_data)
|
||||
{
|
||||
ActivateData *data = (ActivateData *) user_data;
|
||||
NMPolicy *policy;
|
||||
NMConnection *best_connection;
|
||||
char *specific_object = NULL;
|
||||
GSList *connections, *iter;
|
||||
|
||||
g_assert (data);
|
||||
policy = data->policy;
|
||||
|
||||
/* System connections first, then user connections */
|
||||
connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_SYSTEM);
|
||||
connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_USER));
|
||||
|
||||
/* Remove connections that are in the invalid list. */
|
||||
elt = connections;
|
||||
while (elt) {
|
||||
NMConnection *iter_connection = NM_CONNECTION (elt->data);
|
||||
GSList *next = g_slist_next (elt);
|
||||
iter = connections;
|
||||
while (iter) {
|
||||
NMConnection *iter_connection = NM_CONNECTION (iter->data);
|
||||
GSList *next = g_slist_next (iter);
|
||||
|
||||
if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) {
|
||||
connections = g_slist_remove_link (connections, elt);
|
||||
connections = g_slist_remove_link (connections, iter);
|
||||
g_object_unref (iter_connection);
|
||||
g_slist_free (elt);
|
||||
g_slist_free (iter);
|
||||
}
|
||||
elt = next;
|
||||
iter = next;
|
||||
}
|
||||
|
||||
for (elt = nm_manager_get_devices (policy->manager); elt; elt = elt->next) {
|
||||
NMConnection *tmp_con = NULL;
|
||||
char *tmp_obj = NULL;
|
||||
gboolean carrier;
|
||||
guint prio = 0;
|
||||
NMDevice * dev = (NMDevice *)(elt->data);
|
||||
guint32 caps;
|
||||
best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object);
|
||||
if (best_connection) {
|
||||
GError *error = NULL;
|
||||
|
||||
carrier = nm_device_get_carrier (dev);
|
||||
caps = nm_device_get_capabilities (dev);
|
||||
|
||||
tmp_con = nm_device_get_best_connection (dev, connections, &tmp_obj);
|
||||
if (tmp_con == NULL) {
|
||||
NMActRequest *req = nm_device_get_act_request (dev);
|
||||
|
||||
/* If the device is activating, the NMConnection it's got is the
|
||||
* best one. In other words, follow activation of a particular
|
||||
* NMConnection through to success/failure rather than cutting it
|
||||
* off if it becomes invalid
|
||||
*/
|
||||
tmp_con = req ? nm_act_request_get_connection (req) : NULL;
|
||||
if (!tmp_con)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NM_IS_DEVICE_802_3_ETHERNET (dev)) {
|
||||
if (carrier)
|
||||
prio += 1;
|
||||
|
||||
if (nm_device_get_act_request (dev) && carrier)
|
||||
prio += 1;
|
||||
|
||||
if (prio > best_wired_prio) {
|
||||
best_wired_dev = NM_DEVICE_802_3_ETHERNET (dev);
|
||||
best_wired_prio = prio;
|
||||
best_wired_connection = tmp_con;
|
||||
best_wired_specific_object = tmp_obj;
|
||||
}
|
||||
} else if ( NM_IS_DEVICE_802_11_WIRELESS (dev)
|
||||
&& nm_manager_wireless_enabled (policy->manager)) {
|
||||
/* Bump by 1 so that _something_ gets chosen every time */
|
||||
prio += 1;
|
||||
|
||||
if (carrier)
|
||||
prio += 1;
|
||||
|
||||
if (nm_device_get_act_request (dev) && carrier)
|
||||
prio += 3;
|
||||
|
||||
if (prio > best_wireless_prio) {
|
||||
best_wireless_dev = NM_DEVICE_802_11_WIRELESS (dev);
|
||||
best_wireless_prio = prio;
|
||||
best_wireless_connection = tmp_con;
|
||||
best_wireless_specific_object = tmp_obj;
|
||||
}
|
||||
if (!nm_manager_activate_device (policy->manager,
|
||||
data->device,
|
||||
best_connection,
|
||||
specific_object,
|
||||
FALSE,
|
||||
&error)) {
|
||||
nm_warning ("Failed to automatically activate device %s: (%d) %s",
|
||||
nm_device_get_iface (data->device),
|
||||
error->code,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
if (best_wired_dev) {
|
||||
highest_priority_dev = NM_DEVICE (best_wired_dev);
|
||||
*connection = g_object_ref (best_wired_connection);
|
||||
*specific_object = best_wired_specific_object;
|
||||
} else if (best_wireless_dev) {
|
||||
gboolean can_activate;
|
||||
/* Remove this call's handler ID */
|
||||
policy->pending_activation_checks = g_slist_remove (policy->pending_activation_checks, data);
|
||||
|
||||
can_activate = nm_device_802_11_wireless_can_activate (best_wireless_dev);
|
||||
if (can_activate) {
|
||||
highest_priority_dev = NM_DEVICE (best_wireless_dev);
|
||||
*connection = g_object_ref (best_wireless_connection);
|
||||
*specific_object = best_wireless_specific_object;
|
||||
}
|
||||
}
|
||||
g_object_unref (data->device);
|
||||
|
||||
g_slist_foreach (connections, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (connections);
|
||||
|
||||
if (FALSE) {
|
||||
nm_info ("AUTO: Best wired device = %s, best wireless device = %s, best connection name = '%s'",
|
||||
best_wired_dev ? nm_device_get_iface (NM_DEVICE (best_wired_dev)) : "(null)",
|
||||
best_wireless_dev ? nm_device_get_iface (NM_DEVICE (best_wireless_dev)) : "(null)",
|
||||
*connection ? get_connection_id (*connection) : "(none)");
|
||||
}
|
||||
|
||||
return *connection ? highest_priority_dev : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_policy_device_change_check
|
||||
*
|
||||
* Figures out which interface to switch the active
|
||||
* network connection to if our global network state has changed.
|
||||
* Global network state changes are triggered by:
|
||||
* 1) insertion/deletion of interfaces
|
||||
* 2) link state change of an interface
|
||||
* 3) wireless network topology changes
|
||||
*
|
||||
*/
|
||||
static gboolean
|
||||
nm_policy_device_change_check (gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
GSList *iter;
|
||||
guint32 caps;
|
||||
NMConnection *connection = NULL;
|
||||
NMConnection *old_connection = NULL;
|
||||
NMActRequest *old_act_req = NULL;
|
||||
char * specific_object = NULL;
|
||||
NMDevice * new_dev = NULL;
|
||||
NMDevice * old_dev = NULL;
|
||||
gboolean do_switch = FALSE;
|
||||
|
||||
policy->update_state_id = 0;
|
||||
|
||||
switch (nm_manager_get_state (policy->manager)) {
|
||||
case NM_STATE_CONNECTED:
|
||||
old_dev = nm_manager_get_active_device (policy->manager);
|
||||
|
||||
/* Don't touch devices that are not upped/downed automatically */
|
||||
if (!NM_IS_DEVICE_802_3_ETHERNET (old_dev) && !NM_IS_DEVICE_802_11_WIRELESS (old_dev))
|
||||
goto out;
|
||||
|
||||
caps = nm_device_get_capabilities (old_dev);
|
||||
|
||||
/* Don't interrupt semi-supported devices. If the user chose
|
||||
* one, they must explicitly choose to move to another device, we're not
|
||||
* going to move for them.
|
||||
*/
|
||||
if ((NM_IS_DEVICE_802_3_ETHERNET (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT))) {
|
||||
nm_info ("Old device '%s' was semi-supported and user chosen, won't"
|
||||
" change unless told to.",
|
||||
nm_device_get_iface (old_dev));
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case NM_STATE_CONNECTING:
|
||||
for (iter = nm_manager_get_devices (policy->manager); iter; iter = iter->next) {
|
||||
NMDevice *d = NM_DEVICE (iter->data);
|
||||
|
||||
if (nm_device_is_activating (d)) {
|
||||
if (nm_device_can_interrupt_activation (d)) {
|
||||
old_dev = d;
|
||||
break;
|
||||
} else
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_STATE_DISCONNECTED:
|
||||
if (nm_manager_activation_pending (policy->manager)) {
|
||||
nm_info ("There is a pending activation, won't change.");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
new_dev = nm_policy_auto_get_best_device (policy, &connection, &specific_object);
|
||||
|
||||
if (old_dev) {
|
||||
old_act_req = nm_device_get_act_request (old_dev);
|
||||
if (old_act_req)
|
||||
old_connection = nm_act_request_get_connection (old_act_req);
|
||||
}
|
||||
|
||||
/* Four cases here:
|
||||
*
|
||||
* 1) old device is NULL, new device is NULL - we aren't currently connected to anything, and we
|
||||
* can't find anything to connect to. Do nothing.
|
||||
*
|
||||
* 2) old device is NULL, new device is good - we aren't currently connected to anything, but
|
||||
* we have something we can connect to. Connect to it.
|
||||
*
|
||||
* 3) old device is good, new device is NULL - have a current connection, but it's no good since
|
||||
* auto device picking didn't come up with the save device. Terminate current connection.
|
||||
*
|
||||
* 4) old device is good, new device is good - have a current connection, and auto device picking
|
||||
* came up with a device too. More considerations:
|
||||
* a) different devices? activate new device
|
||||
* b) same device, different access points? activate new device
|
||||
* c) same device, same access point? do nothing
|
||||
*/
|
||||
|
||||
if (!old_dev && !new_dev) {
|
||||
; /* Do nothing, wait for something like link-state to change, or an access point to be found */
|
||||
} else if (!old_dev && new_dev) {
|
||||
/* Activate new device */
|
||||
nm_info ("SWITCH: no current connection, found better connection '%s (%s)'.",
|
||||
connection ? get_connection_id (connection) : "(none)",
|
||||
nm_device_get_iface (new_dev));
|
||||
do_switch = TRUE;
|
||||
} else if (old_dev && !new_dev) {
|
||||
/* Terminate current connection */
|
||||
nm_info ("SWITCH: terminating current connection '%s (%s)' because it's"
|
||||
" no longer valid.",
|
||||
old_connection ? get_connection_id (old_connection) : "(none)",
|
||||
nm_device_get_iface (old_dev));
|
||||
do_switch = TRUE;
|
||||
} else if (old_dev && new_dev) {
|
||||
gboolean old_user_requested = nm_act_request_get_user_requested (old_act_req);
|
||||
gboolean old_carrier = nm_device_get_carrier (old_dev);
|
||||
|
||||
/* If an old device is active or being activated (and has an active link),
|
||||
* and its connection is a system connection, and the best connection is
|
||||
* a user connection, don't switch.
|
||||
*/
|
||||
if ( old_connection
|
||||
&& (nm_connection_get_scope (old_connection) == NM_CONNECTION_SCOPE_SYSTEM)
|
||||
&& (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_USER)
|
||||
&& old_carrier)
|
||||
goto out;
|
||||
|
||||
if ( (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM)
|
||||
&& (nm_connection_get_scope (old_connection) == NM_CONNECTION_SCOPE_USER)) {
|
||||
do_switch = TRUE;
|
||||
nm_info ("SWITCH: found system connection '%s (%s)', overrides"
|
||||
" current connection '%s (%s)'.",
|
||||
connection ? get_connection_id (connection) : "(none)",
|
||||
nm_device_get_iface (new_dev),
|
||||
old_connection ? get_connection_id (old_connection) : "(none)",
|
||||
nm_device_get_iface (old_dev));
|
||||
goto do_switch;
|
||||
}
|
||||
|
||||
if (NM_IS_DEVICE_802_3_ETHERNET (old_dev)) {
|
||||
/* Only switch if the old device was not user requested, and we are switching to
|
||||
* a new device. Note that new_dev will never be wireless since automatic device picking
|
||||
* above will prefer a wired device to a wireless device.
|
||||
*/
|
||||
if ((!old_user_requested || !old_carrier) && (new_dev != old_dev)) {
|
||||
nm_info ("SWITCH: found better connection '%s (%s)' than "
|
||||
" current connection '%s (%s)'.",
|
||||
connection ? get_connection_id (connection) : "(none)",
|
||||
nm_device_get_iface (new_dev),
|
||||
old_connection ? get_connection_id (old_connection) : "(none)",
|
||||
nm_device_get_iface (old_dev));
|
||||
do_switch = TRUE;
|
||||
}
|
||||
} else if (NM_IS_DEVICE_802_11_WIRELESS (old_dev)) {
|
||||
/* Only switch if the old device's wireless config is invalid */
|
||||
if (NM_IS_DEVICE_802_11_WIRELESS (new_dev)) {
|
||||
NMAccessPoint *old_ap = nm_device_802_11_wireless_get_activation_ap (NM_DEVICE_802_11_WIRELESS (old_dev));
|
||||
int old_mode = nm_ap_get_mode (old_ap);
|
||||
gboolean same_activating = FALSE;
|
||||
|
||||
/* Don't interrupt activation of a wireless device by
|
||||
* trying to auto-activate any connection on that device.
|
||||
*/
|
||||
if (old_dev == new_dev && nm_device_is_activating (new_dev))
|
||||
same_activating = TRUE;
|
||||
|
||||
if (!same_activating && !old_carrier && (old_mode != IW_MODE_ADHOC)) {
|
||||
NMSettingConnection * new_sc = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
NMSettingConnection * old_sc = (NMSettingConnection *) nm_connection_get_setting (old_connection, NM_TYPE_SETTING_CONNECTION);
|
||||
|
||||
nm_info ("SWITCH: found better connection '%s/%s'"
|
||||
" than current connection '%s/%s'. "
|
||||
"have_link=%d",
|
||||
nm_device_get_iface (new_dev),
|
||||
new_sc->id,
|
||||
nm_device_get_iface (old_dev),
|
||||
old_sc->id,
|
||||
old_carrier);
|
||||
do_switch = TRUE;
|
||||
}
|
||||
} else if (NM_IS_DEVICE_802_3_ETHERNET (new_dev)) {
|
||||
/* Always prefer Ethernet over wireless, unless the user explicitly switched away. */
|
||||
if (!old_user_requested)
|
||||
do_switch = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_switch:
|
||||
if (do_switch) {
|
||||
// FIXME: remove old_dev deactivation when multiple device support lands
|
||||
if (old_dev)
|
||||
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (old_dev));
|
||||
|
||||
if (new_dev) {
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
success = nm_manager_activate_device (policy->manager,
|
||||
new_dev,
|
||||
connection,
|
||||
specific_object,
|
||||
FALSE,
|
||||
&error);
|
||||
if (!success) {
|
||||
nm_warning ("Failed to automatically activate device %s: (%d) %s",
|
||||
nm_device_get_iface (new_dev),
|
||||
error->code,
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (connection)
|
||||
g_object_unref (connection);
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
@ -430,13 +223,41 @@ global_state_changed (NMManager *manager, NMState state, gpointer user_data)
|
|||
}
|
||||
|
||||
static void
|
||||
schedule_change_check (NMPolicy *policy)
|
||||
schedule_activate_check (NMPolicy *policy, NMDevice *device)
|
||||
{
|
||||
if (policy->update_state_id > 0)
|
||||
ActivateData *data;
|
||||
GSList *iter;
|
||||
gboolean wireless_enabled;
|
||||
|
||||
if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP)
|
||||
return;
|
||||
|
||||
policy->update_state_id = g_idle_add (nm_policy_device_change_check,
|
||||
policy);
|
||||
// FIXME: kind of a hack, but devices don't have access to the manager
|
||||
// object directly
|
||||
wireless_enabled = nm_manager_wireless_enabled (policy->manager);
|
||||
if (!nm_device_can_activate (device, wireless_enabled))
|
||||
return;
|
||||
|
||||
// FIXME: if a device is already activating (or activated) with a connection
|
||||
// but another connection now overrides the current one for that device,
|
||||
// deactivate the device and activate the new connection instead of just
|
||||
// bailing if the device is already active
|
||||
if (nm_device_get_act_request (device))
|
||||
return;
|
||||
|
||||
for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) {
|
||||
/* Only one pending activation check at a time */
|
||||
if (((ActivateData *) iter->data)->device == device)
|
||||
return;
|
||||
}
|
||||
|
||||
data = g_malloc0 (sizeof (ActivateData));
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
data->policy = policy;
|
||||
data->device = g_object_ref (device);
|
||||
data->id = g_idle_add (auto_activate_device, data);
|
||||
policy->pending_activation_checks = g_slist_append (policy->pending_activation_checks, data);
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
|
@ -458,69 +279,126 @@ device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
|
|||
NMConnection *connection = get_device_connection (device);
|
||||
|
||||
if ((state == NM_DEVICE_STATE_FAILED) || (state == NM_DEVICE_STATE_CANCELLED)) {
|
||||
schedule_change_check (policy);
|
||||
|
||||
/* Mark the connection invalid so it doesn't get automatically chosen */
|
||||
if (connection) {
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
|
||||
nm_info ("Marking connection '%s' invalid.", get_connection_id (connection));
|
||||
}
|
||||
|
||||
if (state == NM_DEVICE_STATE_CANCELLED)
|
||||
schedule_activate_check (policy, device);
|
||||
} else if (state == NM_DEVICE_STATE_ACTIVATED) {
|
||||
/* Clear the invalid tag on the connection */
|
||||
if (connection)
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
|
||||
|
||||
update_routing_and_dns (policy);
|
||||
} else if (state == NM_DEVICE_STATE_DISCONNECTED) {
|
||||
schedule_change_check (policy);
|
||||
update_routing_and_dns (policy);
|
||||
|
||||
schedule_activate_check (policy, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
device_carrier_changed (NMDevice *device, gboolean carrier_on, gpointer user_data)
|
||||
device_carrier_changed (NMDevice *device, gboolean carrier, gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
|
||||
schedule_change_check (policy);
|
||||
if (!carrier) {
|
||||
if (NM_IS_DEVICE_802_3_ETHERNET (device))
|
||||
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device));
|
||||
} else {
|
||||
schedule_activate_check ((NMPolicy *) user_data, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wireless_networks_changed (NMDevice80211Wireless *device, NMAccessPoint *ap, gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device));
|
||||
}
|
||||
|
||||
schedule_change_check (policy);
|
||||
typedef struct {
|
||||
gulong id;
|
||||
NMDevice *device;
|
||||
} DeviceSignalID;
|
||||
|
||||
static GSList *
|
||||
add_device_signal_id (GSList *list, gulong id, NMDevice *device)
|
||||
{
|
||||
DeviceSignalID *data;
|
||||
|
||||
data = g_malloc0 (sizeof (DeviceSignalID));
|
||||
if (!data)
|
||||
return list;
|
||||
|
||||
data->id = id;
|
||||
data->device = device;
|
||||
return g_slist_append (list, data);
|
||||
}
|
||||
|
||||
static void
|
||||
device_added (NMManager *manager, NMDevice *device, gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
gulong id;
|
||||
|
||||
g_signal_connect (device, "state-changed",
|
||||
G_CALLBACK (device_state_changed),
|
||||
policy);
|
||||
id = g_signal_connect (device, "state-changed",
|
||||
G_CALLBACK (device_state_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
g_signal_connect (device, "carrier-changed",
|
||||
G_CALLBACK (device_carrier_changed),
|
||||
policy);
|
||||
id = g_signal_connect (device, "carrier-changed",
|
||||
G_CALLBACK (device_carrier_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
if (NM_IS_DEVICE_802_11_WIRELESS (device)) {
|
||||
g_signal_connect (device, "access-point-added",
|
||||
G_CALLBACK (wireless_networks_changed),
|
||||
policy);
|
||||
g_signal_connect (device, "access-point-removed",
|
||||
G_CALLBACK (wireless_networks_changed),
|
||||
policy);
|
||||
id = g_signal_connect (device, "access-point-added",
|
||||
G_CALLBACK (wireless_networks_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
id = g_signal_connect (device, "access-point-removed",
|
||||
G_CALLBACK (wireless_networks_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
}
|
||||
|
||||
schedule_change_check (policy);
|
||||
schedule_activate_check (policy, device);
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
GSList *iter = policy->dev_signal_ids;
|
||||
|
||||
schedule_change_check (policy);
|
||||
/* Clear any signal handlers for this device */
|
||||
while (iter) {
|
||||
DeviceSignalID *data = (DeviceSignalID *) iter->data;
|
||||
GSList *next = g_slist_next (iter);
|
||||
|
||||
if (data->device == device) {
|
||||
policy->dev_signal_ids = g_slist_remove_link (policy->dev_signal_ids, iter);
|
||||
|
||||
g_signal_handler_disconnect (data->device, data->id);
|
||||
g_free (data);
|
||||
g_slist_free (iter);
|
||||
}
|
||||
iter = next;
|
||||
}
|
||||
|
||||
update_routing_and_dns (policy);
|
||||
}
|
||||
|
||||
static void
|
||||
schedule_activate_all (NMPolicy *policy)
|
||||
{
|
||||
GSList *iter, *devices;
|
||||
|
||||
devices = nm_manager_get_devices (policy->manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter))
|
||||
schedule_activate_check (policy, NM_DEVICE (iter->data));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -528,9 +406,7 @@ connections_added (NMManager *manager,
|
|||
NMConnectionScope scope,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
|
||||
schedule_change_check (policy);
|
||||
schedule_activate_all ((NMPolicy *) user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -539,9 +415,7 @@ connection_added (NMManager *manager,
|
|||
NMConnectionScope scope,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
|
||||
schedule_change_check (policy);
|
||||
schedule_activate_all ((NMPolicy *) user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -550,12 +424,10 @@ connection_updated (NMManager *manager,
|
|||
NMConnectionScope scope,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
|
||||
/* Clear the invalid tag on the connection if it got updated. */
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
|
||||
|
||||
schedule_change_check (policy);
|
||||
schedule_activate_all ((NMPolicy *) user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -564,12 +436,11 @@ connection_removed (NMManager *manager,
|
|||
NMConnectionScope scope,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
GSList *iter;
|
||||
|
||||
/* If the connection just removed was active, deactive it */
|
||||
for (iter = nm_manager_get_devices (manager); iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *device = (NMDevice *) iter->data;
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
NMActRequest *req = nm_device_get_act_request (device);
|
||||
NMConnection *dev_connection;
|
||||
|
||||
|
@ -577,11 +448,11 @@ connection_removed (NMManager *manager,
|
|||
continue;
|
||||
|
||||
dev_connection = nm_act_request_get_connection (req);
|
||||
if (dev_connection == connection)
|
||||
if (dev_connection == connection) {
|
||||
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device));
|
||||
schedule_activate_check ((NMPolicy *) user_data, device);
|
||||
}
|
||||
}
|
||||
|
||||
schedule_change_check (policy);
|
||||
}
|
||||
|
||||
NMPolicy *
|
||||
|
@ -640,15 +511,27 @@ nm_policy_destroy (NMPolicy *policy)
|
|||
|
||||
g_return_if_fail (policy != NULL);
|
||||
|
||||
if (policy->update_state_id) {
|
||||
g_source_remove (policy->update_state_id);
|
||||
policy->update_state_id = 0;
|
||||
for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) {
|
||||
ActivateData *data = (ActivateData *) iter->data;
|
||||
|
||||
g_source_remove (data->id);
|
||||
g_object_unref (data->device);
|
||||
g_free (data);
|
||||
}
|
||||
g_slist_free (policy->pending_activation_checks);
|
||||
|
||||
for (iter = policy->signal_ids; iter; iter = g_slist_next (iter))
|
||||
g_signal_handler_disconnect (policy->manager, (gulong) iter->data);
|
||||
g_slist_free (policy->signal_ids);
|
||||
|
||||
for (iter = policy->dev_signal_ids; iter; iter = g_slist_next (iter)) {
|
||||
DeviceSignalID *data = (DeviceSignalID *) iter->data;
|
||||
|
||||
g_signal_handler_disconnect (data->device, data->id);
|
||||
g_free (data);
|
||||
}
|
||||
g_slist_free (policy->dev_signal_ids);
|
||||
|
||||
g_object_unref (policy->manager);
|
||||
g_free (policy);
|
||||
}
|
||||
|
|
|
@ -190,11 +190,9 @@ nm_system_device_set_from_ip4_config (const char *iface,
|
|||
NMIP4Config *config,
|
||||
gboolean route_to_iface)
|
||||
{
|
||||
NMNamedManager * named_mgr;
|
||||
struct nl_handle * nlh = NULL;
|
||||
struct rtnl_addr * addr = NULL;
|
||||
int err;
|
||||
int len, i;
|
||||
struct nl_handle *nlh = NULL;
|
||||
struct rtnl_addr *addr = NULL;
|
||||
int len, i, err;
|
||||
guint32 flags;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
|
@ -224,13 +222,6 @@ nm_system_device_set_from_ip4_config (const char *iface,
|
|||
|
||||
sleep (1);
|
||||
|
||||
if (route_to_iface)
|
||||
nm_system_device_add_default_route_via_device_with_iface (iface);
|
||||
else
|
||||
nm_system_device_set_ip4_route (iface, config,
|
||||
nm_ip4_config_get_gateway (config), 0, 0,
|
||||
nm_ip4_config_get_mss (config));
|
||||
|
||||
len = nm_ip4_config_get_num_static_routes (config);
|
||||
for (i = 0; i < len; i++) {
|
||||
guint32 mss = nm_ip4_config_get_mss (config);
|
||||
|
@ -240,9 +231,8 @@ nm_system_device_set_from_ip4_config (const char *iface,
|
|||
nm_system_device_set_ip4_route (iface, config, route, saddr, 0xffffffff, mss);
|
||||
}
|
||||
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_add_ip4_config (named_mgr, config);
|
||||
g_object_unref (named_mgr);
|
||||
if (nm_ip4_config_get_mtu (config))
|
||||
nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -339,7 +329,6 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
|
|||
NMIP4Config * ad_config = NULL;
|
||||
struct nl_handle * nlh = NULL;
|
||||
struct rtnl_addr * addr = NULL;
|
||||
struct rtnl_link * request = NULL;
|
||||
NMNamedManager *named_mgr;
|
||||
int iface_idx;
|
||||
|
||||
|
@ -347,7 +336,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
|
|||
|
||||
/* Set up a route to the VPN gateway through the real network device */
|
||||
if (active_device && (ad_config = nm_device_get_ip4_config (active_device))) {
|
||||
nm_system_device_set_ip4_route (nm_device_get_iface (active_device),
|
||||
nm_system_device_set_ip4_route (nm_device_get_ip_iface (active_device),
|
||||
ad_config,
|
||||
nm_ip4_config_get_gateway (ad_config),
|
||||
nm_ip4_config_get_gateway (config),
|
||||
|
@ -376,28 +365,15 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
|
|||
nm_warning ("couldn't create rtnl address!\n");
|
||||
|
||||
/* Set the MTU */
|
||||
if ((request = rtnl_link_alloc ())) {
|
||||
struct rtnl_link * old;
|
||||
guint32 mtu;
|
||||
|
||||
old = nm_netlink_index_to_rtnl_link (iface_idx);
|
||||
mtu = nm_ip4_config_get_mtu (config);
|
||||
if (mtu == 0)
|
||||
mtu = 1412; /* Default to 1412 (vpnc) */
|
||||
rtnl_link_set_mtu (request, mtu);
|
||||
rtnl_link_change (nlh, old, request, 0);
|
||||
|
||||
rtnl_link_put (old);
|
||||
rtnl_link_put (request);
|
||||
}
|
||||
if (nm_ip4_config_get_mtu (config))
|
||||
nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
|
||||
|
||||
sleep (1);
|
||||
|
||||
nm_system_device_flush_routes_with_iface (iface);
|
||||
|
||||
if (g_slist_length (routes) == 0) {
|
||||
nm_system_delete_default_route ();
|
||||
nm_system_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_system_device_replace_default_route (iface, 0, 0);
|
||||
} else {
|
||||
GSList *iter;
|
||||
|
||||
|
@ -421,7 +397,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
|
|||
|
||||
out:
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_add_ip4_config (named_mgr, config);
|
||||
nm_named_manager_add_ip4_config (named_mgr, config, NM_NAMED_IP_CONFIG_TYPE_VPN);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
return TRUE;
|
||||
|
@ -498,42 +474,37 @@ out:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_set_mtu
|
||||
*
|
||||
* Set the MTU for a given device.
|
||||
*/
|
||||
void nm_system_set_mtu (NMDevice *dev)
|
||||
gboolean
|
||||
nm_system_device_set_mtu (const char *iface, guint32 mtu)
|
||||
{
|
||||
struct rtnl_link * request;
|
||||
struct rtnl_link * old;
|
||||
unsigned long mtu;
|
||||
struct nl_handle * nlh;
|
||||
guint32 idx;
|
||||
struct rtnl_link *old;
|
||||
struct rtnl_link *new;
|
||||
gboolean success = FALSE;
|
||||
struct nl_handle *nlh;
|
||||
int iface_idx;
|
||||
|
||||
mtu = nm_system_get_mtu (dev);
|
||||
if (!mtu)
|
||||
return;
|
||||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
g_return_val_if_fail (mtu > 0, FALSE);
|
||||
|
||||
request = rtnl_link_alloc ();
|
||||
if (!request)
|
||||
return;
|
||||
new = rtnl_link_alloc ();
|
||||
if (!new)
|
||||
return FALSE;
|
||||
|
||||
idx = nm_netlink_iface_to_index (nm_device_get_iface (dev));
|
||||
old = nm_netlink_index_to_rtnl_link (idx);
|
||||
if (!old)
|
||||
goto out_request;
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
old = nm_netlink_index_to_rtnl_link (iface_idx);
|
||||
if (old) {
|
||||
rtnl_link_set_mtu (new, mtu);
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
if (nlh) {
|
||||
rtnl_link_change (nlh, old, new, 0);
|
||||
success = TRUE;
|
||||
}
|
||||
rtnl_link_put (old);
|
||||
}
|
||||
|
||||
nm_info ("Setting MTU of interface '%s' to %ld",
|
||||
nm_device_get_iface (dev),
|
||||
mtu);
|
||||
rtnl_link_set_mtu (request, mtu);
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
if (nlh)
|
||||
rtnl_link_change (nlh, old, request, 0);
|
||||
|
||||
rtnl_link_put (old);
|
||||
out_request:
|
||||
rtnl_link_put (request);
|
||||
rtnl_link_put (new);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,8 +38,9 @@ gboolean nm_system_device_has_active_routes (NMDevice *dev);
|
|||
void nm_system_device_flush_routes (NMDevice *dev);
|
||||
void nm_system_device_flush_routes_with_iface (const char *iface);
|
||||
|
||||
void nm_system_device_add_default_route_via_device(NMDevice *dev);
|
||||
void nm_system_device_add_default_route_via_device_with_iface(const char *iface);
|
||||
void nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss);
|
||||
|
||||
void nm_system_device_add_route_via_device_with_iface (const char *iface, const char *route);
|
||||
|
||||
|
@ -82,8 +83,7 @@ void nm_system_set_hostname (NMIP4Config *config);
|
|||
void nm_system_activate_nis (NMIP4Config *config);
|
||||
void nm_system_shutdown_nis (void);
|
||||
|
||||
void nm_system_set_mtu (NMDevice *dev);
|
||||
guint32 nm_system_get_mtu (NMDevice *dev);
|
||||
gboolean nm_system_device_set_mtu (const char *iface, guint32 mtu);
|
||||
|
||||
gboolean nm_system_should_modify_resolv_conf (void);
|
||||
|
||||
|
|
|
@ -65,26 +65,17 @@ void nm_system_init (void)
|
|||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -686,14 +677,3 @@ void nm_system_set_hostname (NMIP4Config *config)
|
|||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -54,26 +54,17 @@ void nm_system_init (void)
|
|||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -405,14 +396,3 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -243,37 +243,21 @@ void nm_system_device_add_route_via_device_with_iface (const char *iface, const
|
|||
g_free (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
*
|
||||
* Flush all routes associated with a network device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev));
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
g_return_if_fail (iface != NULL);
|
||||
|
||||
/* Add default gateway */
|
||||
buf = g_strdup_printf ("/usr/sbin/ip route add default dev %s", iface);
|
||||
nm_spawn_process (buf);
|
||||
g_free (buf);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_flush_loopback_routes
|
||||
|
@ -371,17 +355,6 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_get_system_config
|
||||
*
|
||||
|
|
|
@ -50,33 +50,34 @@ void nm_generic_init (void)
|
|||
}
|
||||
|
||||
/*
|
||||
* nm_generic_device_add_default_route_via_device
|
||||
* nm_generic_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
* Replace default route with one via the current device
|
||||
*
|
||||
*/
|
||||
void nm_generic_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_generic_device_replace_default_route (const char *iface, guint32 gw, guint32 mss)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
nm_system_device_add_default_route_via_device_with_iface (nm_device_get_iface (dev));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_generic_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_generic_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
char *buf;
|
||||
char *buf, *addr_str = NULL, *mss_str = NULL;
|
||||
|
||||
g_return_if_fail (iface != NULL);
|
||||
|
||||
/* Add default gateway */
|
||||
buf = g_strdup_printf (IP_BINARY_PATH" route add default dev %s", iface);
|
||||
if (gw > 0) {
|
||||
struct in_addr addr = { .s_addr = gw };
|
||||
char buf2[INET_ADDRSTRLEN + 1];
|
||||
|
||||
memset (buf2, 0, sizeof (buf2));
|
||||
inet_ntop (AF_INET, &addr, buf2, INET_ADDRSTRLEN);
|
||||
addr_str = g_strdup_printf ("via %s", buf2);
|
||||
}
|
||||
|
||||
if (mss > 0)
|
||||
mss_str = g_strdup_printf ("advmss %d", mss);
|
||||
|
||||
buf = g_strdup_printf (IP_BINARY_PATH" route replace default %s %s dev %s",
|
||||
addr_str ? addr_str : "",
|
||||
mss_str ? mss_str : "",
|
||||
iface);
|
||||
nm_spawn_process (buf);
|
||||
g_free (buf);
|
||||
}
|
||||
|
@ -452,14 +453,3 @@ gboolean nm_generic_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_generic_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_generic_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,7 @@ gboolean nm_generic_device_has_active_routes (NMDevice *dev);
|
|||
void nm_generic_device_flush_routes (NMDevice *dev);
|
||||
void nm_generic_device_flush_routes_with_iface (const char *iface);
|
||||
|
||||
void nm_generic_device_add_default_route_via_device(NMDevice *dev);
|
||||
void nm_generic_device_add_default_route_via_device_with_iface(const char *iface);
|
||||
void nm_generic_device_replace_default_route (const char *iface, guint32 gw, guint32 mss);
|
||||
|
||||
void nm_generic_device_add_route_via_device_with_iface (const char *iface, const char *route);
|
||||
|
||||
|
@ -78,9 +77,6 @@ void nm_generic_set_hostname (NMIP4Config *config);
|
|||
void nm_generic_activate_nis (NMIP4Config *config);
|
||||
void nm_generic_shutdown_nis (void);
|
||||
|
||||
void nm_generic_set_mtu (NMDevice *dev);
|
||||
guint32 nm_generic_get_mtu (NMDevice *dev);
|
||||
|
||||
gboolean nm_generic_should_modify_resolv_conf (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -404,25 +404,17 @@ void *nm_system_device_get_system_config (NMDevice *dev)
|
|||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
*
|
||||
* Flush all routes associated with a network device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data)
|
||||
|
@ -491,13 +483,4 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,26 +76,17 @@ void nm_system_device_flush_routes_with_iface (const char *iface)
|
|||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
|
||||
|
@ -527,13 +518,3 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
unsigned int nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -73,26 +73,17 @@ void nm_system_device_flush_routes_with_iface (const char *iface)
|
|||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,14 +534,3 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -219,25 +219,17 @@ void nm_system_device_add_route_via_device_with_iface (const char *iface, const
|
|||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
*
|
||||
* Flush all routes associated with a network device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
|
||||
|
@ -322,14 +314,3 @@ gboolean nm_system_should_modify_resolv_conf (void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -80,26 +80,17 @@ void nm_system_device_flush_routes_with_iface (const char *iface)
|
|||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device
|
||||
* nm_system_device_replace_default_route
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device (NMDevice *dev)
|
||||
void
|
||||
nm_system_device_replace_default_route (const char *iface,
|
||||
guint32 gw,
|
||||
guint32 mss)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_device_add_default_route_via_device_with_iface
|
||||
*
|
||||
* Add default route to the given device
|
||||
*
|
||||
*/
|
||||
void nm_system_device_add_default_route_via_device_with_iface (const char *iface)
|
||||
{
|
||||
nm_generic_device_add_default_route_via_device_with_iface (iface);
|
||||
nm_generic_device_replace_default_route (iface, gw, mss);
|
||||
}
|
||||
|
||||
|
||||
|
@ -724,20 +715,3 @@ out_gfree:
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_system_get_mtu
|
||||
*
|
||||
* Return a user-provided or system-mandated MTU for this device or zero if
|
||||
* no such MTU is provided.
|
||||
*/
|
||||
guint32 nm_system_get_mtu (NMDevice *dev)
|
||||
{
|
||||
SuSEDeviceConfigData * sys_data;
|
||||
|
||||
sys_data = nm_device_get_system_config_data (dev);
|
||||
if (!sys_data)
|
||||
return 0;
|
||||
|
||||
return sys_data->mtu;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <glib.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-utils.h"
|
||||
#include "NetworkManagerSystem.h"
|
||||
|
@ -61,19 +63,20 @@ G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
|
|||
NM_TYPE_NAMED_MANAGER, \
|
||||
NMNamedManagerPrivate))
|
||||
|
||||
static NMIP4Config *get_last_default_domain (NMNamedManager *mgr);
|
||||
|
||||
static gboolean add_all_ip4_configs_to_named (NMNamedManager *mgr);
|
||||
|
||||
static gboolean rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error);
|
||||
static gboolean rewrite_resolv_conf (NMNamedManager *mgr, GError **error);
|
||||
|
||||
static gboolean remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config);
|
||||
|
||||
|
||||
struct NMNamedManagerPrivate {
|
||||
gboolean use_named;
|
||||
NMDBusManager * dbus_mgr;
|
||||
GSList * configs;
|
||||
gboolean use_named;
|
||||
NMDBusManager * dbus_mgr;
|
||||
|
||||
NMIP4Config * vpn_config;
|
||||
NMIP4Config * device_config;
|
||||
GSList * configs;
|
||||
|
||||
gboolean disposed;
|
||||
};
|
||||
|
@ -145,7 +148,7 @@ nm_named_manager_name_owner_changed (NMDBusManager *dbus_mgr,
|
|||
|
||||
if (handled) {
|
||||
GError *error = NULL;
|
||||
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
|
||||
if (!rewrite_resolv_conf (mgr, &error)) {
|
||||
nm_warning ("Could not write resolv.conf. Error: '%s'",
|
||||
error ? error->message : "(none)");
|
||||
g_error_free (error);
|
||||
|
@ -177,7 +180,7 @@ nm_named_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
|
|||
|
||||
if (handled) {
|
||||
GError *error = NULL;
|
||||
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
|
||||
if (!rewrite_resolv_conf (mgr, &error)) {
|
||||
nm_warning ("Could not write resolv.conf. Error: '%s'",
|
||||
error ? error->message : "(none)");
|
||||
g_error_free (error);
|
||||
|
@ -186,87 +189,79 @@ nm_named_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
|
|||
}
|
||||
|
||||
static char *
|
||||
compute_nameservers (NMNamedManager *mgr, NMIP4Config *config)
|
||||
compute_nameservers (NMIP4Config *config)
|
||||
{
|
||||
int i, num_nameservers;
|
||||
int i, num;
|
||||
GString *str = NULL;
|
||||
|
||||
g_return_val_if_fail (mgr != NULL, g_strdup (""));
|
||||
g_return_val_if_fail (config != NULL, g_strdup (""));
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
num_nameservers = nm_ip4_config_get_num_nameservers (config);
|
||||
if (num_nameservers > 3)
|
||||
num_nameservers = 3; /* 'man resolv.conf' says we can't have > 3 */
|
||||
for (i = 0; i < num_nameservers; i++)
|
||||
{
|
||||
num = nm_ip4_config_get_num_nameservers (config);
|
||||
if (num == 0)
|
||||
return NULL;
|
||||
|
||||
str = g_string_new ("");
|
||||
for (i = 0; i < num; i++) {
|
||||
#define ADDR_BUF_LEN 50
|
||||
struct in_addr addr;
|
||||
char *buf;
|
||||
|
||||
if (!str)
|
||||
str = g_string_new ("");
|
||||
|
||||
addr.s_addr = nm_ip4_config_get_nameserver (config, i);
|
||||
buf = g_malloc0 (ADDR_BUF_LEN);
|
||||
if (!buf)
|
||||
continue;
|
||||
|
||||
inet_ntop (AF_INET, &addr, buf, ADDR_BUF_LEN);
|
||||
|
||||
if (i == 3) {
|
||||
g_string_append (str, "# ");
|
||||
g_string_append (str, _("NOTE: the glibc resolver does not support more than 3 nameservers."));
|
||||
g_string_append (str, "\n# ");
|
||||
g_string_append (str, _("The nameservers listed below may not be recognized."));
|
||||
g_string_append_c (str, '\n');
|
||||
}
|
||||
|
||||
g_string_append (str, "nameserver ");
|
||||
g_string_append (str, buf);
|
||||
g_string_append_c (str, '\n');
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
if (!str)
|
||||
return g_strdup ("");
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
compute_searches (NMNamedManager *mgr, NMIP4Config *config)
|
||||
static void
|
||||
merge_one_ip4_config (NMIP4Config *dst, NMIP4Config *src)
|
||||
{
|
||||
int i, num_searches;
|
||||
GString *str = NULL;
|
||||
guint32 num, i;
|
||||
|
||||
g_return_val_if_fail (mgr != NULL, g_strdup (""));
|
||||
num = nm_ip4_config_get_num_nameservers (src);
|
||||
for (i = 0; i < num; i++)
|
||||
nm_ip4_config_add_nameserver (dst, nm_ip4_config_get_nameserver (src, i));
|
||||
|
||||
/* config can be NULL */
|
||||
if (!config)
|
||||
return g_strdup ("");
|
||||
|
||||
num_searches = nm_ip4_config_get_num_domains (config);
|
||||
for (i = 0; i < num_searches; i++)
|
||||
{
|
||||
if (!str)
|
||||
str = g_string_new ("search");
|
||||
|
||||
g_string_append_c (str, ' ');
|
||||
g_string_append (str, nm_ip4_config_get_domain (config, i));
|
||||
}
|
||||
|
||||
if (!str)
|
||||
return g_strdup ("");
|
||||
else
|
||||
g_string_append_c (str, '\n');
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
num = nm_ip4_config_get_num_domains (src);
|
||||
for (i = 0; i < num; i++)
|
||||
nm_ip4_config_add_domain (dst, nm_ip4_config_get_domain (src, i));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error)
|
||||
rewrite_resolv_conf (NMNamedManager *mgr, GError **error)
|
||||
{
|
||||
const char * tmp_resolv_conf = RESOLV_CONF ".tmp";
|
||||
char * searches = NULL;
|
||||
FILE * f;
|
||||
NMIP4Config *ns_config = config;
|
||||
NMNamedManagerPrivate *priv;
|
||||
const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
|
||||
char *searches = NULL;
|
||||
guint32 num_domains, i;
|
||||
NMIP4Config *composite;
|
||||
GSList *iter;
|
||||
FILE *f;
|
||||
|
||||
/* If no config, we don't have anything to update, so exit silently */
|
||||
if (!config)
|
||||
return TRUE;
|
||||
g_return_val_if_fail (error != NULL, FALSE);
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
/* If the sysadmin disabled modifying resolv.conf, exit silently */
|
||||
if (!nm_system_should_modify_resolv_conf ())
|
||||
{
|
||||
if (!nm_system_should_modify_resolv_conf ()) {
|
||||
nm_info ("DHCP returned name servers but system has disabled dynamic modification!");
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -290,85 +285,107 @@ rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the ip4 config is a secondary config and has no nameservers, use the
|
||||
* nameservers from the primary config.
|
||||
*/
|
||||
if ( nm_ip4_config_get_secondary (config)
|
||||
&& !nm_ip4_config_get_num_nameservers (config)) {
|
||||
ns_config = mgr->priv->configs->data;
|
||||
}
|
||||
g_return_val_if_fail (ns_config != NULL, FALSE);
|
||||
/* Construct the composite config from all the currently active IP4Configs */
|
||||
composite = nm_ip4_config_new ();
|
||||
|
||||
searches = compute_searches (mgr, ns_config);
|
||||
if (priv->vpn_config)
|
||||
merge_one_ip4_config (composite, priv->vpn_config);
|
||||
|
||||
if (priv->device_config)
|
||||
merge_one_ip4_config (composite, priv->device_config);
|
||||
|
||||
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
|
||||
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
|
||||
|
||||
if ((config == priv->vpn_config) || (config == priv->device_config))
|
||||
continue;
|
||||
|
||||
merge_one_ip4_config (composite, config);
|
||||
}
|
||||
|
||||
/* Compute resolv.conf search domains */
|
||||
num_domains = nm_ip4_config_get_num_domains (composite);
|
||||
if (num_domains > 0) {
|
||||
GString *str;
|
||||
|
||||
str = g_string_new ("search");
|
||||
for (i = 0; i < num_domains; i++) {
|
||||
g_string_append_c (str, ' ');
|
||||
g_string_append (str, nm_ip4_config_get_domain (composite, i));
|
||||
}
|
||||
|
||||
g_string_append_c (str, '\n');
|
||||
searches = g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
if (mgr->priv->use_named == TRUE) {
|
||||
/* Using caching-nameserver & local DNS */
|
||||
if (fprintf (f,
|
||||
"%s%s%s",
|
||||
"; Use a local caching nameserver controlled by NetworkManager\n\n",
|
||||
searches,
|
||||
searches ? searches : "",
|
||||
"\nnameserver 127.0.0.1\n") < 0) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not write " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
fclose (f);
|
||||
g_free (searches);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Using glibc resolver */
|
||||
char *nameservers = compute_nameservers (mgr, ns_config);
|
||||
char *nameservers = compute_nameservers (composite);
|
||||
|
||||
if ((fprintf (f, "%s\n\n", searches) < 0) ||
|
||||
(fprintf (f, "%s\n\n", nameservers) < 0)) {
|
||||
if ((fprintf (f, "%s\n\n", searches ? searches : "") < 0) ||
|
||||
(fprintf (f, "%s\n\n", nameservers ? nameservers : "") < 0)) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not write to " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
g_free (nameservers);
|
||||
g_free (searches);
|
||||
fclose (f);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (nameservers);
|
||||
}
|
||||
g_free (searches);
|
||||
|
||||
if (fclose (f) < 0) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not close " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
if (*error == NULL) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not close " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not replace " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
g_free (searches);
|
||||
|
||||
if (*error == NULL) {
|
||||
if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
|
||||
g_set_error (error,
|
||||
NM_NAMED_MANAGER_ERROR,
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
"Could not replace " RESOLV_CONF ": %s\n",
|
||||
g_strerror (errno));
|
||||
} else {
|
||||
nm_system_update_dns ();
|
||||
}
|
||||
}
|
||||
nm_system_update_dns ();
|
||||
return TRUE;
|
||||
|
||||
return *error ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_domain_for_config (NMIP4Config *config, gboolean *dflt)
|
||||
get_domain_for_config (NMNamedManager *mgr, NMIP4Config *config, gboolean *dflt)
|
||||
{
|
||||
NMNamedManagerPrivate *priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
gboolean is_dflt = FALSE;
|
||||
const char *domain;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NULL);
|
||||
|
||||
/* Primary configs always use default domain */
|
||||
if (!nm_ip4_config_get_secondary (config))
|
||||
if (config == priv->vpn_config)
|
||||
is_dflt = TRUE;
|
||||
|
||||
/* Any config without a domain becomes default */
|
||||
if (nm_ip4_config_get_num_domains (config) == 0)
|
||||
is_dflt = TRUE;
|
||||
|
@ -387,6 +404,7 @@ get_domain_for_config (NMIP4Config *config, gboolean *dflt)
|
|||
static gboolean
|
||||
add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
|
||||
{
|
||||
NMNamedManagerPrivate *priv;
|
||||
const char *domain;
|
||||
NMIP4Config *ns_config = config;
|
||||
int i, num_nameservers;
|
||||
|
@ -400,15 +418,17 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
|
|||
g_return_val_if_fail (mgr != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
dbus_error_init (&error);
|
||||
|
||||
dbus_connection = nm_dbus_manager_get_dbus_connection (mgr->priv->dbus_mgr);
|
||||
dbus_connection = nm_dbus_manager_get_dbus_connection (priv->dbus_mgr);
|
||||
if (!dbus_connection) {
|
||||
nm_warning ("could not get dbus connection.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(domain = get_domain_for_config (config, &dflt)))
|
||||
if (!(domain = get_domain_for_config (mgr, config, &dflt)))
|
||||
goto out;
|
||||
|
||||
message = dbus_message_new_method_call (NAMED_DBUS_SERVICE,
|
||||
|
@ -427,9 +447,9 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
|
|||
/* If the ip4 config is a secondary config and has no nameservers, use the
|
||||
* nameservers from the primary config.
|
||||
*/
|
||||
if ( nm_ip4_config_get_secondary (config)
|
||||
if ( (config == priv->vpn_config)
|
||||
&& !nm_ip4_config_get_num_nameservers (config)) {
|
||||
ns_config = mgr->priv->configs->data;
|
||||
ns_config = priv->device_config;
|
||||
}
|
||||
g_return_val_if_fail (ns_config != NULL, FALSE);
|
||||
|
||||
|
@ -486,12 +506,27 @@ out:
|
|||
static gboolean
|
||||
add_all_ip4_configs_to_named (NMNamedManager *mgr)
|
||||
{
|
||||
GSList *elt = NULL;
|
||||
NMNamedManagerPrivate *priv;
|
||||
GSList *iter = NULL;
|
||||
|
||||
g_return_val_if_fail (mgr != NULL, FALSE);
|
||||
|
||||
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
|
||||
add_ip4_config_to_named (mgr, (NMIP4Config *)(elt->data));
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
if (priv->vpn_config)
|
||||
add_ip4_config_to_named (mgr, priv->vpn_config);
|
||||
|
||||
if (priv->device_config)
|
||||
add_ip4_config_to_named (mgr, priv->device_config);
|
||||
|
||||
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
|
||||
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
|
||||
|
||||
if ((config == priv->vpn_config) || (config == priv->device_config))
|
||||
continue;
|
||||
|
||||
add_ip4_config_to_named (mgr, config);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -581,7 +616,7 @@ remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config)
|
|||
g_return_val_if_fail (mgr != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
if (!(domain = get_domain_for_config (config, NULL)))
|
||||
if (!(domain = get_domain_for_config (mgr, config, NULL)))
|
||||
return FALSE;
|
||||
|
||||
return remove_one_zone_from_named (mgr, domain);
|
||||
|
@ -675,32 +710,40 @@ out:
|
|||
}
|
||||
|
||||
gboolean
|
||||
nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
|
||||
nm_named_manager_add_ip4_config (NMNamedManager *mgr,
|
||||
NMIP4Config *config,
|
||||
NMNamedIPConfigType cfg_type)
|
||||
{
|
||||
GError * error = NULL;
|
||||
NMNamedManagerPrivate *priv;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (mgr != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
switch (cfg_type) {
|
||||
case NM_NAMED_IP_CONFIG_TYPE_VPN:
|
||||
priv->vpn_config = config;
|
||||
break;
|
||||
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
|
||||
priv->device_config = config;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't allow the same zone added twice */
|
||||
if (g_slist_find (mgr->priv->configs, config))
|
||||
return FALSE;
|
||||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
||||
/* First clear out and reload configs in named */
|
||||
if (mgr->priv->use_named)
|
||||
{
|
||||
if (priv->use_named) {
|
||||
remove_all_zones_from_named (mgr);
|
||||
add_all_ip4_configs_to_named (mgr);
|
||||
}
|
||||
|
||||
mgr->priv->configs = g_slist_append (mgr->priv->configs, g_object_ref (config));
|
||||
|
||||
/* Activate the zone config */
|
||||
if (mgr->priv->use_named)
|
||||
add_ip4_config_to_named (mgr, config);
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, config, &error))
|
||||
{
|
||||
if (!rewrite_resolv_conf (mgr, &error)) {
|
||||
nm_warning ("Could not commit DNS changes. Error: '%s'", error ? error->message : "(none)");
|
||||
g_error_free (error);
|
||||
}
|
||||
|
@ -708,60 +751,45 @@ nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static NMIP4Config *
|
||||
get_last_default_domain (NMNamedManager *mgr)
|
||||
{
|
||||
GSList *elt = NULL;
|
||||
NMIP4Config *last_default = NULL;
|
||||
NMIP4Config *last = NULL;
|
||||
|
||||
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
|
||||
{
|
||||
gboolean dflt = FALSE;
|
||||
const char *domain = NULL;
|
||||
NMIP4Config *config = (NMIP4Config *)(elt->data);
|
||||
|
||||
last = config;
|
||||
domain = get_domain_for_config (config, &dflt);
|
||||
if (dflt)
|
||||
last_default = config;
|
||||
}
|
||||
|
||||
/* Fall back the last config added to the list if none are the default */
|
||||
return (last_default ? last_default : last);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
|
||||
{
|
||||
GError * error = NULL;
|
||||
NMNamedManagerPrivate *priv;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (mgr != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
/* Can't remove it if it wasn't in the list to begin with */
|
||||
if (!g_slist_find (mgr->priv->configs, config))
|
||||
if (!g_slist_find (priv->configs, config))
|
||||
return FALSE;
|
||||
|
||||
/* Deactivate the config */
|
||||
if (mgr->priv->use_named)
|
||||
if (priv->use_named)
|
||||
remove_ip4_config_from_named (mgr, config);
|
||||
|
||||
mgr->priv->configs = g_slist_remove (mgr->priv->configs, config);
|
||||
priv->configs = g_slist_remove (priv->configs, config);
|
||||
|
||||
if (config == priv->vpn_config)
|
||||
priv->vpn_config = NULL;
|
||||
|
||||
if (config == priv->device_config)
|
||||
priv->device_config = NULL;
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
/* Clear out and reload configs since we may need a new
|
||||
* default zone if the one we are removing was the old
|
||||
* default zone.
|
||||
*/
|
||||
if (mgr->priv->use_named)
|
||||
{
|
||||
if (mgr->priv->use_named) {
|
||||
remove_all_zones_from_named (mgr);
|
||||
add_all_ip4_configs_to_named (mgr);
|
||||
}
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error))
|
||||
{
|
||||
if (!rewrite_resolv_conf (mgr, &error)) {
|
||||
nm_warning ("Could not commit DNS changes. Error: '%s'", error ? error->message : "(none)");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
|
|
|
@ -28,14 +28,19 @@
|
|||
#include <dbus/dbus.h>
|
||||
#include "nm-ip4-config.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
NM_NAMED_MANAGER_ERROR_SYSTEM,
|
||||
NM_NAMED_MANAGER_ERROR_INVALID_NAMESERVER,
|
||||
NM_NAMED_MANAGER_ERROR_INVALID_HOST,
|
||||
NM_NAMED_MANAGER_ERROR_INVALID_ID
|
||||
} NMNamedManagerError;
|
||||
|
||||
typedef enum {
|
||||
NM_NAMED_IP_CONFIG_TYPE_DEFAULT = 0,
|
||||
NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE,
|
||||
NM_NAMED_IP_CONFIG_TYPE_VPN
|
||||
} NMNamedIPConfigType;
|
||||
|
||||
#define NM_NAMED_MANAGER_ERROR nm_named_manager_error_quark ()
|
||||
GQuark nm_named_manager_error_quark (void);
|
||||
|
||||
|
@ -64,7 +69,9 @@ GType nm_named_manager_get_type (void);
|
|||
|
||||
NMNamedManager * nm_named_manager_get (void);
|
||||
|
||||
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config);
|
||||
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr,
|
||||
NMIP4Config *config,
|
||||
NMNamedIPConfigType cfg_type);
|
||||
|
||||
gboolean nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config);
|
||||
|
||||
|
|
|
@ -856,10 +856,19 @@ real_check_connection_conflicts (NMDevice *device,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_can_activate (NMDevice *dev, gboolean wireless_enabled)
|
||||
{
|
||||
if (!wireless_enabled)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
real_get_best_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
real_get_best_auto_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
{
|
||||
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev);
|
||||
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
|
||||
|
@ -2756,31 +2765,40 @@ static NMActStageReturn
|
|||
real_act_stage4_get_ip4_config (NMDevice *dev,
|
||||
NMIP4Config **config)
|
||||
{
|
||||
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
|
||||
NMAccessPoint * ap = nm_device_802_11_wireless_get_activation_ap (self);
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMIP4Config * real_config = NULL;
|
||||
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev);
|
||||
NMAccessPoint *ap = nm_device_802_11_wireless_get_activation_ap (self);
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
g_assert (ap);
|
||||
if (nm_ap_get_user_created (ap))
|
||||
{
|
||||
real_config = nm_device_new_ip4_autoip_config (NM_DEVICE (self));
|
||||
if (nm_ap_get_user_created (ap)) {
|
||||
*config = nm_device_new_ip4_autoip_config (NM_DEVICE (self));
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
NMDevice80211WirelessClass * klass;
|
||||
NMDeviceClass * parent_class;
|
||||
|
||||
/* Chain up to parent */
|
||||
klass = NM_DEVICE_802_11_WIRELESS_GET_CLASS (self);
|
||||
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
|
||||
ret = parent_class->act_stage4_get_ip4_config (dev, &real_config);
|
||||
ret = parent_class->act_stage4_get_ip4_config (dev, config);
|
||||
}
|
||||
|
||||
if ((ret == NM_ACT_STAGE_RETURN_SUCCESS) && *config) {
|
||||
NMConnection *connection;
|
||||
NMSettingWireless *s_wireless;
|
||||
|
||||
connection = nm_act_request_get_connection (nm_device_get_act_request (dev));
|
||||
g_assert (connection);
|
||||
s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
|
||||
g_assert (s_wireless);
|
||||
|
||||
/* MTU override */
|
||||
if (s_wireless->mtu)
|
||||
nm_ip4_config_set_mtu (*config, s_wireless->mtu);
|
||||
}
|
||||
*config = real_config;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3065,7 +3083,8 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
|
|||
parent_class->bring_down = real_bring_down;
|
||||
parent_class->update_link = real_update_link;
|
||||
parent_class->set_hw_address = real_set_hw_address;
|
||||
parent_class->get_best_connection = real_get_best_connection;
|
||||
parent_class->get_best_auto_connection = real_get_best_auto_connection;
|
||||
parent_class->can_activate = real_can_activate;
|
||||
parent_class->connection_secrets_updated = real_connection_secrets_updated;
|
||||
parent_class->check_connection_conflicts = real_check_connection_conflicts;
|
||||
|
||||
|
|
|
@ -349,10 +349,20 @@ real_can_interrupt_activation (NMDevice *dev)
|
|||
return interrupt;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_can_activate (NMDevice *dev, gboolean wireless_enabled)
|
||||
{
|
||||
/* Can't do anything if there isn't a carrier */
|
||||
if (!nm_device_get_carrier (dev))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
real_get_best_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
real_get_best_auto_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
{
|
||||
NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev);
|
||||
NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self);
|
||||
|
@ -385,6 +395,40 @@ real_get_best_connection (NMDevice *dev,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
real_act_stage4_get_ip4_config (NMDevice *dev,
|
||||
NMIP4Config **config)
|
||||
{
|
||||
NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev);
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMDevice8023EthernetClass *klass;
|
||||
NMDeviceClass *parent_class;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
/* Chain up to parent */
|
||||
klass = NM_DEVICE_802_3_ETHERNET_GET_CLASS (self);
|
||||
parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass));
|
||||
ret = parent_class->act_stage4_get_ip4_config (dev, config);
|
||||
|
||||
if ((ret == NM_ACT_STAGE_RETURN_SUCCESS) && *config) {
|
||||
NMConnection *connection;
|
||||
NMSettingWired *s_wired;
|
||||
|
||||
connection = nm_act_request_get_connection (nm_device_get_act_request (dev));
|
||||
g_assert (connection);
|
||||
s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
|
||||
g_assert (s_wired);
|
||||
|
||||
/* MTU override */
|
||||
if (s_wired->mtu)
|
||||
nm_ip4_config_set_mtu (*config, s_wired->mtu);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_802_3_ethernet_dispose (GObject *object)
|
||||
{
|
||||
|
@ -468,7 +512,9 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass)
|
|||
parent_class->update_link = real_update_link;
|
||||
parent_class->can_interrupt_activation = real_can_interrupt_activation;
|
||||
parent_class->set_hw_address = real_set_hw_address;
|
||||
parent_class->get_best_connection = real_get_best_connection;
|
||||
parent_class->get_best_auto_connection = real_get_best_auto_connection;
|
||||
parent_class->can_activate = real_can_activate;
|
||||
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
|
||||
|
||||
/* properties */
|
||||
g_object_class_install_property
|
||||
|
|
|
@ -248,7 +248,7 @@ nm_device_get_iface (NMDevice *self)
|
|||
}
|
||||
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
nm_device_get_ip_iface (NMDevice *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
|
@ -373,10 +373,19 @@ nm_device_set_carrier (NMDevice *self,
|
|||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nm_device_can_activate (NMDevice *self, gboolean wireless_enabled)
|
||||
{
|
||||
if (!NM_DEVICE_GET_CLASS (self)->can_activate)
|
||||
return TRUE;
|
||||
|
||||
return NM_DEVICE_GET_CLASS (self)->can_activate (self, wireless_enabled);
|
||||
}
|
||||
|
||||
NMConnection *
|
||||
nm_device_get_best_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
nm_device_get_best_auto_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object)
|
||||
{
|
||||
guint32 caps;
|
||||
|
||||
|
@ -389,10 +398,10 @@ nm_device_get_best_connection (NMDevice *dev,
|
|||
if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED))
|
||||
return NULL;
|
||||
|
||||
if (!NM_DEVICE_GET_CLASS (dev)->get_best_connection)
|
||||
if (!NM_DEVICE_GET_CLASS (dev)->get_best_auto_connection)
|
||||
return NULL;
|
||||
|
||||
return NM_DEVICE_GET_CLASS (dev)->get_best_connection (dev, connections, specific_object);
|
||||
return NM_DEVICE_GET_CLASS (dev)->get_best_auto_connection (dev, connections, specific_object);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -709,34 +718,25 @@ static NMActStageReturn
|
|||
real_act_stage4_get_ip4_config (NMDevice *self,
|
||||
NMIP4Config **config)
|
||||
{
|
||||
NMIP4Config * real_config = NULL;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
if (nm_device_get_use_dhcp (self)) {
|
||||
real_config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
|
||||
connection = nm_act_request_get_connection (nm_device_get_act_request (self));
|
||||
|
||||
if (nm_device_get_use_dhcp (self))
|
||||
*config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
|
||||
nm_device_get_iface (self));
|
||||
else
|
||||
*config = nm_ip4_config_new ();
|
||||
|
||||
if (real_config && nm_ip4_config_get_mtu (real_config) == 0) {
|
||||
/* If the DHCP server doesn't set the MTU, get it from backend. */
|
||||
// FIXME: let the NMConnection override the MTU
|
||||
nm_ip4_config_set_mtu (real_config, nm_system_get_mtu (self));
|
||||
}
|
||||
} else {
|
||||
real_config = nm_ip4_config_new ();
|
||||
}
|
||||
if (*config) {
|
||||
NMSettingIP4Config *s_ip4;
|
||||
|
||||
if (real_config) {
|
||||
NMActRequest *req;
|
||||
|
||||
req = nm_device_get_act_request (self);
|
||||
merge_ip4_config (real_config,
|
||||
(NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req),
|
||||
NM_TYPE_SETTING_IP4_CONFIG));
|
||||
|
||||
*config = real_config;
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
|
||||
merge_ip4_config (*config, s_ip4);
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
} else {
|
||||
/* Make sure device is up even if config fails */
|
||||
|
@ -1397,7 +1397,6 @@ nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config)
|
|||
nm_device_update_ip4_address (self);
|
||||
nm_system_device_add_ip6_link_address (self);
|
||||
nm_system_set_hostname (config);
|
||||
nm_system_set_mtu (self);
|
||||
nm_system_activate_nis (config);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,9 +90,11 @@ struct _NMDeviceClass
|
|||
guint32 (* get_type_capabilities) (NMDevice *self);
|
||||
guint32 (* get_generic_capabilities) (NMDevice *self);
|
||||
|
||||
NMConnection * (* get_best_connection) (NMDevice *self,
|
||||
GSList *connections,
|
||||
char **specific_object);
|
||||
gboolean (* can_activate) (NMDevice *self, gboolean wireless_enabled);
|
||||
|
||||
NMConnection * (* get_best_auto_connection) (NMDevice *self,
|
||||
GSList *connections,
|
||||
char **specific_object);
|
||||
|
||||
void (* connection_secrets_updated) (NMDevice *self,
|
||||
NMConnection *connection,
|
||||
|
@ -122,6 +124,7 @@ GType nm_device_get_type (void);
|
|||
|
||||
const char * nm_device_get_udi (NMDevice *dev);
|
||||
const char * nm_device_get_iface (NMDevice *dev);
|
||||
const char * nm_device_get_ip_iface (NMDevice *dev);
|
||||
const char * nm_device_get_driver (NMDevice *dev);
|
||||
|
||||
NMDeviceType nm_device_get_device_type (NMDevice *dev);
|
||||
|
@ -152,9 +155,11 @@ void * nm_device_get_system_config_data (NMDevice *dev);
|
|||
|
||||
NMActRequest * nm_device_get_act_request (NMDevice *dev);
|
||||
|
||||
NMConnection * nm_device_get_best_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object);
|
||||
gboolean nm_device_can_activate (NMDevice *dev, gboolean wireless_enabled);
|
||||
|
||||
NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
|
||||
GSList *connections,
|
||||
char **specific_object);
|
||||
|
||||
void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device);
|
||||
void nm_device_activate_schedule_stage2_device_config (NMDevice *device);
|
||||
|
|
|
@ -56,12 +56,6 @@ typedef struct {
|
|||
gchar * nis_domain;
|
||||
GArray *nis_servers;
|
||||
GArray *static_routes;
|
||||
|
||||
/* If this is a VPN/etc config that requires
|
||||
* another device (like Ethernet) to already have
|
||||
* an IP4Config before it can be used.
|
||||
*/
|
||||
gboolean secondary;
|
||||
} NMIP4ConfigPrivate;
|
||||
|
||||
|
||||
|
@ -144,20 +138,6 @@ NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config)
|
|||
return dst_config;
|
||||
}
|
||||
|
||||
gboolean nm_ip4_config_get_secondary (NMIP4Config *config)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), FALSE);
|
||||
|
||||
return NM_IP4_CONFIG_GET_PRIVATE (config)->secondary;
|
||||
}
|
||||
|
||||
void nm_ip4_config_set_secondary (NMIP4Config *config, gboolean secondary)
|
||||
{
|
||||
g_return_if_fail (NM_IS_IP4_CONFIG (config));
|
||||
|
||||
NM_IP4_CONFIG_GET_PRIVATE (config)->secondary = secondary;
|
||||
}
|
||||
|
||||
guint32 nm_ip4_config_get_address (NMIP4Config *config)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
|
||||
|
|
|
@ -59,9 +59,6 @@ GType nm_ip4_config_get_type (void);
|
|||
NMIP4Config * nm_ip4_config_new (void);
|
||||
NMIP4Config * nm_ip4_config_copy (NMIP4Config *config);
|
||||
|
||||
gboolean nm_ip4_config_get_secondary (NMIP4Config *config);
|
||||
void nm_ip4_config_set_secondary (NMIP4Config *config, gboolean secondary);
|
||||
|
||||
guint32 nm_ip4_config_get_address (NMIP4Config *config);
|
||||
void nm_ip4_config_set_address (NMIP4Config *config, guint32 addr);
|
||||
|
||||
|
|
|
@ -1262,6 +1262,9 @@ nm_manager_activate_device (NMManager *manager,
|
|||
if (!check_connection_allowed (manager, dev_iface, connection, specific_object, error))
|
||||
return FALSE;
|
||||
|
||||
if (nm_device_get_act_request (device))
|
||||
nm_device_interface_deactivate (dev_iface);
|
||||
|
||||
req = nm_act_request_new (connection, specific_object, user_requested);
|
||||
success = nm_device_interface_activate (dev_iface, req, error);
|
||||
g_object_unref (req);
|
||||
|
@ -1307,39 +1310,6 @@ wait_for_connection_expired (gpointer data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* ICK ICK ICK; should go away with multiple device support. There is
|
||||
* corresponding code in NetworkManagerPolicy.c that handles this for
|
||||
* automatically activated connections.
|
||||
*/
|
||||
static void
|
||||
deactivate_old_device (NMManager *manager)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
NMDevice *device = NULL;
|
||||
GSList *iter;
|
||||
|
||||
switch (priv->state) {
|
||||
case NM_STATE_CONNECTED:
|
||||
device = nm_manager_get_active_device (manager);
|
||||
break;
|
||||
case NM_STATE_CONNECTING:
|
||||
for (iter = nm_manager_get_devices (manager); iter; iter = iter->next) {
|
||||
NMDevice *d = NM_DEVICE (iter->data);
|
||||
|
||||
if (nm_device_is_activating (d)) {
|
||||
device = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (device)
|
||||
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device));
|
||||
}
|
||||
|
||||
static void
|
||||
connection_added_default_handler (NMManager *manager,
|
||||
NMConnection *connection,
|
||||
|
@ -1362,9 +1332,6 @@ connection_added_default_handler (NMManager *manager,
|
|||
/* Will destroy below; can't be valid during the initial activation start */
|
||||
priv->pending_connection_info = NULL;
|
||||
|
||||
// FIXME: remove old_dev deactivation when multiple device support lands
|
||||
deactivate_old_device (manager);
|
||||
|
||||
success = nm_manager_activate_device (manager,
|
||||
info->device,
|
||||
connection,
|
||||
|
@ -1428,9 +1395,6 @@ impl_manager_activate_device (NMManager *manager,
|
|||
if (connection) {
|
||||
gboolean success;
|
||||
|
||||
// FIXME: remove old_dev deactivation when multiple device support lands
|
||||
deactivate_old_device (manager);
|
||||
|
||||
success = nm_manager_activate_device (manager,
|
||||
device,
|
||||
connection,
|
||||
|
|
|
@ -243,7 +243,6 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
|
|||
priv->ipconfig_timeout = 0;
|
||||
|
||||
config = nm_ip4_config_new ();
|
||||
nm_ip4_config_set_secondary (config, TRUE);
|
||||
|
||||
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY);
|
||||
if (val)
|
||||
|
|
Loading…
Reference in a new issue