diff --git a/ChangeLog b/ChangeLog index d13d84678d..0a5ee139ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,115 @@ +2008-04-07 Dan Williams + + * include/NetworkManager.h + - Remove the DOWN and CANCELLED device states + - Add UNMANAGED and UNAVAILABLE device states + - Document the device states + + * introspection/nm-device.xml + src/nm-device-interface.c + src/nm-device-interface.h + - Add the 'managed' property + + * test/nm-tool.c + - (detail_device): print out device state + + * src/NetworkManagerSystem.h + src/backends/NetworkManagerArch.c + src/backends/NetworkManagerDebian.c + src/backends/NetworkManagerFrugalware.c + src/backends/NetworkManagerGentoo.c + src/backends/NetworkManagerMandriva.c + src/backends/NetworkManagerPaldo.c + src/backends/NetworkManagerRedHat.c + src/backends/NetworkManagerSlackware.c + src/backends/NetworkManagerSuSE.c + - (nm_system_device_get_system_config, nm_system_device_get_disabled + nm_system_device_free_system_config): remove; they were unused and + their functionality should be re-implemented in each distro's + system settings service plugin + + * src/nm-gsm-device.c + src/nm-gsm-device.h + src/nm-cdma-device.c + src/nm-cdma-device.h + - (*_new): take the 'managed' argument + + * src/nm-device.c + - (nm_device_set_address): remove, fold into nm_device_bring_up() + - (nm_device_init): start in unmanaged state, not disconnected + - (constructor): don't start device until the system settings service + has had a chance to figure out if the device is managed or not + - (nm_device_deactivate, nm_device_bring_up, nm_device_bring_down): + don't set device state here, let callers handle that as appropriate + - (nm_device_dispose): don't touch the device if it's not managed + - (set_property, get_property, nm_device_class_init): implement the + 'managed' property + - (nm_device_state_changed): bring the device up if its now managed, + and deactivate it if it used to be active + - (nm_device_get_managed, nm_device_set_managed): do the right thing + with the managed state + + * src/nm-hal-manager.c + - (wired_device_creator, wireless_device_creator, modem_device_creator): + take initial managed state and pass it along to device constructors + - (create_device_and_add_to_list): get managed state and pass to + type creators + + * src/nm-device-802-11-wireless.c + - (real_can_activate): fold in most of + nm_device_802_11_wireless_can_activate() + - (can_scan): can't scan in UNAVAILABLE or UNMANAGED + - (link_timeout_cb): instead of deactivating, change device state and + let the device state handler to it + - (real_update_hw_address): clean up + - (state_changed_cb): when entering UNAVAILABLE state, schedule an idle + handler to transition to DISCONNECTED if the device isn't rfkilled + + * src/nm-device-802-3-ethernet.c + - (set_carrier): move above callers and get rid of prototype + - (device_state_changed): when entering UNAVAILABLE state, schedule an + idle handler to transition to DISCONNECTED if the device has a + carrier + - (real_update_hw_address): clean up + - (link_timeout_cb, ppp_state_changed): change state instead of calling + deactivation directly as deactivation doesn't change state anymore + + * src/NetworkManagerPolicy.c + - (schedule_activate_check): yay, remove wireless_enabled hack since + the NMManager and wireless devices work that out themselves now + - (device_state_changed): change to a switch and update for new device + states + - (device_carrier_changed): remove; device handles this now through + state changes + - (device_added): don't care about carrier any more; the initial + activation check will happen when the device transitions to + DISCONNECTED + + * src/nm-manager.c + - (dispose): clear unmanaged devices + - (handle_unmanaged_devices): update unmanaged device list and toggle + the managed property on each device when needed + - (system_settings_properties_changed_cb): handle signals from the + system settings service + - (system_settings_get_unmanaged_devices_cb): handle callback from + getting the unmanaged device list method call + - (query_unmanaged_devices): ask the system settings service for its + list of unmanaged devices + - (nm_manager_name_owner_changed, initial_get_connections): get unmanaged + devices + - (manager_set_wireless_enabled): push rfkill state down to wireless + devices directly and let them handle the necessary state transitions + - (manager_device_state_changed): update for new device states + - (nm_manager_add_device): set initial rfkill state on wireless devices + - (nm_manager_remove_device): don't touch the device if it's unmanaged + - (nm_manager_activate_connection): return error if the device is + unmanaged + - (nm_manager_sleep): handle new device states correctly; don't change + the state of unavailable/unmanaged devices + + * libnm-glib/nm-device-802-11-wireless.c + - (state_changed_cb): update for new device states + 2008-04-07 Dan Williams * marshallers/nm-marshal.list diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 888bfd9c87..15bdfffd3e 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -128,15 +128,68 @@ typedef enum NMDeviceType typedef enum { NM_DEVICE_STATE_UNKNOWN = 0, - NM_DEVICE_STATE_DOWN, + + /* Initial state of all devices and the only state for devices not + * managed by NetworkManager. + * + * Allowed next states: + * UNAVAILABLE: the device is now managed by NetworkManager + */ + NM_DEVICE_STATE_UNMANAGED, + + /* Indicates the device is not yet ready for use, but is managed by + * NetworkManager. For Ethernet devices, the device may not have an + * active carrier. For WiFi devices, the device may not have it's radio + * enabled. + * + * Allowed next states: + * UNMANAGED: the device is no longer managed by NetworkManager + * DISCONNECTED: the device is now ready for use + */ + NM_DEVICE_STATE_UNAVAILABLE, + + /* Indicates the device does not have an activate connection to anything. + * + * Allowed next states: + * UNMANAGED: the device is no longer managed by NetworkManager + * UNAVAILABLE: the device is no longer ready for use (rfkill, no carrier, etc) + * PREPARE: the device has started activation + */ NM_DEVICE_STATE_DISCONNECTED, + + /* Indicate states in device activation. + * + * Allowed next states: + * UNMANAGED: the device is no longer managed by NetworkManager + * UNAVAILABLE: the device is no longer ready for use (rfkill, no carrier, etc) + * FAILED: an error ocurred during activation + * NEED_AUTH: authentication/secrets are needed + * ACTIVATED: (IP_CONFIG only) activation was successful + * DISCONNECTED: the device's connection is no longer valid, or NetworkManager went to sleep + */ NM_DEVICE_STATE_PREPARE, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_IP_CONFIG, + + /* Indicates the device is part of an active network connection. + * + * Allowed next states: + * UNMANAGED: the device is no longer managed by NetworkManager + * UNAVAILABLE: the device is no longer ready for use (rfkill, no carrier, etc) + * FAILED: a DHCP lease was not renewed, or another error + * DISCONNECTED: the device's connection is no longer valid, or NetworkManager went to sleep + */ NM_DEVICE_STATE_ACTIVATED, + + /* Indicates the device's activation failed. + * + * Allowed next states: + * UNMANAGED: the device is no longer managed by NetworkManager + * UNAVAILABLE: the device is no longer ready for use (rfkill, no carrier, etc) + * DISCONNECTED: the device's connection is ready for activation, or NetworkManager went to sleep + */ NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_CANCELLED, } NMDeviceState; diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 0f4f50d925..848942abb8 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -37,6 +37,11 @@ Object path of the Ip4Config object describing the configuration of the device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state. + + + Whether or not this device is managed by NetworkManager. + + diff --git a/libnm-glib/nm-device-802-11-wireless.c b/libnm-glib/nm-device-802-11-wireless.c index b5f3e13c16..6032a793c4 100644 --- a/libnm-glib/nm-device-802-11-wireless.c +++ b/libnm-glib/nm-device-802-11-wireless.c @@ -382,18 +382,11 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); switch (nm_device_get_state (device)) { - case NM_DEVICE_STATE_PREPARE: - case NM_DEVICE_STATE_CONFIG: - case NM_DEVICE_STATE_NEED_AUTH: - case NM_DEVICE_STATE_IP_CONFIG: - case NM_DEVICE_STATE_ACTIVATED: - break; case NM_DEVICE_STATE_UNKNOWN: - case NM_DEVICE_STATE_DOWN: + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_FAILED: - case NM_DEVICE_STATE_CANCELLED: - default: /* Just clear active AP; don't clear the AP list unless wireless is disabled completely */ if (priv->active_ap) { g_object_unref (priv->active_ap); @@ -404,6 +397,8 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) priv->rate = 0; nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_802_11_WIRELESS_BITRATE); break; + default: + break; } } diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 22d3f3d2f6..458eab71ab 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -260,15 +260,16 @@ schedule_activate_check (NMPolicy *policy, NMDevice *device) { ActivateData *data; GSList *iter; - gboolean wireless_enabled; + NMDeviceState state; if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP) return; - // 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)) + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); + if (state < NM_DEVICE_STATE_DISCONNECTED) + return; + + if (!nm_device_can_activate (device)) return; for (iter = policy->pending_activation_checks; iter; iter = g_slist_next (iter)) { @@ -304,43 +305,31 @@ device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) NMPolicy *policy = (NMPolicy *) user_data; NMConnection *connection = get_device_connection (device); - if ((state == NM_DEVICE_STATE_FAILED) || (state == NM_DEVICE_STATE_CANCELLED)) { + switch (state) { + case NM_DEVICE_STATE_FAILED: /* 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) { + schedule_activate_check (policy, device); + break; + case 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, FALSE); - } else if (state == NM_DEVICE_STATE_DISCONNECTED) { + break; + case NM_DEVICE_STATE_DISCONNECTED: update_routing_and_dns (policy, FALSE); - schedule_activate_check (policy, device); + break; + default: + break; } } -static void -device_carrier_changed (NMDevice8023Ethernet *device, - GParamSpec *pspec, - gpointer user_data) -{ - const char *prop = g_param_spec_get_name (pspec); - - g_return_if_fail (strcmp (prop, NM_DEVICE_802_3_ETHERNET_CARRIER) == 0); - - if (!nm_device_802_3_ethernet_get_carrier (device)) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); - else - schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device)); -} - static void device_ip4_config_changed (NMDevice *device, GParamSpec *pspec, @@ -401,15 +390,6 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) policy); policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); } - - if (NM_IS_DEVICE_802_3_ETHERNET (device)) { - id = g_signal_connect (device, "notify::" NM_DEVICE_802_3_ETHERNET_CARRIER, - G_CALLBACK (device_carrier_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); - } - - schedule_activate_check (policy, device); } static void diff --git a/src/NetworkManagerSystem.h b/src/NetworkManagerSystem.h index 54ebf281cb..e471840163 100644 --- a/src/NetworkManagerSystem.h +++ b/src/NetworkManagerSystem.h @@ -55,11 +55,6 @@ void nm_system_update_dns (void); void nm_system_restart_mdns_responder (void); void nm_system_device_add_ip6_link_address (NMDevice *dev); -void * nm_system_device_get_system_config (NMDevice *dev); -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data); - -gboolean nm_system_device_get_disabled (NMDevice *dev); - gboolean nm_system_device_set_from_ip4_config (const char *iface, NMIP4Config *config, gboolean route_to_iface); diff --git a/src/backends/NetworkManagerArch.c b/src/backends/NetworkManagerArch.c index f61bf104e4..4c94e9fe8f 100644 --- a/src/backends/NetworkManagerArch.c +++ b/src/backends/NetworkManagerArch.c @@ -491,143 +491,6 @@ static GHashTable * ArchReadConfig(const char* file, const char* dev) return ifs; } - -typedef struct ArchSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; -} ArchSystemConfigData; - - - -/* - * nm_system_device_get_system_config - * - * Retrieve any relevant configuration info for a particular device - * from the system network configuration information. Clear out existing - * info before setting stuff too. - * - */ -void* nm_system_device_get_system_config (NMDevice * dev) -{ - - GHashTable* ifh; - gpointer val; - ArchSystemConfigData* sys_data=NULL; - - g_return_val_if_fail (dev != NULL, NULL); - - sys_data = g_malloc0 (sizeof (ArchSystemConfigData)); - sys_data->use_dhcp = TRUE; - sys_data->config=NULL; - - ifh=ArchReadConfig("/etc/rc.conf",nm_device_get_iface(dev)); - if (ifh==NULL) - { - g_free(sys_data); - return NULL; - } - val=g_hash_table_lookup(ifh,nm_device_get_iface(dev)); - if (val && !g_hash_table_lookup(ifh, "dhcp")) - { - /* This device does not use DHCP */ - - sys_data->use_dhcp=FALSE; - sys_data->config = nm_ip4_config_new(); - - nm_ip4_config_set_address (sys_data->config, inet_addr (val)); - - val = g_hash_table_lookup(ifh, "gateway"); - if (val) - nm_ip4_config_set_gateway (sys_data->config, inet_addr (val)); - - val = g_hash_table_lookup(ifh, "netmask"); - if (val) - nm_ip4_config_set_netmask (sys_data->config, inet_addr (val)); - else - { - guint32 addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - val = g_hash_table_lookup(ifh, "broadcast"); - if (val) - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (val)); - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - - nm_generic_set_ip4_config_from_resolv_conf (SYSCONFDIR"/resolv.conf", sys_data->config); -#if 0 - { - int j; - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug (" ADDR=%d", nm_ip4_config_get_address (sys_data->config)); - nm_debug (" GW =%d", nm_ip4_config_get_gateway (sys_data->config)); - nm_debug (" NM =%d", nm_ip4_config_get_netmask (sys_data->config)); - nm_debug (" NSs =%d",nm_ip4_config_get_num_nameservers(sys_data->config)); - for (j=0;jconfig);j++) - { - nm_debug (" NS =%d",nm_ip4_config_get_nameserver(sys_data->config,j)); - } - nm_debug ("---------------------\n"); - } -#endif - - } - - g_hash_table_destroy(ifh); - - - return (void *)sys_data; -} - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - ArchSystemConfigData *sys_data = (ArchSystemConfigData*) system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - { - return; - } - - if (sys_data->config) - g_object_unref (sys_data->config); - - -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - return FALSE; -} - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerDebian.c b/src/backends/NetworkManagerDebian.c index 780f6dfd48..5f61ffabc0 100644 --- a/src/backends/NetworkManagerDebian.c +++ b/src/backends/NetworkManagerDebian.c @@ -214,139 +214,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } -typedef struct DebSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; -} DebSystemConfigData; - -/* - * nm_system_device_get_system_config - * - * Retrieve any relevant configuration info for a particular device - * from the system network configuration information. Clear out existing - * info before setting stuff too. - * - */ -void* nm_system_device_get_system_config (NMDevice *dev) -{ - DebSystemConfigData * sys_data = NULL; - if_block *curr_device; - const char *buf; - gboolean error = FALSE; - - g_return_val_if_fail (dev != NULL, NULL); - - sys_data = g_malloc0 (sizeof (DebSystemConfigData)); - sys_data->use_dhcp = TRUE; - - ifparser_init(); - - /* Make sure this config file is for this device */ - curr_device = ifparser_getif(nm_device_get_iface (dev)); - if (curr_device == NULL) - goto out; - - buf = ifparser_getkey(curr_device, "inet"); - if (buf) - { - if (strcmp (buf, "dhcp")!=0) - sys_data->use_dhcp = FALSE; - } - - sys_data->config = nm_ip4_config_new (); - - buf = ifparser_getkey (curr_device, "address"); - if (buf) - nm_ip4_config_set_address (sys_data->config, inet_addr (buf)); - - buf = ifparser_getkey (curr_device, "gateway"); - if (buf) - nm_ip4_config_set_gateway (sys_data->config, inet_addr (buf)); - - buf = ifparser_getkey (curr_device, "netmask"); - if (buf) - nm_ip4_config_set_netmask (sys_data->config, inet_addr (buf)); - else - { - guint32 addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - buf = ifparser_getkey (curr_device, "broadcast"); - if (buf) - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (buf)); - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - - if (!sys_data->use_dhcp) - nm_generic_set_ip4_config_from_resolv_conf (SYSCONFDIR"/resolv.conf", sys_data->config); - -#if 0 - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug (" DHCP=%s\n", sys_data->use_dhcp); - nm_debug (" ADDR=%d\n", nm_ip4_config_get_address (sys_data->config)); - nm_debug (" GW=%d\n", nm_ip4_config_get_gateway (sys_data->config)); - nm_debug (" NM=%d\n", nm_ip4_config_get_netmask (sys_data->config)); - nm_debug ("---------------------\n"); -#endif - -out: - ifparser_destroy(); - if (error) - { - sys_data->use_dhcp = TRUE; - /* Clear out the config */ - g_object_unref (sys_data->config); - sys_data->config = NULL; - } - - return (void *)sys_data; -} - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - DebSystemConfigData *sys_data = (DebSystemConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - return; - - if (sys_data->config) - g_object_unref (sys_data->config); -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - return FALSE; -} - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerFrugalware.c b/src/backends/NetworkManagerFrugalware.c index d7c97ac09b..95847ceb3b 100644 --- a/src/backends/NetworkManagerFrugalware.c +++ b/src/backends/NetworkManagerFrugalware.c @@ -40,12 +40,6 @@ // Provided by the frugalwareutils package on Frugalware #include -typedef struct FWDeviceConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; -} FWDeviceConfigData; - /* * nm_system_init * @@ -274,37 +268,6 @@ void nm_system_flush_arp_cache (void) nm_spawn_process ("/usr/sbin/ip neigh flush all"); } -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ -} - -/* - * get_current_profile_name - * - * Retrieve the current network profile, if any - * - */ -static char *get_current_profile_name (void) -{ - char * buf; - - buf = fwnet_lastprofile(); - return buf; -} - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - return FALSE; -} - - /* * nm_system_activate_nis * @@ -345,127 +308,3 @@ gboolean nm_system_should_modify_resolv_conf (void) return TRUE; } - -/* - * nm_system_device_get_system_config - * - * Read in the config file for a device. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - fwnet_profile_t *profile; - fwnet_interface_t *interface; - FWDeviceConfigData *sys_data = NULL; - int dhcp, i; - char *data = NULL; - gboolean error = FALSE; - char ip[15]; - char netmask[15]; - char mybroadcast[15]; - int ret; - - sys_data = g_malloc0 (sizeof (FWDeviceConfigData)); - sys_data->use_dhcp = TRUE; - - profile = fwnet_parseprofile(get_current_profile_name()); - - for (i=0; iinterfaces); i++) - { - interface = g_list_nth_data(profile->interfaces, i); - if(!strcmp(interface->name, nm_device_get_iface (dev))) - break; - interface = NULL; - } - - if (!interface) - return NULL; - - dhcp = fwnet_is_dhcp(interface); - - if (!dhcp) - sys_data->use_dhcp = FALSE; - else - goto out; - - sys_data->config = nm_ip4_config_new (); - - if (!(sys_data->use_dhcp)) - { - data = g_list_nth_data(interface->options, 0); - - ret = sscanf(data, "%s netmask %s broadcast %s", ip, netmask, mybroadcast); - - if (ret >= 1) - { - nm_ip4_config_set_address (sys_data->config, inet_addr (ip)); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but could not split options. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - - if (ret >= 2) - { - nm_ip4_config_set_netmask (sys_data->config, inet_addr (netmask)); - } - else - { - guint32 addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - if (ret >= 3) - { - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (mybroadcast)); - } - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - - if (interface->gateway != NULL) - { - nm_ip4_config_set_gateway (sys_data->config, inet_addr (interface->gateway)); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but no gateway specified. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - } - -#if 0 - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug (" DHCP=%d\n", sys_data->use_dhcp); - nm_debug (" ADDR=%d\n", nm_ip4_config_get_address (sys_data->config)); - nm_debug (" GW=%d\n", nm_ip4_config_get_gateway (sys_data->config)); - nm_debug (" NM=%d\n", nm_ip4_config_get_netmask (sys_data->config)); - nm_debug ("---------------------\n"); -#endif - -out: - if (error) - { - sys_data->use_dhcp = TRUE; - /* Clear out the config */ - g_object_unref (sys_data->config); - sys_data->config = NULL; - } - - return (void *)sys_data; -} diff --git a/src/backends/NetworkManagerGentoo.c b/src/backends/NetworkManagerGentoo.c index 1afa59f169..b72cc16a6e 100644 --- a/src/backends/NetworkManagerGentoo.c +++ b/src/backends/NetworkManagerGentoo.c @@ -243,157 +243,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } -typedef struct GentooSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; -} GentooSystemConfigData; - - -/* - * nm_system_device_get_system_config - * - * Retrieve any relevant configuration info for a particular device - * from the system network configuration information. Clear out existing - * info before setting stuff too. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - char *cfg_file_path = NULL; - FILE *file = NULL; - char buffer[100]; - char confline[100], dhcpline[100], ipline[100]; - int ipa, ipb, ipc, ipd; - int nNext = 0, bNext = 0, count = 0; - char *confToken; - gboolean data_good = FALSE; - gboolean use_dhcp = TRUE; - GentooSystemConfigData *sys_data = NULL; - guint32 ip4_address = 0; - guint32 ip4_netmask = 0; - guint32 ip4_gateway = 0; - guint32 ip4_broadcast = 0; - - g_return_val_if_fail (dev != NULL, NULL); - - sys_data = g_malloc0 (sizeof (GentooSystemConfigData)); - sys_data->config = nm_device_get_ip4_config(dev); - /* We use DHCP on an interface unless told not to */ - sys_data->use_dhcp = TRUE; - nm_device_set_use_dhcp (dev, TRUE); -// nm_ip4_config_set_address (sys_data->config, 0); -// nm_ip4_config_set_gateway (sys_data->config, 0); -// nm_ip4_config_set_netmask (sys_data->config, 0); - - /* Gentoo systems store this information in - * /etc/conf.d/net, this is for all interfaces. - */ - - cfg_file_path = g_strdup ("/etc/conf.d/net"); - if (!cfg_file_path) { - g_free (sys_data); - return NULL; - } - - if (!(file = fopen (cfg_file_path, "r"))) - { - g_free (cfg_file_path); - g_free (sys_data); - return NULL; - } - snprintf(confline, 100, "iface_%s", nm_device_get_iface (dev)); - snprintf(dhcpline, 100, "iface_%s=\"dhcp\"", nm_device_get_iface (dev)); - /* buffer is char[100], guess this fgets call was fairly wrong then? */ - while (fgets (buffer, 100, file) && !feof (file)) - { - /* Kock off newline if any */ - g_strstrip (buffer); - - if (strncmp (buffer, confline, strlen(confline)) == 0) - { - /* Make sure this config file is for this device */ - if (strncmp (&buffer[strlen(confline) - strlen(nm_device_get_iface (dev))], - nm_device_get_iface (dev), strlen(nm_device_get_iface (dev))) != 0) - { - nm_warning ("System config file '%s' does not define device '%s'\n", - cfg_file_path, nm_device_get_iface (dev)); - break; - } - else - data_good = TRUE; - - if (strncmp (buffer, dhcpline, strlen(dhcpline)) == 0) - { - use_dhcp = TRUE; - } - else - { - use_dhcp = FALSE; - confToken = strtok(&buffer[strlen(confline) + 2], " "); - while (count < 3) - { - if (nNext == 1 && bNext == 1) - { - ip4_address = inet_addr (confToken); - count++; - continue; - } - if (strcmp(confToken, "netmask") == 0) - { - confToken = strtok(NULL, " "); - ip4_netmask = inet_addr (confToken); - count++; - nNext = 1; - } - else if (strcmp(confToken, "broadcast") == 0) - { - confToken = strtok(NULL, " "); - count++; - bNext = 1; - } - else - { - ip4_address = inet_addr (confToken); - count++; - } - confToken = strtok(NULL, " "); - } - } - } - /* If we aren't using dhcp, then try to get the gateway */ - if (!use_dhcp) - { - snprintf(ipline, 100, "gateway=\"%s/", nm_device_get_iface (dev)); - if (strncmp(buffer, ipline, strlen(ipline) - 1) == 0) - { - snprintf(ipline, 100, "gateway=\"%s/%%d.%%d.%%d.%%d\"", nm_device_get_iface (dev) ); - sscanf(buffer, ipline, &ipa, &ipb, &ipc, &ipd); - snprintf(ipline, 100, "%d.%d.%d.%d", ipa, ipb, ipc, ipd); - ip4_gateway = inet_addr (ipline); - } - } - } - fclose (file); - g_free (cfg_file_path); - - /* If successful, set values on the device */ - if (data_good) - { - nm_warning("data good :-)"); - nm_device_set_use_dhcp (dev, use_dhcp); - if (ip4_address) - nm_ip4_config_set_address (sys_data->config, ip4_address); - if (ip4_gateway) - nm_ip4_config_set_gateway (sys_data->config, ip4_gateway); - if (ip4_netmask) - nm_ip4_config_set_netmask (sys_data->config, ip4_netmask); - if (ip4_broadcast) - nm_ip4_config_set_broadcast (sys_data->config, ip4_broadcast); - } - return (void *)sys_data; -} - /* * nm_system_device_replace_default_route * @@ -408,32 +257,6 @@ nm_system_device_replace_default_route (const char *iface, nm_generic_device_replace_default_route (iface, gw, mss); } -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - GentooSystemConfigData *sys_data = (GentooSystemConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - g_return_if_fail(sys_data != NULL); - - if (sys_data->config) - g_object_unref (sys_data->config); - - g_free (sys_data); -} - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - return FALSE; -} - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerMandriva.c b/src/backends/NetworkManagerMandriva.c index ec9979d19e..62ae4715f7 100644 --- a/src/backends/NetworkManagerMandriva.c +++ b/src/backends/NetworkManagerMandriva.c @@ -265,239 +265,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } - -typedef struct MandrivaSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; - gboolean system_disabled; -} MandrivaSystemConfigData; - - -/* - * get_current_profile_name - * - * Retrieve the current network profile, if any - * - */ -static char *get_current_profile_name (void) -{ - shvarFile * file; - char * buf; - - if (!(file = svNewFile (SYSCONFDIR"/sysconfig/network"))) - return NULL; - - buf = svGetValue (file, "CURRENT_PROFILE"); - if (!buf) - buf = strdup ("default"); - svCloseFile (file); - - return buf; -} - - -/* - * nm_system_device_get_system_config - * - * Read in the config file for a device. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - char * cfg_file_path = NULL; - shvarFile * file; - char * buf = NULL; - MandrivaSystemConfigData * sys_data = NULL; - gboolean error = FALSE; - - g_return_val_if_fail (dev != NULL, NULL); - - /* Red Hat/Fedora Core systems store this information in - * /etc/sysconfig/network-scripts/ifcfg-* where * is the interface - * name. - */ - - sys_data = g_malloc0 (sizeof (MandrivaSystemConfigData)); - sys_data->use_dhcp = TRUE; - - cfg_file_path = g_strdup_printf (SYSCONFDIR"/sysconfig/network-scripts/ifcfg-%s", nm_device_get_iface (dev)); - if (!cfg_file_path) - return sys_data; - - if (!(file = svNewFile (cfg_file_path))) - { - g_free (cfg_file_path); - return sys_data; - } - g_free (cfg_file_path); - - /* Make sure this config file is for this device */ - buf = svGetValue (file, "DEVICE"); - if (!buf || strcmp (buf, nm_device_get_iface (dev))) - { - free (buf); - goto out; - } - - if ((buf = svGetValue (file, "BOOTPROTO"))) - { - if (strcasecmp (buf, "dhcp")) - sys_data->use_dhcp = FALSE; - free (buf); - } - - if ((buf = svGetValue (file, "NM_CONTROLLED"))) - { - nm_debug ("NM_CONTROLLED=%s", buf); - if (!strcasecmp (buf, "no")) - { - nm_info ("System configuration disables device %s", nm_device_get_iface (dev)); - sys_data->system_disabled = TRUE; - } - free (buf); - } - - sys_data->config = nm_ip4_config_new (); - - if (!(sys_data->use_dhcp)) - { - if ((buf = svGetValue (file, "IPADDR"))) - { - nm_ip4_config_set_address (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but no IP address specified. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - - if ((buf = svGetValue (file, "GATEWAY"))) - { - nm_ip4_config_set_gateway (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but no gateway specified. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - - if ((buf = svGetValue (file, "NETMASK"))) - { - nm_ip4_config_set_netmask (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - if ((buf = svGetValue (file, "BROADCAST"))) - { - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - } - - /* If we're using Static IP, grab DNS servers from the profile's config file */ - if (!sys_data->use_dhcp) - { - char * cur_profile_name = get_current_profile_name (); - - if (cur_profile_name) - { - char *filename = g_strdup_printf (SYSCONFDIR"/sysconfig/networking/profiles/%s/resolv.conf", cur_profile_name); - - nm_generic_set_ip4_config_from_resolv_conf (filename, sys_data->config); - g_free (filename); - g_free (cur_profile_name); - } - } - -#if 0 - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug (" DHCP=%d\n", sys_data->use_dhcp); - nm_debug (" ADDR=%d\n", nm_ip4_config_get_address (sys_data->config)); - nm_debug (" GW=%d\n", nm_ip4_config_get_gateway (sys_data->config)); - nm_debug (" NM=%d\n", nm_ip4_config_get_netmask (sys_data->config)); - nm_debug ("---------------------\n"); -#endif - -out: - svCloseFile (file); - - if (error) - { - sys_data->use_dhcp = TRUE; - /* Clear out the config */ - g_object_unref (sys_data->config); - sys_data->config = NULL; - } - - return (void *)sys_data; -} - - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - MandrivaSystemConfigData *sys_data = (MandrivaSystemConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - return; - - if (sys_data->config) - g_object_unref (sys_data->config); -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - MandrivaSystemConfigData *sys_data; - - g_return_val_if_fail (dev != NULL, FALSE); - - if ((sys_data = nm_device_get_system_config_data (dev))) - return sys_data->system_disabled; - - return FALSE; -} - - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerPaldo.c b/src/backends/NetworkManagerPaldo.c index 33ad87898e..1b8d2e9851 100644 --- a/src/backends/NetworkManagerPaldo.c +++ b/src/backends/NetworkManagerPaldo.c @@ -228,246 +228,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } - -typedef struct PaldoSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; - gboolean system_disabled; -} PaldoSystemConfigData; - -#define PALDO_NETDEVICE_CONFIG_DIR SYSCONFDIR "/network/devices" - -static GKeyFile *nm_system_device_get_netdevice_file (NMDevice *dev) -{ - GDir *dir; - GKeyFile *file; - const char *entry; - char *path; - char *file_udi; - - dir = g_dir_open (PALDO_NETDEVICE_CONFIG_DIR, 0, NULL); - if (dir == NULL) - return NULL; - - file = g_key_file_new (); - - for (entry = g_dir_read_name (dir); entry != NULL; entry = g_dir_read_name (dir)) - { - if (!g_str_has_suffix (entry, ".netdevice")) - continue; - - path = g_strdup_printf ("%s/%s", PALDO_NETDEVICE_CONFIG_DIR, entry); - if (!g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL)) - { - g_free (path); - continue; - } - g_free (path); - - file_udi = g_key_file_get_string (file, "Network Device", "UDI", NULL); - if (file_udi == NULL) - continue; - - if (strcmp (file_udi, nm_device_get_udi (dev)) != 0) { - g_free (file_udi); - continue; - } - - g_free (file_udi); - break; - } - - if (entry == NULL) - { - g_key_file_free (file); - file = NULL; - } - - g_dir_close (dir); - - return file; -} - -static NMIP4Config *netdevice_file_get_ip4_config (GKeyFile *file) -{ - NMIP4Config *ip4_config; - char **ipaddress_list; - char **ipaddress; - char *gateway; - char *value; - struct in_addr addr; - - ipaddress_list = g_key_file_get_string_list (file, "Network Device", "IPAddress", NULL, NULL); - if (ipaddress_list == NULL) - return NULL; - - ip4_config = nm_ip4_config_new (); - - for (ipaddress = ipaddress_list; *ipaddress != NULL; ipaddress++) - { - char *mask_slash, *mask_str; - int mask, hostmask; - - mask_slash = strchr (*ipaddress, '/'); - if (mask_slash == NULL) - continue; - - mask_str = mask_slash + 1; - if (*mask_str == '\0') - continue; - *mask_slash = '\0'; - - if (!inet_aton (*ipaddress, &addr)) - continue; - - mask = atoi (mask_str); - if (mask < 0 || mask > 32) - continue; - - hostmask = (1 << (32 - mask)) - 1; - nm_ip4_config_set_address (ip4_config, addr.s_addr); - nm_ip4_config_set_netmask (ip4_config, ~hostmask); - nm_ip4_config_set_broadcast (ip4_config, addr.s_addr | hostmask); - - break; - } - - g_strfreev (ipaddress_list); - - if (ipaddress == NULL) - { - g_object_unref (ip4_config); - return NULL; - } - - gateway = g_key_file_get_string (file, "Network Device", "Gateway", NULL); - if (gateway != NULL) - { - if (inet_aton (gateway, &addr)) - nm_ip4_config_set_gateway (ip4_config, addr.s_addr); - - g_free (gateway); - } - - ipaddress_list = g_key_file_get_string_list (file, "Network Device", "Nameserver", NULL, NULL); - if (ipaddress_list != NULL) - { - for (ipaddress = ipaddress_list; *ipaddress != NULL; ipaddress++) - { - if (!inet_aton (*ipaddress, &addr)) - continue; - - nm_ip4_config_add_nameserver (ip4_config, addr.s_addr); - } - - g_strfreev (ipaddress_list); - } - - value = g_key_file_get_string (file, "Network Device", "Domain", NULL); - if (value != NULL) - { - nm_ip4_config_add_domain (ip4_config, value); - g_free (value); - } - - value = g_key_file_get_string (file, "Network Device", "Hostname", NULL); - if (value != NULL) - { - nm_ip4_config_set_hostname (ip4_config, value); - g_free (value); - } - - return ip4_config; -} - -/* - * nm_system_device_get_system_config - * - * Read in the config file for a device. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - PaldoSystemConfigData *sys_data = NULL; - GKeyFile *file; - char *method; - GError *error = NULL; - gboolean value; - - g_return_val_if_fail (dev != NULL, NULL); - - sys_data = g_malloc0 (sizeof (PaldoSystemConfigData)); - sys_data->use_dhcp = TRUE; - - file = nm_system_device_get_netdevice_file (dev); - if (file == NULL) - return sys_data; - - method = g_key_file_get_string (file, "Network Device", "Method", NULL); - if (method != NULL && strcmp (method, "static") == 0) - { - sys_data->config = netdevice_file_get_ip4_config (file); - - /* only disable dhcp if valid config has been found */ - if (sys_data->config != NULL) - sys_data->use_dhcp = FALSE; - } - g_free (method); - - value = g_key_file_get_boolean (file, "Network Device", "Disabled", &error); - if (error == NULL) - sys_data->system_disabled = value; - g_clear_error (&error); - - g_key_file_free (file); - - /* FIXME: add /etc/network/networks/example.network files */ - - return (void *)sys_data; -} - - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - PaldoSystemConfigData *sys_data = (PaldoSystemConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - return; - - if (sys_data->config) - g_object_unref (sys_data->config); -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to - * disable this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - PaldoSystemConfigData *sys_data; - - g_return_val_if_fail (dev != NULL, FALSE); - - if ((sys_data = nm_device_get_system_config_data (dev))) - return sys_data->system_disabled; - - return FALSE; -} - - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerRedHat.c b/src/backends/NetworkManagerRedHat.c index f29ee25c9b..a9cec5b4bb 100644 --- a/src/backends/NetworkManagerRedHat.c +++ b/src/backends/NetworkManagerRedHat.c @@ -252,238 +252,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } - -typedef struct RHSystemConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; - gboolean system_disabled; -} RHSystemConfigData; - - -/* - * get_current_profile_name - * - * Retrieve the current network profile, if any - * - */ -static char *get_current_profile_name (void) -{ - shvarFile * file; - char * buf; - - if (!(file = svNewFile (SYSCONFDIR"/sysconfig/network"))) - return NULL; - - buf = svGetValue (file, "CURRENT_PROFILE"); - if (!buf) - buf = strdup ("default"); - svCloseFile (file); - - return buf; -} - - -/* - * nm_system_device_get_system_config - * - * Read in the config file for a device. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - char * cfg_file_path = NULL; - shvarFile * file; - char * buf = NULL; - RHSystemConfigData * sys_data = NULL; - gboolean error = FALSE; - - g_return_val_if_fail (dev != NULL, NULL); - - /* Red Hat/Fedora Core systems store this information in - * /etc/sysconfig/network-scripts/ifcfg-* where * is the interface - * name. - */ - - sys_data = g_malloc0 (sizeof (RHSystemConfigData)); - sys_data->use_dhcp = TRUE; - - cfg_file_path = g_strdup_printf (SYSCONFDIR"/sysconfig/network-scripts/ifcfg-%s", nm_device_get_iface (dev)); - if (!cfg_file_path) - return sys_data; - - if (!(file = svNewFile (cfg_file_path))) - { - g_free (cfg_file_path); - return sys_data; - } - g_free (cfg_file_path); - - /* Make sure this config file is for this device */ - buf = svGetValue (file, "DEVICE"); - if (!buf || strcmp (buf, nm_device_get_iface (dev))) - { - free (buf); - goto out; - } - - if ((buf = svGetValue (file, "BOOTPROTO"))) - { - if (strcasecmp (buf, "dhcp")) - sys_data->use_dhcp = FALSE; - free (buf); - } - - if ((buf = svGetValue (file, "NM_CONTROLLED"))) - { - nm_debug ("NM_CONTROLLED=%s", buf); - if (!strcasecmp (buf, "no")) - { - nm_info ("System configuration disables device %s", nm_device_get_iface (dev)); - sys_data->system_disabled = TRUE; - } - free (buf); - } - - sys_data->config = nm_ip4_config_new (); - - if (!(sys_data->use_dhcp)) - { - if ((buf = svGetValue (file, "IPADDR"))) - { - nm_ip4_config_set_address (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but no IP address specified. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - - if ((buf = svGetValue (file, "GATEWAY"))) - { - nm_ip4_config_set_gateway (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - nm_warning ("Network configuration for device '%s' was invalid (non-DHCP configuration, " - "but no gateway specified. Will use DHCP instead.", nm_device_get_iface (dev)); - error = TRUE; - goto out; - } - - if ((buf = svGetValue (file, "NETMASK"))) - { - nm_ip4_config_set_netmask (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - if ((buf = svGetValue (file, "BROADCAST"))) - { - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - } - - /* If we're using Static IP, grab DNS servers from the profile's config file */ - if (!sys_data->use_dhcp) - { - char * cur_profile_name = get_current_profile_name (); - - if (cur_profile_name) - { - char *filename = g_strdup_printf (SYSCONFDIR"/sysconfig/networking/profiles/%s/resolv.conf", cur_profile_name); - - nm_generic_set_ip4_config_from_resolv_conf (filename, sys_data->config); - g_free (filename); - g_free (cur_profile_name); - } - } - -#if 0 - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug (" DHCP=%d\n", sys_data->use_dhcp); - nm_debug (" ADDR=%d\n", nm_ip4_config_get_address (sys_data->config)); - nm_debug (" GW=%d\n", nm_ip4_config_get_gateway (sys_data->config)); - nm_debug (" NM=%d\n", nm_ip4_config_get_netmask (sys_data->config)); - nm_debug ("---------------------\n"); -#endif - -out: - svCloseFile (file); - - if (error) - { - sys_data->use_dhcp = TRUE; - /* Clear out the config */ - g_object_unref (sys_data->config); - sys_data->config = NULL; - } - - return (void *)sys_data; -} - - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - RHSystemConfigData *sys_data = (RHSystemConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - return; - - if (sys_data->config) - g_object_unref (sys_data->config); -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - RHSystemConfigData *sys_data; - - g_return_val_if_fail (dev != NULL, FALSE); - - if ((sys_data = nm_device_get_system_config_data (dev))) - return sys_data->system_disabled; - - return FALSE; -} - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerSlackware.c b/src/backends/NetworkManagerSlackware.c index beeb1e06fd..15a31012ad 100644 --- a/src/backends/NetworkManagerSlackware.c +++ b/src/backends/NetworkManagerSlackware.c @@ -98,19 +98,6 @@ void nm_system_device_flush_addresses_with_iface (const char *iface) nm_generic_device_flush_addresses_with_iface (iface); } -/* - * nm_system_device_get_system_config - * - * Retrieve any relevant configuration info for a particular device - * from the system network configuration information. Clear out existing - * info before setting stuff too. - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - return NULL; -} - /* * nm_system_device_has_active_routes * @@ -233,23 +220,6 @@ void nm_system_flush_arp_cache (void) nm_generic_flush_arp_cache (); } -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ -} - -/* - * nm_system_device_get_disabled - * - * Return whether the distro-specific system config tells us to use - * dhcp for this device. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - return FALSE; -} - - /* * nm_system_activate_nis * diff --git a/src/backends/NetworkManagerSuSE.c b/src/backends/NetworkManagerSuSE.c index 1ae0bbf1ab..30be3ba441 100644 --- a/src/backends/NetworkManagerSuSE.c +++ b/src/backends/NetworkManagerSuSE.c @@ -249,286 +249,6 @@ void nm_system_device_add_ip6_link_address (NMDevice *dev) nm_generic_device_add_ip6_link_address (dev); } - -typedef struct SuSEDeviceConfigData -{ - NMIP4Config * config; - gboolean use_dhcp; - gboolean system_disabled; - guint32 mtu; -} SuSEDeviceConfigData; - - -/* - * nm_system_device_get_system_config - * - * Read in the config file for a device. - * - * SuSE stores this information in /etc/sysconfig/network/ifcfg-*- - * - */ -void *nm_system_device_get_system_config (NMDevice *dev) -{ - char *cfg_file_path = NULL; - char mac[18]; - struct stat statbuf; - shvarFile *file; - char *buf = NULL; - SuSEDeviceConfigData *sys_data = NULL; - struct ether_addr hw_addr; - FILE *f = NULL; - char buffer[512]; - gboolean error = FALSE; - int i, len; - struct in_addr temp_addr; - char *ip_str; - - g_return_val_if_fail (dev != NULL, NULL); - - sys_data = g_malloc0 (sizeof (SuSEDeviceConfigData)); - sys_data->use_dhcp = TRUE; - - if (NM_IS_DEVICE_802_3_ETHERNET (dev)) - nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); - else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) - nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr); - - sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x", - hw_addr.ether_addr_octet[0], hw_addr.ether_addr_octet[1], - hw_addr.ether_addr_octet[2], hw_addr.ether_addr_octet[3], - hw_addr.ether_addr_octet[4], hw_addr.ether_addr_octet[5]); - cfg_file_path = g_strdup_printf (SYSCONFDIR"/sysconfig/network/ifcfg-eth-id-%s", mac); - if (!cfg_file_path) - return sys_data; - if (stat(cfg_file_path, &statbuf) == 0) - goto found; - - g_free(cfg_file_path); - cfg_file_path = g_strdup_printf (SYSCONFDIR"/sysconfig/network/ifcfg-wlan-id-%s", mac); - if (!cfg_file_path) - return sys_data; - if (stat(cfg_file_path, &statbuf) == 0) - goto found; - - g_free(cfg_file_path); - cfg_file_path = g_strdup_printf (SYSCONFDIR"/sysconfig/network/ifcfg-%s", nm_device_get_iface (dev)); - if (!cfg_file_path) - return sys_data; - if (stat(cfg_file_path, &statbuf) == 0) - goto found; - - g_free (cfg_file_path); - return sys_data; - -found: - nm_debug ("found config '%s' for interface '%s'", cfg_file_path, nm_device_get_iface (dev)); - if (!(file = svNewFile (cfg_file_path))) - { - g_free (cfg_file_path); - return sys_data; - } - g_free (cfg_file_path); - - if ((buf = svGetValue (file, "BOOTPROTO"))) - { - nm_debug ("BOOTPROTO=%s", buf); - if (strcasecmp (buf, "dhcp")) - sys_data->use_dhcp = FALSE; - free (buf); - } - - if ((buf = svGetValue (file, "NM_CONTROLLED"))) - { - nm_debug ("NM_CONTROLLED=%s", buf); - if (!strcasecmp (buf, "no")) - { - nm_info ("System configuration disables device %s", nm_device_get_iface (dev)); - sys_data->system_disabled = TRUE; - } - free (buf); - } - - if ((buf = svGetValue (file, "MTU"))) - { - guint32 mtu; - - errno = 0; - mtu = strtoul (buf, NULL, 10); - if (!errno && mtu > 500 && mtu < INT_MAX) - sys_data->mtu = mtu; - free (buf); - } - - sys_data->config = nm_ip4_config_new (); - - if (!sys_data->use_dhcp || sys_data->system_disabled) - { - buf = svGetValue (file, "IPADDR"); - if (buf) - { - struct in_addr ip; - int ret; - - ret = inet_aton (buf, &ip); - if (ret) - nm_ip4_config_set_address (sys_data->config, ip.s_addr); - else - error = TRUE; - free (buf); - } - else - error = TRUE; - - if (error) - { - nm_warning ("Network configuration for device '%s' was invalid: Non-DHCP configuration, " - "but no IP address specified. Will use DHCP instead.", nm_device_get_iface (dev)); - goto out; - } - - if ((buf = svGetValue (file, "NETMASK"))) - { - nm_ip4_config_set_netmask (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 ip4addr = nm_ip4_config_get_address (sys_data->config); - - /* Make a default netmask if we have an IP address */ - if (((ntohl (ip4addr) & 0xFF000000) >> 24) <= 127) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFF000000)); - else if (((ntohl (ip4addr) & 0xFF000000) >> 24) <= 191) - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFF0000)); - else - nm_ip4_config_set_netmask (sys_data->config, htonl (0xFFFFFF00)); - } - - if ((buf = svGetValue (file, "BROADCAST"))) - { - nm_ip4_config_set_broadcast (sys_data->config, inet_addr (buf)); - free (buf); - } - else - { - guint32 broadcast = ((nm_ip4_config_get_address (sys_data->config) & nm_ip4_config_get_netmask (sys_data->config)) - | ~nm_ip4_config_get_netmask (sys_data->config)); - nm_ip4_config_set_broadcast (sys_data->config, broadcast); - } - - nm_ip4_config_set_mtu (sys_data->config, sys_data->mtu); - - buf = NULL; - if ((f = fopen (SYSCONFDIR"/sysconfig/network/routes", "r"))) - { - while (fgets (buffer, 512, f) && !feof (f)) - { - buf = strtok(buffer, " "); - if (strcmp(buf, "default") == 0) - { - buf = strtok(NULL, " "); - if (buf) - nm_ip4_config_set_gateway (sys_data->config, inet_addr (buf)); - break; - } - } - fclose (f); - } - if (!buf) - nm_info ("Network configuration for device '%s' does not specify a gateway but is " - "statically configured (non-DHCP).", nm_device_get_iface (dev)); - - nm_generic_set_ip4_config_from_resolv_conf (SYSCONFDIR"/resolv.conf", sys_data->config); - } - -out: - svCloseFile (file); - - if (error) - { - nm_debug ("error, enable dhcp"); - sys_data->use_dhcp = TRUE; - /* Clear out the config */ - g_object_unref (sys_data->config); - sys_data->config = NULL; - } - - nm_debug ("------ Config (%s)", nm_device_get_iface (dev)); - nm_debug ("dhcp=%u", sys_data->use_dhcp); - - temp_addr.s_addr = nm_ip4_config_get_address (sys_data->config); - ip_str = g_strdup (inet_ntoa (temp_addr)); - nm_debug ("addr=%s", ip_str); - g_free (ip_str); - - temp_addr.s_addr = nm_ip4_config_get_gateway (sys_data->config); - ip_str = g_strdup (inet_ntoa (temp_addr)); - nm_debug ("gw=%s", ip_str); - g_free (ip_str); - - temp_addr.s_addr = nm_ip4_config_get_netmask (sys_data->config); - ip_str = g_strdup (inet_ntoa (temp_addr)); - nm_debug ("mask=%s", ip_str); - g_free (ip_str); - - if (sys_data->mtu) - nm_debug ("mtu=%u", sys_data->mtu); - - len = nm_ip4_config_get_num_nameservers (sys_data->config); - for (i = 0; i < len; i++) - { - guint ns_addr = nm_ip4_config_get_nameserver (sys_data->config, i); - - temp_addr.s_addr = ns_addr; - ip_str = g_strdup (inet_ntoa (temp_addr)); - nm_debug ("ns_%u=%s", i, ip_str); - g_free (ip_str); - } - nm_debug ("---------------------\n"); - - return sys_data; -} - - -/* - * nm_system_device_free_system_config - * - * Free stored system config data - * - */ -void nm_system_device_free_system_config (NMDevice *dev, void *system_config_data) -{ - SuSEDeviceConfigData *sys_data = (SuSEDeviceConfigData *)system_config_data; - - g_return_if_fail (dev != NULL); - - if (!sys_data) - return; - - if (sys_data->config) - g_object_unref (sys_data->config); -} - - -/* - * nm_system_device_get_disabled - * - * Return whether the distribution has flagged this device as disabled. - * - */ -gboolean nm_system_device_get_disabled (NMDevice *dev) -{ - SuSEDeviceConfigData *sys_data; - - g_return_val_if_fail (dev != NULL, FALSE); - - if ((sys_data = nm_device_get_system_config_data (dev))) - return sys_data->system_disabled; - - return FALSE; -} - - /* * nm_system_activate_nis * diff --git a/src/nm-cdma-device.c b/src/nm-cdma-device.c index b0c23113c7..2941832eaa 100644 --- a/src/nm-cdma-device.c +++ b/src/nm-cdma-device.c @@ -41,7 +41,8 @@ NMCdmaDevice * nm_cdma_device_new (const char *udi, const char *data_iface, const char *monitor_iface, - const char *driver) + const char *driver, + gboolean managed) { g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (data_iface != NULL, NULL); @@ -52,6 +53,7 @@ nm_cdma_device_new (const char *udi, NM_DEVICE_INTERFACE_IFACE, data_iface, NM_DEVICE_INTERFACE_DRIVER, driver, NM_CDMA_DEVICE_MONITOR_IFACE, monitor_iface, + NM_DEVICE_INTERFACE_MANAGED, managed, NULL); } diff --git a/src/nm-cdma-device.h b/src/nm-cdma-device.h index 953d9ac0e5..eef2aba5df 100644 --- a/src/nm-cdma-device.h +++ b/src/nm-cdma-device.h @@ -32,7 +32,8 @@ GType nm_cdma_device_get_type (void); NMCdmaDevice *nm_cdma_device_new (const char *udi, const char *data_iface, const char *monitor_iface, - const char *driver); + const char *driver, + gboolean managed); G_END_DECLS diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 97275078dd..c1c94dd4b3 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -142,6 +142,8 @@ struct _NMDevice80211WirelessPrivate GSList * ap_list; NMAccessPoint * current_ap; guint32 rate; + gboolean enabled; /* rfkilled or not */ + guint state_to_disconnected_id; gboolean scanning; glong scheduled_scan_time; @@ -874,9 +876,22 @@ real_check_connection_compatible (NMDevice *device, } static gboolean -real_can_activate (NMDevice *dev, gboolean wireless_enabled) +real_can_activate (NMDevice *dev) { - if (!wireless_enabled) + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + NMSupplicantInterface *sup_iface; + guint32 state; + + if (!priv->enabled) + return FALSE; + + sup_iface = priv->supplicant.iface; + if (!sup_iface) + return FALSE; + + state = nm_supplicant_interface_get_state (sup_iface); + if (state != NM_SUPPLICANT_INTERFACE_STATE_READY) return FALSE; return TRUE; @@ -978,28 +993,6 @@ impl_device_get_access_points (NMDevice80211Wireless *self, return TRUE; } - -/* Return TRUE if activation is possible, FALSE if not */ -gboolean -nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self) -{ - NMSupplicantInterface * sup_iface; - guint32 state; - - g_return_val_if_fail (self != NULL, FALSE); - - sup_iface = self->priv->supplicant.iface; - - if (sup_iface == NULL) - return FALSE; - - state = nm_supplicant_interface_get_state (sup_iface); - if (state == NM_SUPPLICANT_INTERFACE_STATE_READY) - return TRUE; - - return FALSE; -} - /* * nm_device_get_mode * @@ -1469,14 +1462,15 @@ can_scan (NMDevice80211Wireless *self) sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface); dev_state = nm_device_get_state (NM_DEVICE (self)); + /* Don't scan when unknown, unmanaged, or unavailable */ + if (dev_state < NM_DEVICE_STATE_DISCONNECTED) + return FALSE; + is_disconnected = ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING - || dev_state == NM_DEVICE_STATE_UNKNOWN - || dev_state == NM_DEVICE_STATE_DOWN || dev_state == NM_DEVICE_STATE_DISCONNECTED - || dev_state == NM_DEVICE_STATE_FAILED - || dev_state == NM_DEVICE_STATE_CANCELLED) ? TRUE : FALSE; + || dev_state == NM_DEVICE_STATE_FAILED) ? TRUE : FALSE; /* All wireless devices can scan when disconnected */ if (is_disconnected) @@ -1911,7 +1905,7 @@ link_timeout_cb (gpointer user_data) * fail. */ if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (dev)); + nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED); return FALSE; } @@ -2523,12 +2517,11 @@ error: /****************************************************************************/ static void -real_set_hw_address (NMDevice *dev) +real_update_hw_address (NMDevice *dev) { NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); - const char *iface; + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); struct ifreq req; - size_t len; int ret, fd; fd = socket (PF_INET, SOCK_DGRAM, 0); @@ -2537,20 +2530,19 @@ real_set_hw_address (NMDevice *dev) return; } - iface = nm_device_get_iface (dev); - len = MIN (sizeof (req.ifr_name) - 1, (size_t) strlen (iface)); - memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, iface, len); + strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); ret = ioctl (fd, SIOCGIFHWADDR, &req); - if (ret) + if (ret) { + nm_warning ("%s: (%s) error getting hardware address: %d", + __func__, nm_device_get_iface (dev), errno); goto out; + } - if (memcmp (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)) == 0) - goto out; - - memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); - g_object_notify (G_OBJECT (dev), NM_DEVICE_802_11_WIRELESS_HW_ADDRESS); + if (memcmp (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr))) { + memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr)); + g_object_notify (G_OBJECT (dev), NM_DEVICE_802_11_WIRELESS_HW_ADDRESS); + } out: close (fd); @@ -2975,6 +2967,11 @@ nm_device_802_11_wireless_dispose (GObject *object) set_current_ap (self, NULL); + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + G_OBJECT_CLASS (nm_device_802_11_wireless_parent_class)->dispose (object); } @@ -3029,7 +3026,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) parent_class->is_up = real_is_up; parent_class->bring_up = real_bring_up; parent_class->bring_down = real_bring_down; - parent_class->set_hw_address = real_set_hw_address; + parent_class->update_hw_address = real_update_hw_address; 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; @@ -3121,10 +3118,35 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) dbus_g_error_domain_register (NM_WIFI_ERROR, NULL, NM_TYPE_WIFI_ERROR); } +static gboolean +unavailable_to_disconnected (gpointer user_data) +{ + nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); + return FALSE; +} + static void state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) { + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (device); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + + /* Remove any previous delayed transition to disconnected */ + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + switch (state) { + case NM_DEVICE_STATE_UNAVAILABLE: + /* If transitioning to UNAVAILBLE and the device is not rfkilled, + * transition to DISCONNECTED because the device is ready to use. + * Otherwise the rfkill/enabled handler handle the transition to + * DISCONNECTED when the device is no longer rfkilled. + */ + if (priv->enabled) + priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); + break; case NM_DEVICE_STATE_ACTIVATED: activation_success_handler (device); break; @@ -3143,7 +3165,8 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) NMDevice80211Wireless * nm_device_802_11_wireless_new (const char *udi, const char *iface, - const char *driver) + const char *driver, + gboolean managed) { GObject *obj; @@ -3155,6 +3178,7 @@ nm_device_802_11_wireless_new (const char *udi, NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_DRIVER, driver, + NM_DEVICE_INTERFACE_MANAGED, managed, NULL); if (obj == NULL) return NULL; @@ -3193,3 +3217,27 @@ nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *self) return NULL; } +void +nm_device_802_11_wireless_set_enabled (NMDevice80211Wireless *self, gboolean enabled) +{ + NMDevice80211WirelessPrivate *priv; + NMDeviceState state; + + g_return_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self)); + + priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + if (priv->enabled == enabled) + return; + + priv->enabled = enabled; + + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + if (state >= NM_DEVICE_STATE_UNAVAILABLE) { + if (enabled) + nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED); + else + nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE); + } +} + + diff --git a/src/nm-device-802-11-wireless.h b/src/nm-device-802-11-wireless.h index 035f8cb30f..59b30794f3 100644 --- a/src/nm-device-802-11-wireless.h +++ b/src/nm-device-802-11-wireless.h @@ -82,7 +82,8 @@ GType nm_device_802_11_wireless_get_type (void); NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *udi, const char *iface, - const char *driver); + const char *driver, + gboolean managed); void nm_device_802_11_wireless_set_ssid (NMDevice80211Wireless *self, const GByteArray * ssid); @@ -100,10 +101,9 @@ gboolean nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self); -gboolean nm_device_802_11_wireless_can_activate (NMDevice80211Wireless * self); - NMAccessPoint * nm_device_802_11_wireless_get_activation_ap (NMDevice80211Wireless *self); +void nm_device_802_11_wireless_set_enabled (NMDevice80211Wireless *self, gboolean enabled); G_END_DECLS diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index fb5f31ecfc..63432bb91a 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "nm-device-802-3-ethernet.h" #include "nm-device-interface.h" @@ -89,6 +90,7 @@ typedef struct { struct ether_addr hw_addr; gboolean carrier; + guint state_to_disconnected_id; char * carrier_file_path; gulong link_connected_id; @@ -120,8 +122,6 @@ enum { }; -static void set_carrier (NMDevice8023Ethernet *self, const gboolean carrier); - static gboolean supports_mii_carrier_detect (NMDevice8023Ethernet *dev); static gboolean supports_ethtool_carrier_detect (NMDevice8023Ethernet *dev); @@ -157,6 +157,31 @@ nm_ethernet_error_get_type (void) return etype; } +static void +set_carrier (NMDevice8023Ethernet *self, const gboolean carrier) +{ + NMDevice8023EthernetPrivate *priv; + NMDeviceState state; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); + if (priv->carrier == carrier) + return; + + priv->carrier = carrier; + g_object_notify (G_OBJECT (self), NM_DEVICE_802_3_ETHERNET_CARRIER); + + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + if (state == NM_DEVICE_STATE_UNAVAILABLE) { + if (carrier) + nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED); + } else if (state >= NM_DEVICE_STATE_DISCONNECTED) { + if (!carrier) + nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE); + } +} + static void nm_device_802_3_ethernet_carrier_on (NMNetlinkMonitor *monitor, int idx, @@ -195,29 +220,33 @@ nm_device_802_3_ethernet_carrier_off (NMNetlinkMonitor *monitor, } } +static gboolean +unavailable_to_disconnected (gpointer user_data) +{ + nm_device_state_changed (NM_DEVICE (user_data), NM_DEVICE_STATE_DISCONNECTED); + return FALSE; +} + static void device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) { NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (user_data); NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - gboolean carrier = FALSE; - guint32 caps; - gchar *contents; - if (state != NM_DEVICE_STATE_ACTIVATED) - return; - - /* Devices that don't support carrier detect are always "on" */ - caps = nm_device_get_capabilities (NM_DEVICE (self)); - if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) - return; - - if (g_file_get_contents (priv->carrier_file_path, &contents, NULL, NULL)) { - carrier = atoi (contents) > 0 ? TRUE : FALSE; - g_free (contents); + /* Remove any previous delayed transition to disconnected */ + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; } - set_carrier (self, carrier); + /* If transitioning to UNAVAILBLE and we have a carrier, transition to + * DISCONNECTED because the device is ready to use. Otherwise the carrier-on + * handler will handle the transition to DISCONNECTED when the carrier is detected. + */ + if ((state == NM_DEVICE_STATE_UNAVAILABLE) && priv->carrier) { + priv->state_to_disconnected_id = g_idle_add (unavailable_to_disconnected, self); + return; + } } static GObject* @@ -258,7 +287,7 @@ constructor (GType type, } else { priv->link_connected_id = 0; priv->link_disconnected_id = 0; - set_carrier (NM_DEVICE_802_3_ETHERNET (dev), TRUE); + priv->carrier = TRUE; } g_signal_connect (dev, "state-changed", G_CALLBACK (device_state_changed), dev); @@ -314,7 +343,8 @@ real_bring_down (NMDevice *dev) NMDevice8023Ethernet * nm_device_802_3_ethernet_new (const char *udi, const char *iface, - const char *driver) + const char *driver, + gboolean managed) { g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (iface != NULL, NULL); @@ -324,6 +354,7 @@ nm_device_802_3_ethernet_new (const char *udi, NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_DRIVER, driver, + NM_DEVICE_INTERFACE_MANAGED, managed, NULL); } @@ -354,20 +385,6 @@ nm_device_802_3_ethernet_get_carrier (NMDevice8023Ethernet *self) return NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self)->carrier; } -static void -set_carrier (NMDevice8023Ethernet *self, const gboolean carrier) -{ - NMDevice8023EthernetPrivate *priv; - - g_return_if_fail (NM_IS_DEVICE (self)); - - priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - if (priv->carrier != carrier) { - priv->carrier = carrier; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_3_ETHERNET_CARRIER); - } -} - /* Returns speed in Mb/s */ static guint32 nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self) @@ -402,9 +419,10 @@ out: } static void -real_set_hw_address (NMDevice *dev) +real_update_hw_address (NMDevice *dev) { NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev); + NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); struct ifreq req; int ret, fd; @@ -416,13 +434,19 @@ real_set_hw_address (NMDevice *dev) memset (&req, 0, sizeof (struct ifreq)); strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); - ret = ioctl (fd, SIOCGIFHWADDR, &req); - if (ret == 0) { - memcpy (&(NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self)->hw_addr), - &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); + if (ret) { + nm_warning ("%s: (%s) error getting hardware address: %d", + __func__, nm_device_get_iface (dev), errno); + goto out; } + if (memcmp (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr))) { + memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr)); + g_object_notify (G_OBJECT (dev), NM_DEVICE_802_3_ETHERNET_HW_ADDRESS); + } + +out: close (fd); } @@ -461,7 +485,7 @@ real_can_interrupt_activation (NMDevice *dev) } static gboolean -real_can_activate (NMDevice *dev, gboolean wireless_enabled) +real_can_activate (NMDevice *dev) { NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev); @@ -645,7 +669,7 @@ link_timeout_cb (gpointer user_data) req = nm_device_get_act_request (dev); if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (dev)); + nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED); return FALSE; } @@ -1062,7 +1086,7 @@ ppp_state_changed (NMPPPManager *ppp_manager, NMPPPStatus status, gpointer user_ break; case NM_PPP_STATUS_DEAD: if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); else nm_device_state_changed (device, NM_DEVICE_STATE_FAILED); break; @@ -1280,6 +1304,11 @@ nm_device_802_3_ethernet_dispose (GObject *object) } g_object_unref (monitor); + if (priv->state_to_disconnected_id) { + g_source_remove (priv->state_to_disconnected_id); + priv->state_to_disconnected_id = 0; + } + G_OBJECT_CLASS (nm_device_802_3_ethernet_parent_class)->dispose (object); } @@ -1337,7 +1366,7 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) parent_class->bring_up = real_bring_up; parent_class->bring_down = real_bring_down; parent_class->can_interrupt_activation = real_can_interrupt_activation; - parent_class->set_hw_address = real_set_hw_address; + parent_class->update_hw_address = real_update_hw_address; 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; diff --git a/src/nm-device-802-3-ethernet.h b/src/nm-device-802-3-ethernet.h index 99fefb1fa3..7137ca25ad 100644 --- a/src/nm-device-802-3-ethernet.h +++ b/src/nm-device-802-3-ethernet.h @@ -59,7 +59,8 @@ GType nm_device_802_3_ethernet_get_type (void); NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *udi, const char *iface, - const char *driver); + const char *driver, + gboolean managed); void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev, struct ether_addr *addr); diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index f6cf31a569..350c579ede 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -112,6 +112,13 @@ nm_device_interface_init (gpointer g_iface) 0, G_MAXUINT32, DEVICE_TYPE_UNKNOWN, G_PARAM_READABLE)); + g_object_interface_install_property + (g_iface, g_param_spec_boolean (NM_DEVICE_INTERFACE_MANAGED, + "Managed", + "Managed", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /* Signals */ g_signal_new ("state-changed", iface_type, diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h index 514ab77174..44dace1169 100644 --- a/src/nm-device-interface.h +++ b/src/nm-device-interface.h @@ -29,6 +29,7 @@ typedef enum #define NM_DEVICE_INTERFACE_IP4_CONFIG "ip4-config" #define NM_DEVICE_INTERFACE_STATE "state" #define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */ +#define NM_DEVICE_INTERFACE_MANAGED "managed" typedef enum { NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, @@ -41,6 +42,7 @@ typedef enum { NM_DEVICE_INTERFACE_PROP_IP4_CONFIG, NM_DEVICE_INTERFACE_PROP_STATE, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, + NM_DEVICE_INTERFACE_PROP_MANAGED, } NMDeviceInterfaceProp; diff --git a/src/nm-device-private.h b/src/nm-device-private.h index a48acafb56..00752fefc7 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -33,5 +33,4 @@ void nm_device_activate_schedule_stage3_ip_config_start (NMDevice *device); void nm_device_state_changed (NMDevice *device, NMDeviceState state); - #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device.c b/src/nm-device.c index ae638e2e08..2f781b50c5 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -60,6 +60,7 @@ struct _NMDevicePrivate { gboolean dispose_has_run; gboolean initialized; + guint start_timer; NMDeviceState state; @@ -69,6 +70,7 @@ struct _NMDevicePrivate NMDeviceType type; guint32 capabilities; char * driver; + gboolean managed; /* whether managed by NM or not */ guint32 ip4_address; struct in6_addr ip6_address; @@ -97,13 +99,6 @@ static gboolean nm_device_activate (NMDeviceInterface *device, static void nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self); static void nm_device_deactivate (NMDeviceInterface *device); -static void -nm_device_set_address (NMDevice *device) -{ - if (NM_DEVICE_GET_CLASS (device)->set_hw_address) - NM_DEVICE_GET_CLASS (device)->set_hw_address (device); -} - static void device_interface_init (NMDeviceInterface *device_interface_class) { @@ -134,9 +129,18 @@ nm_device_init (NMDevice * self) self->priv->system_config_data = NULL; self->priv->ip4_config = NULL; - self->priv->state = NM_DEVICE_STATE_DISCONNECTED; + self->priv->state = NM_DEVICE_STATE_UNMANAGED; } +static gboolean +device_start (gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + + self->priv->start_timer = 0; + nm_device_state_changed (self, NM_DEVICE_STATE_UNAVAILABLE); + return FALSE; +} static GObject* constructor (GType type, @@ -172,17 +176,14 @@ constructor (GType type, goto error; } - /* Grab IP config data for this device from the system configuration files */ - priv->system_config_data = nm_system_device_get_system_config (dev); - - /* Allow distributions to flag devices as disabled */ - if (nm_system_device_get_disabled (dev)) { - nm_warning ("(%s): Device otherwise managed, ignoring.", priv->iface); - goto error; - } - nm_print_device_capabilities (dev); + /* Delay transition from UNMANAGED to UNAVAILABLE until we've given the + * system settings service a chance to figure out whether the device is + * managed or not. + */ + priv->start_timer = g_timeout_add (4000, device_start, dev); + priv->initialized = TRUE; return object; @@ -348,12 +349,11 @@ nm_device_get_act_request (NMDevice *self) gboolean -nm_device_can_activate (NMDevice *self, gboolean wireless_enabled) +nm_device_can_activate (NMDevice *self) { - if (!NM_DEVICE_GET_CLASS (self)->can_activate) - return TRUE; - - return NM_DEVICE_GET_CLASS (self)->can_activate (self, wireless_enabled); + if (NM_DEVICE_GET_CLASS (self)->can_activate) + return NM_DEVICE_GET_CLASS (self)->can_activate (self); + return TRUE; } NMConnection * @@ -1058,8 +1058,6 @@ nm_device_deactivate (NMDeviceInterface *device) /* Call device type-specific deactivation */ if (NM_DEVICE_GET_CLASS (self)->deactivate) NM_DEVICE_GET_CLASS (self)->deactivate (self); - - nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED); } static gboolean @@ -1483,7 +1481,10 @@ nm_device_bring_up (NMDevice *self, gboolean wait) nm_system_device_set_up_down (self, TRUE); nm_device_update_ip4_address (self); - nm_device_set_address (self); + + /* Can only get HW address of some devices when they are up */ + if (NM_DEVICE_GET_CLASS (self)->update_hw_address) + NM_DEVICE_GET_CLASS (self)->update_hw_address (self); if (NM_DEVICE_GET_CLASS (self)->bring_up) { success = NM_DEVICE_GET_CLASS (self)->bring_up (self); @@ -1495,8 +1496,6 @@ nm_device_bring_up (NMDevice *self, gboolean wait) while (wait && !nm_device_is_up (self) && (tries++ < 50)) g_usleep (200); - nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED); - return TRUE; } @@ -1525,8 +1524,6 @@ nm_device_bring_down (NMDevice *self, gboolean wait) /* Wait for the device to come up if requested */ while (wait && nm_device_is_up (self) && (tries++ < 50)) g_usleep (200); - - nm_device_state_changed (self, NM_DEVICE_STATE_DOWN); } /* @@ -1552,6 +1549,11 @@ nm_device_dispose (GObject *object) if (self->priv->dispose_has_run || !self->priv->initialized) goto out; + if (self->priv->start_timer) { + g_source_remove (self->priv->start_timer); + self->priv->start_timer = 0; + } + self->priv->dispose_has_run = TRUE; /* @@ -1561,10 +1563,10 @@ nm_device_dispose (GObject *object) * reference. */ - nm_device_bring_down (self, FALSE); - - nm_system_device_free_system_config (self, self->priv->system_config_data); - nm_device_set_ip4_config (self, NULL); + if (self->priv->managed) { + nm_device_bring_down (self, FALSE); + nm_device_set_ip4_config (self, NULL); + } clear_act_request (self); @@ -1617,6 +1619,9 @@ set_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS: priv->ip4_address = g_value_get_uint (value); break; + case NM_DEVICE_INTERFACE_PROP_MANAGED: + priv->managed = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1660,6 +1665,9 @@ get_property (GObject *object, guint prop_id, case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: g_value_set_uint (value, priv->type); break; + case NM_DEVICE_INTERFACE_PROP_MANAGED: + g_value_set_boolean (value, priv->managed); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1723,6 +1731,10 @@ nm_device_class_init (NMDeviceClass *klass) g_object_class_override_property (object_class, NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, NM_DEVICE_INTERFACE_DEVICE_TYPE); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_MANAGED, + NM_DEVICE_INTERFACE_MANAGED); } void @@ -1744,8 +1756,12 @@ nm_device_state_changed (NMDevice *device, NMDeviceState state) g_signal_emit_by_name (device, "state-changed", state); switch (state) { - case NM_DEVICE_STATE_DOWN: - if (old_state == NM_DEVICE_STATE_ACTIVATED) + case NM_DEVICE_STATE_UNAVAILABLE: + if (old_state == NM_DEVICE_STATE_UNMANAGED) + nm_device_bring_up (device, TRUE); + /* Fall through */ + case NM_DEVICE_STATE_DISCONNECTED: + if (old_state != NM_DEVICE_STATE_UNAVAILABLE) nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); break; case NM_DEVICE_STATE_ACTIVATED: @@ -1753,14 +1769,13 @@ nm_device_state_changed (NMDevice *device, NMDeviceState state) break; case NM_DEVICE_STATE_FAILED: nm_info ("Activation (%s) failed.", nm_device_get_iface (device)); - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); + nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); break; default: break; } } - NMDeviceState nm_device_get_state (NMDevice *device) { @@ -1768,3 +1783,36 @@ nm_device_get_state (NMDevice *device) return NM_DEVICE_GET_PRIVATE (device)->state; } + +gboolean +nm_device_get_managed (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); + + return NM_DEVICE_GET_PRIVATE (device)->managed; +} + +void +nm_device_set_managed (NMDevice *device, gboolean managed) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (device)); + + priv = NM_DEVICE_GET_PRIVATE (device); + if (priv->managed != managed) { + priv->managed = managed; + nm_info ("(%s): now %s", nm_device_get_iface (device), managed ? "managed" : "unmanaged"); + + if (priv->start_timer) { + g_source_remove (priv->start_timer); + priv->start_timer = 0; + } + + g_object_notify (G_OBJECT (device), NM_DEVICE_INTERFACE_MANAGED); + + /* If now managed, jump to unavailable */ + nm_device_state_changed (device, managed ? NM_DEVICE_STATE_UNAVAILABLE : NM_DEVICE_STATE_UNMANAGED); + } +} + diff --git a/src/nm-device.h b/src/nm-device.h index f7b1ba785d..b2ccc32b43 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -70,12 +70,12 @@ struct _NMDeviceClass gboolean (* bring_up) (NMDevice *self); void (* bring_down) (NMDevice *self); - void (* set_hw_address) (NMDevice *self); + void (* update_hw_address) (NMDevice *self); guint32 (* get_type_capabilities) (NMDevice *self); guint32 (* get_generic_capabilities) (NMDevice *self); - gboolean (* can_activate) (NMDevice *self, gboolean wireless_enabled); + gboolean (* can_activate) (NMDevice *self); NMConnection * (* get_best_auto_connection) (NMDevice *self, GSList *connections, @@ -135,7 +135,7 @@ void * nm_device_get_system_config_data (NMDevice *dev); NMActRequest * nm_device_get_act_request (NMDevice *dev); -gboolean nm_device_can_activate (NMDevice *dev, gboolean wireless_enabled); +gboolean nm_device_can_activate (NMDevice *dev); NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, GSList *connections, @@ -151,6 +151,9 @@ gboolean nm_device_can_interrupt_activation (NMDevice *self); NMDeviceState nm_device_get_state (NMDevice *device); +gboolean nm_device_get_managed (NMDevice *device); +void nm_device_set_managed (NMDevice *device, gboolean managed); + G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/src/nm-gsm-device.c b/src/nm-gsm-device.c index efa95a365b..ba623cbb4d 100644 --- a/src/nm-gsm-device.c +++ b/src/nm-gsm-device.c @@ -50,7 +50,8 @@ NMGsmDevice * nm_gsm_device_new (const char *udi, const char *data_iface, const char *monitor_iface, - const char *driver) + const char *driver, + gboolean managed) { g_return_val_if_fail (udi != NULL, NULL); g_return_val_if_fail (data_iface != NULL, NULL); @@ -61,6 +62,7 @@ nm_gsm_device_new (const char *udi, NM_DEVICE_INTERFACE_IFACE, data_iface, NM_DEVICE_INTERFACE_DRIVER, driver, NM_GSM_DEVICE_MONITOR_IFACE, monitor_iface, + NM_DEVICE_INTERFACE_MANAGED, managed, NULL); } diff --git a/src/nm-gsm-device.h b/src/nm-gsm-device.h index edeb66312f..1cd122f7e7 100644 --- a/src/nm-gsm-device.h +++ b/src/nm-gsm-device.h @@ -32,7 +32,8 @@ GType nm_gsm_device_get_type (void); NMGsmDevice *nm_gsm_device_new (const char *udi, const char *data_iface, const char *monitor_iface, - const char *driver); + const char *driver, + gboolean managed); G_END_DECLS diff --git a/src/nm-hal-manager.c b/src/nm-hal-manager.c index 57cf555d0d..b24c0a0d35 100644 --- a/src/nm-hal-manager.c +++ b/src/nm-hal-manager.c @@ -35,7 +35,8 @@ struct _NMHalManager { /* Device creators */ typedef NMDevice *(*NMDeviceCreatorFn) (NMHalManager *manager, - const char *udi); + const char *udi, + gboolean managed); typedef struct { char *device_type_name; @@ -109,7 +110,7 @@ is_wired_device (NMHalManager *manager, const char *udi) } static NMDevice * -wired_device_creator (NMHalManager *manager, const char *udi) +wired_device_creator (NMHalManager *manager, const char *udi, gboolean managed) { NMDevice *device; char *iface; @@ -122,7 +123,7 @@ wired_device_creator (NMHalManager *manager, const char *udi) } driver = nm_get_device_driver_name (manager->hal_ctx, udi); - device = (NMDevice *) nm_device_802_3_ethernet_new (udi, iface, driver); + device = (NMDevice *) nm_device_802_3_ethernet_new (udi, iface, driver, managed); libhal_free_string (iface); g_free (driver); @@ -152,7 +153,7 @@ is_wireless_device (NMHalManager *manager, const char *udi) } static NMDevice * -wireless_device_creator (NMHalManager *manager, const char *udi) +wireless_device_creator (NMHalManager *manager, const char *udi, gboolean managed) { NMDevice *device; char *iface; @@ -165,7 +166,7 @@ wireless_device_creator (NMHalManager *manager, const char *udi) } driver = nm_get_device_driver_name (manager->hal_ctx, udi); - device = (NMDevice *) nm_device_802_11_wireless_new (udi, iface, driver); + device = (NMDevice *) nm_device_802_11_wireless_new (udi, iface, driver, managed); libhal_free_string (iface); g_free (driver); @@ -194,7 +195,7 @@ is_modem_device (NMHalManager *manager, const char *udi) } static NMDevice * -modem_device_creator (NMHalManager *manager, const char *udi) +modem_device_creator (NMHalManager *manager, const char *udi, gboolean managed) { char *serial_device; char *parent_udi; @@ -246,9 +247,9 @@ modem_device_creator (NMHalManager *manager, const char *udi) } if (type_gsm) - device = (NMDevice *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name); + device = (NMDevice *) nm_gsm_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed); else if (type_cdma) - device = (NMDevice *) nm_cdma_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name); + device = (NMDevice *) nm_cdma_device_new (udi, serial_device + strlen ("/dev/"), NULL, driver_name, managed); out: libhal_free_string (serial_device); @@ -264,8 +265,8 @@ register_built_in_creators (NMHalManager *manager) /* Wired device */ creator = g_slice_new0 (DeviceCreator); - creator->device_type_name = g_strdup ("wired Ethernet (802.3)"); - creator->capability_str = g_strdup ("net"); + creator->device_type_name = g_strdup ("Ethernet"); + creator->capability_str = g_strdup ("net.80203"); creator->is_device_fn = is_wired_device; creator->creator_fn = wired_device_creator; manager->device_creators = g_slist_append (manager->device_creators, creator); @@ -273,7 +274,7 @@ register_built_in_creators (NMHalManager *manager) /* Wireless device */ creator = g_slice_new0 (DeviceCreator); creator->device_type_name = g_strdup ("wireless (802.11)"); - creator->capability_str = g_strdup ("net"); + creator->capability_str = g_strdup ("net.80211"); creator->is_device_fn = is_wireless_device; creator->creator_fn = wireless_device_creator; manager->device_creators = g_slist_append (manager->device_creators, creator); @@ -287,28 +288,28 @@ register_built_in_creators (NMHalManager *manager) manager->device_creators = g_slist_append (manager->device_creators, creator); } -static NMDevice * +static void create_device_and_add_to_list (NMHalManager *manager, DeviceCreator *creator, const char *udi) { NMDevice *dev; + gboolean managed; /* Make sure the device is not already in the device list */ if ((dev = nm_manager_get_device_by_udi (manager->nm_manager, udi))) - return NULL; + return; - dev = creator->creator_fn (manager, udi); + managed = nm_manager_is_udi_managed (manager->nm_manager, udi); + dev = creator->creator_fn (manager, udi, managed); if (dev) { - nm_info ("Now managing %s device '%s'.", - creator->device_type_name, - nm_device_get_iface (dev)); + nm_info ("Found new %s device '%s'.", + creator->device_type_name, + nm_device_get_iface (dev)); nm_manager_add_device (manager->nm_manager, dev); g_object_unref (dev); } - - return dev; } static void diff --git a/src/nm-manager.c b/src/nm-manager.c index 6a0fd80b8d..0ed24a371a 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -8,6 +8,7 @@ #include "nm-dbus-manager.h" #include "nm-vpn-manager.h" #include "nm-device-interface.h" +#include "nm-device-private.h" #include "nm-device-802-11-wireless.h" #include "NetworkManagerSystem.h" #include "nm-properties-changed-signal.h" @@ -70,6 +71,8 @@ typedef struct { GHashTable *system_connections; DBusGProxy *system_proxy; + DBusGProxy *system_props_proxy; + GSList *unmanaged_udis; PendingConnectionInfo *pending_connection_info; gboolean wireless_enabled; @@ -118,6 +121,7 @@ typedef enum { NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + NM_MANAGER_ERROR_UNMANAGED_DEVICE, NM_MANAGER_ERROR_INVALID_SERVICE, NM_MANAGER_ERROR_SYSTEM_CONNECTION, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -150,6 +154,8 @@ nm_manager_error_get_type (void) ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "UnknownConnection"), /* Unknown device. */ ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_DEVICE, "UnknownDevice"), + /* Unmanaged device. */ + ENUM_ENTRY (NM_MANAGER_ERROR_UNMANAGED_DEVICE, "UnmanagedDevice"), /* Invalid settings service (not a recognized system or user * settings service name) */ @@ -294,6 +300,13 @@ dispose (GObject *object) g_hash_table_destroy (priv->system_connections); priv->system_connections = NULL; + if (priv->system_props_proxy) { + g_object_unref (priv->system_props_proxy); + priv->system_props_proxy = NULL; + } + g_slist_foreach (priv->unmanaged_udis, (GFunc) g_free, NULL); + g_slist_free (priv->unmanaged_udis); + if (priv->poke_id) { g_source_remove (priv->poke_id); priv->poke_id = 0; @@ -903,6 +916,126 @@ query_connections (NMManager *manager, G_TYPE_INVALID); } +static void +handle_unmanaged_devices (NMManager *manager, GPtrArray *ops) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + int i; + GSList *unmanaged = NULL, *iter; + + g_slist_foreach (priv->unmanaged_udis, (GFunc) g_free, NULL); + g_slist_free (priv->unmanaged_udis); + priv->unmanaged_udis = NULL; + + /* Mark unmanaged devices */ + for (i = 0; ops && (i < ops->len); i++) { + NMDevice *device; + const char *udi = g_ptr_array_index (ops, i); + + priv->unmanaged_udis = g_slist_prepend (priv->unmanaged_udis, g_strdup (udi)); + + device = nm_manager_get_device_by_udi (manager, udi); + if (device) { + unmanaged = g_slist_prepend (unmanaged, device); + nm_device_set_managed (device, FALSE); + } + } + + /* Mark managed devices */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMDevice *device = NM_DEVICE (iter->data); + + if (!g_slist_find (unmanaged, device)) + nm_device_set_managed (device, TRUE); + } + + g_slist_free (unmanaged); +} + +static void +system_settings_properties_changed_cb (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data) +{ + NMManager *manager = NM_MANAGER (user_data); + GValue *value; + + value = g_hash_table_lookup (properties, "UnmanagedDevices"); + if (!value || !G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) + return; + + handle_unmanaged_devices (manager, g_value_get_boxed (value)); +} + +static void +system_settings_get_unmanaged_devices_cb (DBusGProxy *proxy, + DBusGProxyCall *call_id, + gpointer user_data) +{ + NMManager *manager = NM_MANAGER (user_data); + GError *error = NULL; + GValue value = { 0, }; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_VALUE, &value, + G_TYPE_INVALID)) { + nm_warning ("%s: Error getting unmanaged devices from the system " + "settings service: (%d) %s", + __func__, error->code, error->message); + g_error_free (error); + return; + } + + if (!G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) + return; + + handle_unmanaged_devices (manager, g_value_get_boxed (&value)); + g_object_unref (proxy); +} + +static void +query_unmanaged_devices (NMManager *manager) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + DBusGConnection *g_connection; + DBusGProxy *get_proxy; + + g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + if (!priv->system_props_proxy) { + priv->system_props_proxy = dbus_g_proxy_new_for_name (g_connection, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + "org.freedesktop.NetworkManagerSettings.System"); + if (!priv->system_props_proxy) { + nm_warning ("Error: could not init system settings properties proxy."); + return; + } + + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->system_props_proxy, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->system_props_proxy, "PropertiesChanged", + G_CALLBACK (system_settings_properties_changed_cb), + manager, + NULL); + } + + /* Get unmanaged devices */ + get_proxy = dbus_g_proxy_new_for_name (g_connection, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + "org.freedesktop.DBus.Properties"); + + dbus_g_proxy_begin_call (get_proxy, "Get", + system_settings_get_unmanaged_devices_cb, + manager, + NULL, + G_TYPE_STRING, "org.freedesktop.NetworkManagerSettings.System", + G_TYPE_STRING, "UnmanagedDevices", + G_TYPE_INVALID); +} + static void nm_manager_name_owner_changed (NMDBusManager *mgr, const char *name, @@ -931,11 +1064,17 @@ nm_manager_name_owner_changed (NMDBusManager *mgr, } /* System Settings service appeared, update stuff */ + query_unmanaged_devices (manager); query_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); } else { /* System Settings service disappeared, throw them away (?) */ nm_manager_connections_destroy (manager, NM_CONNECTION_SCOPE_SYSTEM); + if (priv->system_props_proxy) { + g_object_unref (priv->system_props_proxy); + priv->system_props_proxy = NULL; + } + if (priv->poke_id) g_source_remove (priv->poke_id); @@ -984,6 +1123,7 @@ initial_get_connections (gpointer user_data) if (nm_dbus_manager_name_has_owner (nm_dbus_manager_get (), NM_DBUS_SERVICE_SYSTEM_SETTINGS)) { + query_unmanaged_devices (manager); query_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); } else { /* Try to activate the system settings daemon */ @@ -1084,33 +1224,24 @@ manager_set_wireless_enabled (NMManager *manager, gboolean enabled) if (priv->sleeping) return; - /* Tear down all wireless devices */ + /* enable/disable wireless devices as required */ for (iter = priv->devices; iter; iter = iter->next) { - if (NM_IS_DEVICE_802_11_WIRELESS (iter->data)) { - if (enabled) - nm_device_bring_up (NM_DEVICE (iter->data), FALSE); - else - nm_device_bring_down (NM_DEVICE (iter->data), FALSE); - } + if (NM_IS_DEVICE_802_11_WIRELESS (iter->data)) + nm_device_802_11_wireless_set_enabled (NM_DEVICE_802_11_WIRELESS (iter->data), enabled); } } -static void -manager_device_added (NMManager *manager, NMDevice *device) -{ - g_signal_emit (manager, signals[DEVICE_ADDED], 0, device); -} - static void manager_device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); - switch (nm_device_interface_get_state (device)) { + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_FAILED: - case NM_DEVICE_STATE_CANCELLED: - case NM_DEVICE_STATE_DISCONNECTED: g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); break; default: @@ -1197,33 +1328,22 @@ nm_manager_add_device (NMManager *manager, NMDevice *device) g_signal_connect (device, "hidden-ap-found", G_CALLBACK (manager_hidden_ap_found), manager); - } - if (!priv->sleeping) { - if (!NM_IS_DEVICE_802_11_WIRELESS (device) || priv->wireless_enabled) { - nm_device_bring_down (device, TRUE); - nm_device_bring_up (device, TRUE); - } + /* Set initial rfkill state */ + nm_device_802_11_wireless_set_enabled (NM_DEVICE_802_11_WIRELESS (device), priv->wireless_enabled); } - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); - nm_info ("(%s): exported as %s", - nm_device_get_iface (device), - nm_device_get_udi (device)); + nm_device_get_iface (device), + nm_device_get_udi (device)); + dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), nm_device_get_udi (device), G_OBJECT (device)); - manager_device_added (manager, device); + g_signal_emit (manager, signals[DEVICE_ADDED], 0, device); } -static void -manager_device_removed (NMManager *manager, NMDevice *device) -{ - g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); -} - void nm_manager_remove_device (NMManager *manager, NMDevice *device, gboolean deactivate) { @@ -1239,13 +1359,12 @@ nm_manager_remove_device (NMManager *manager, NMDevice *device, gboolean deactiv if (iter->data == device) { priv->devices = g_slist_delete_link (priv->devices, iter); - nm_device_bring_down (device, FALSE); - if (deactivate) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); + if (nm_device_get_managed (device)) + nm_device_bring_down (device, FALSE); g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); - manager_device_removed (manager, device); + g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_unref (device); break; } @@ -1362,10 +1481,8 @@ internal_activate_device (NMManager *manager, if (!nm_device_interface_check_connection_compatible (dev_iface, connection, error)) return NULL; - if (nm_device_get_act_request (device)) { - nm_device_interface_deactivate (dev_iface); - g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); - } + if (nm_device_get_act_request (device)) + nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); req = nm_act_request_new (connection, specific_object, user_requested, (gpointer) device); success = nm_device_interface_activate (dev_iface, req, error); @@ -1455,6 +1572,8 @@ nm_manager_activate_connection (NMManager *manager, error); g_object_unref (vpn_manager); } else { + NMDeviceState state; + /* Device-based connection */ device = nm_manager_get_device_by_path (manager, device_path); if (!device) { @@ -1464,6 +1583,14 @@ nm_manager_activate_connection (NMManager *manager, return NULL; } + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); + if (state < NM_DEVICE_STATE_DISCONNECTED) { + g_set_error (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE, + "%s", "Device not managed by NetworkManager"); + return NULL; + } + path = (char *) internal_activate_device (manager, device, connection, @@ -1613,8 +1740,7 @@ nm_manager_deactivate_connection (NMManager *manager, continue; if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) { - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); - g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); + nm_device_state_changed (device, NM_DEVICE_STATE_DISCONNECTED); success = TRUE; goto done; } @@ -1701,8 +1827,16 @@ nm_manager_sleep (NMManager *manager, gboolean sleep) /* Just deactivate and down all devices from the device list, * we'll remove them in 'wake' for speed's sake. */ - for (iter = priv->devices; iter; iter = iter->next) - nm_device_bring_down (NM_DEVICE (iter->data), FALSE); + for (iter = priv->devices; iter; iter = iter->next) { + NMDeviceState state; + + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (iter->data)); + if (state >= NM_DEVICE_STATE_UNAVAILABLE) { + nm_device_bring_down (NM_DEVICE (iter->data), FALSE); + if (state >= NM_DEVICE_STATE_DISCONNECTED) + nm_device_state_changed (NM_DEVICE (iter->data), NM_DEVICE_STATE_DISCONNECTED); + } + } } else { nm_info ("Waking up from sleep."); @@ -1834,3 +1968,19 @@ nm_manager_get_active_connections_by_connection (NMManager *manager, return get_active_connections (manager, connection); } +gboolean +nm_manager_is_udi_managed (NMManager *manager, const char *udi) +{ + NMManagerPrivate *priv; + GSList *iter; + + g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE); + + priv = NM_MANAGER_GET_PRIVATE (manager); + for (iter = priv->unmanaged_udis; iter; iter = g_slist_next (iter)) { + if (!strcmp (udi, iter->data)) + return FALSE; + } + return TRUE; +} + diff --git a/src/nm-manager.h b/src/nm-manager.h index bf19a0043c..1401fe95f7 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -61,6 +61,7 @@ void nm_manager_remove_device (NMManager *manager, NMDevice *device, gboolean de GSList *nm_manager_get_devices (NMManager *manager); NMDevice *nm_manager_get_device_by_path (NMManager *manager, const char *path); NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi); +gboolean nm_manager_is_udi_managed (NMManager *manager, const char *udi); const char * nm_manager_activate_connection (NMManager *manager, NMConnection *connection, diff --git a/test/nm-tool.c b/test/nm-tool.c index 08e984c65b..5c852a571d 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -169,6 +169,30 @@ ip4_address_as_string (guint32 ip) return g_strdup (ip_string); } +static const char * +get_dev_state_string (NMDeviceState state) +{ + if (state == NM_DEVICE_STATE_UNMANAGED) + return "unmanaged"; + else if (state == NM_DEVICE_STATE_UNAVAILABLE) + return "unavailable"; + else if (state == NM_DEVICE_STATE_DISCONNECTED) + return "disconnected"; + else if (state == NM_DEVICE_STATE_PREPARE) + return "connecting (prepare)"; + else if (state == NM_DEVICE_STATE_CONFIG) + return "connecting (configuring)"; + else if (state == NM_DEVICE_STATE_NEED_AUTH) + return "connecting (need authentication)"; + else if (state == NM_DEVICE_STATE_IP_CONFIG) + return "connecting (getting IP configuration)"; + else if (state == NM_DEVICE_STATE_ACTIVATED) + return "connected"; + else if (state == NM_DEVICE_STATE_FAILED) + return "connection failed"; + return "unknown"; +} + static void detail_device (gpointer data, gpointer user_data) { @@ -192,10 +216,7 @@ detail_device (gpointer data, gpointer user_data) print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)"); - if (state == NM_DEVICE_STATE_ACTIVATED) - print_string ("Active", "yes"); - else - print_string ("Active", "no"); + print_string ("State", get_dev_state_string (state)); tmp = NULL; if (NM_IS_DEVICE_802_3_ETHERNET (device))