core: add IP configuration for unmanaged devices

Use NMPlatform to read the IP address/route configuration of unmanaged
devices, and export that via D-Bus like we do with NM-generated IP
configs.
This commit is contained in:
Dan Winship
2013-04-04 10:20:24 -04:00
parent 669fdf9131
commit ab7ebead2c
8 changed files with 239 additions and 28 deletions

View File

@@ -549,6 +549,10 @@ show_device_info (gpointer data, gpointer user_data)
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
gboolean was_output = FALSE;
NMIP4Config *cfg4;
NMIP6Config *cfg6;
NMDHCP4Config *dhcp4;
NMDHCP6Config *dhcp6;
if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0)
fields_str = fields_common;
@@ -813,28 +817,26 @@ show_device_info (gpointer data, gpointer user_data)
#endif
/* IP configuration info */
if (state == NM_DEVICE_STATE_ACTIVATED) {
NMIP4Config *cfg4 = nm_device_get_ip4_config (device);
NMIP6Config *cfg6 = nm_device_get_ip6_config (device);
NMDHCP4Config *dhcp4 = nm_device_get_dhcp4_config (device);
NMDHCP6Config *dhcp6 = nm_device_get_dhcp6_config (device);
cfg4 = nm_device_get_ip4_config (device);
cfg6 = nm_device_get_ip6_config (device);
dhcp4 = nm_device_get_dhcp4_config (device);
dhcp6 = nm_device_get_dhcp6_config (device);
/* IP4 */
if (cfg4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[7].name))
was_output = print_ip4_config (cfg4, nmc, nmc_fields_dev_show_sections[7].name);
/* IP4 */
if (cfg4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[7].name))
was_output = print_ip4_config (cfg4, nmc, nmc_fields_dev_show_sections[7].name);
/* DHCP4 */
if (dhcp4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[8].name))
was_output = print_dhcp4_config (dhcp4, nmc, nmc_fields_dev_show_sections[8].name);
/* DHCP4 */
if (dhcp4 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[8].name))
was_output = print_dhcp4_config (dhcp4, nmc, nmc_fields_dev_show_sections[8].name);
/* IP6 */
if (cfg6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[9].name))
was_output = print_ip6_config (cfg6, nmc, nmc_fields_dev_show_sections[9].name);
/* IP6 */
if (cfg6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[9].name))
was_output = print_ip6_config (cfg6, nmc, nmc_fields_dev_show_sections[9].name);
/* DHCP6 */
if (dhcp6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[10].name))
was_output = print_dhcp6_config (dhcp6, nmc, nmc_fields_dev_show_sections[10].name);
}
/* DHCP6 */
if (dhcp6 && !strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[10].name))
was_output = print_dhcp6_config (dhcp6, nmc, nmc_fields_dev_show_sections[10].name);
/* Bond-specific information */
if ((NM_IS_DEVICE_BOND (device))) {

View File

@@ -68,6 +68,7 @@
#include "nm-dispatcher.h"
#include "nm-config-device.h"
#include "nm-config.h"
#include "nm-platform.h"
static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context);
@@ -169,6 +170,7 @@ typedef struct {
NMDeviceState state;
NMDeviceStateReason state_reason;
QueuedState queued_state;
guint queued_ip_config_id;
char * udi;
char * path;
@@ -312,10 +314,32 @@ static const char *state_to_string (NMDeviceState state);
static void carrier_changed (GObject *object, GParamSpec *param, gpointer user_data);
static void carrier_action_defer_clear (NMDevice *self);
static void nm_device_queued_ip_config_change_clear (NMDevice *self);
static void update_ip_config (NMDevice *self);
static void device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, gpointer user_data);
static const char const *platform_ip_signals[] = {
NM_PLATFORM_IP4_ADDRESS_ADDED,
NM_PLATFORM_IP4_ADDRESS_CHANGED,
NM_PLATFORM_IP4_ADDRESS_REMOVED,
NM_PLATFORM_IP4_ROUTE_ADDED,
NM_PLATFORM_IP4_ROUTE_CHANGED,
NM_PLATFORM_IP4_ROUTE_REMOVED,
NM_PLATFORM_IP6_ADDRESS_ADDED,
NM_PLATFORM_IP6_ADDRESS_CHANGED,
NM_PLATFORM_IP6_ADDRESS_REMOVED,
NM_PLATFORM_IP6_ROUTE_ADDED,
NM_PLATFORM_IP6_ROUTE_CHANGED,
NM_PLATFORM_IP6_ROUTE_REMOVED,
};
static const int n_platform_ip_signals = G_N_ELEMENTS (platform_ip_signals);
static void
nm_device_init (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMPlatform *platform;
int i;
priv->type = NM_DEVICE_TYPE_UNKNOWN;
priv->capabilities = NM_DEVICE_CAP_NONE;
@@ -325,6 +349,13 @@ nm_device_init (NMDevice *self)
priv->rfkill_type = RFKILL_TYPE_UNKNOWN;
priv->autoconnect = DEFAULT_AUTOCONNECT;
priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
/* Watch for external IP config changes */
platform = nm_platform_get ();
for (i = 0; i < n_platform_ip_signals; i++) {
g_signal_connect (platform, platform_ip_signals[i],
G_CALLBACK (device_ip_changed), self);
}
}
static void
@@ -478,6 +509,7 @@ constructor (GType type,
update_accept_ra_save (dev);
update_ip6_privacy_save (dev);
update_ip_config (dev);
priv->initialized = TRUE;
return object;
@@ -3973,6 +4005,7 @@ nm_device_deactivate (NMDevice *self, NMDeviceStateReason reason)
/* Clear any queued transitions */
nm_device_queued_state_clear (self);
nm_device_queued_ip_config_change_clear (self);
priv->ip4_state = priv->ip6_state = IP_NONE;
@@ -4446,6 +4479,7 @@ dispose (GObject *object)
NMDevice *self = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
gboolean take_down = TRUE;
NMPlatform *platform;
if (priv->disposed || !priv->initialized)
goto out;
@@ -4479,6 +4513,7 @@ dispose (GObject *object)
/* Clear any queued transitions */
nm_device_queued_state_clear (self);
nm_device_queued_ip_config_change_clear (self);
/* Clean up and stop DHCP */
dhcp4_cleanup (self, take_down, FALSE);
@@ -4541,6 +4576,9 @@ dispose (GObject *object)
clear_act_request (self);
platform = nm_platform_get ();
g_signal_handlers_disconnect_by_func (platform, G_CALLBACK (device_ip_changed), self);
out:
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
}
@@ -4672,9 +4710,16 @@ set_property (GObject *object, guint prop_id,
}
static gboolean
_is_connected (NMDeviceState state)
has_ip_config (NMDevice *self)
{
return (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (!priv->ip4_config && !priv->ip6_config)
return FALSE;
return ( ( priv->state >= NM_DEVICE_STATE_IP_CONFIG
&& priv->state <= NM_DEVICE_STATE_DEACTIVATING)
|| (priv->state == NM_DEVICE_STATE_UNMANAGED));
}
static void
@@ -4683,14 +4728,11 @@ get_property (GObject *object, guint prop_id,
{
NMDevice *self = NM_DEVICE (object);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDeviceState state;
const char *ac_path = NULL;
GPtrArray *array;
GHashTableIter iter;
NMConnection *connection;
state = nm_device_get_state (self);
switch (prop_id) {
case PROP_UDI:
g_value_set_string (value, priv->udi);
@@ -4699,7 +4741,7 @@ get_property (GObject *object, guint prop_id,
g_value_set_string (value, priv->iface);
break;
case PROP_IP_IFACE:
if (_is_connected (state))
if (has_ip_config (self))
g_value_set_string (value, nm_device_get_ip_iface (self));
else
g_value_set_string (value, NULL);
@@ -4723,25 +4765,25 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, priv->ip4_address);
break;
case PROP_IP4_CONFIG:
if (_is_connected (state) && priv->ip4_config)
if (has_ip_config (self) && priv->ip4_config)
g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config));
else
g_value_set_boxed (value, "/");
break;
case PROP_DHCP4_CONFIG:
if (_is_connected (state) && priv->dhcp4_client)
if (has_ip_config (self) && priv->dhcp4_client)
g_value_set_boxed (value, nm_dhcp4_config_get_dbus_path (priv->dhcp4_config));
else
g_value_set_boxed (value, "/");
break;
case PROP_IP6_CONFIG:
if (_is_connected (state) && priv->ip6_config)
if (has_ip_config (self) && priv->ip6_config)
g_value_set_boxed (value, nm_ip6_config_get_dbus_path (priv->ip6_config));
else
g_value_set_boxed (value, "/");
break;
case PROP_DHCP6_CONFIG:
if (_is_connected (state) && priv->dhcp6_client)
if (has_ip_config (self) && priv->dhcp6_client)
g_value_set_boxed (value, nm_dhcp6_config_get_dbus_path (priv->dhcp6_config));
else
g_value_set_boxed (value, "/");
@@ -5517,6 +5559,78 @@ nm_device_get_state (NMDevice *device)
return NM_DEVICE_GET_PRIVATE (device)->state;
}
static void
update_ip_config (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
NMIP4Config *ip4_config;
NMIP6Config *ip6_config;
int ifindex;
if (priv->state != NM_DEVICE_STATE_UNMANAGED)
return;
ifindex = nm_device_get_ip_ifindex (self);
if (!ifindex)
return;
ip4_config = nm_ip4_config_new_for_interface (ifindex);
ip6_config = nm_ip6_config_new_for_interface (ifindex);
nm_device_set_ip4_config (self, ip4_config, TRUE, &ignored);
nm_device_set_ip6_config (self, ip6_config, TRUE, &ignored);
if (ip4_config)
g_object_unref (ip4_config);
if (ip6_config)
g_object_unref (ip6_config);
}
static gboolean
queued_ip_config_change (gpointer user_data)
{
NMDevice *self = NM_DEVICE (user_data);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
/* Wait for any queued state changes */
if (priv->queued_state.id)
return TRUE;
priv->queued_ip_config_id = 0;
update_ip_config (self);
return FALSE;
}
static void
device_ip_changed (NMPlatform *platform, int ifindex, gpointer platform_object, gpointer user_data)
{
NMDevice *self = user_data;
if (nm_device_get_ip_ifindex (self) == ifindex) {
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (!priv->queued_ip_config_id)
priv->queued_ip_config_id = g_idle_add (queued_ip_config_change, self);
nm_log_dbg (LOGD_DEVICE, "(%s): queued IP config change",
nm_device_get_iface (self));
}
}
void
nm_device_queued_ip_config_change_clear (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->queued_ip_config_id) {
nm_log_dbg (LOGD_DEVICE, "(%s): clearing queued IP config change",
nm_device_get_iface (self));
g_source_remove (priv->queued_ip_config_id);
priv->queued_ip_config_id = 0;
}
}
gboolean
nm_device_get_managed (NMDevice *device)
{

View File

@@ -297,6 +297,8 @@ void nm_device_queue_state (NMDevice *self,
NMDeviceState state,
NMDeviceStateReason reason);
void nm_device_queue_ip_config_change (NMDevice *self);
gboolean nm_device_get_firmware_missing (NMDevice *self);
void nm_device_activate (NMDevice *device, NMActRequest *req);

View File

@@ -27,6 +27,7 @@
#include "NetworkManager.h"
#include "NetworkManagerUtils.h"
#include "nm-setting-ip4-config.h"
#include "nm-platform.h"
#include "nm-utils.h"
#include <netlink/route/addr.h>
@@ -97,6 +98,49 @@ nm_ip4_config_new (void)
return (NMIP4Config *) g_object_new (NM_TYPE_IP4_CONFIG, NULL);
}
NMIP4Config *
nm_ip4_config_new_for_interface (int ifindex)
{
NMIP4Config *ip4;
GArray *addrs_array, *routes_array;
NMPlatformIP4Address *addrs;
NMPlatformIP4Route *routes;
NMIP4Address *addr;
NMIP4Route *route;
int i;
addrs_array = nm_platform_ip4_address_get_all (ifindex);
if (addrs_array->len == 0) {
g_array_unref (addrs_array);
return NULL;
}
ip4 = nm_ip4_config_new ();
addrs = (NMPlatformIP4Address *)addrs_array->data;
for (i = 0; i < addrs_array->len; i++) {
addr = nm_ip4_address_new ();
nm_ip4_address_set_address (addr, addrs[i].address);
nm_ip4_address_set_prefix (addr, addrs[i].plen);
nm_ip4_config_take_address (ip4, addr);
}
g_array_unref (addrs_array);
routes_array = nm_platform_ip4_route_get_all (ifindex);
routes = (NMPlatformIP4Route *)routes_array->data;
for (i = 0; i < routes_array->len; i++) {
route = nm_ip4_route_new ();
nm_ip4_route_set_dest (route, routes[i].network);
nm_ip4_route_set_prefix (route, routes[i].plen);
nm_ip4_route_set_next_hop (route, routes[i].gateway);
nm_ip4_route_set_metric (route, routes[i].metric);
nm_ip4_config_take_route (ip4, route);
}
g_array_unref (routes_array);
return ip4;
}
void
nm_ip4_config_export (NMIP4Config *config)
{

View File

@@ -51,6 +51,8 @@ GType nm_ip4_config_get_type (void);
NMIP4Config * nm_ip4_config_new (void);
NMIP4Config * nm_ip4_config_new_for_interface (int ifindex);
void nm_ip4_config_export (NMIP4Config *config);
const char * nm_ip4_config_get_dbus_path (NMIP4Config *config);

View File

@@ -27,6 +27,7 @@
#include "NetworkManager.h"
#include "NetworkManagerUtils.h"
#include "nm-setting-ip6-config.h"
#include "nm-platform.h"
#include "nm-utils.h"
#include <netlink/route/addr.h>
@@ -94,6 +95,49 @@ nm_ip6_config_new (void)
return (NMIP6Config *) g_object_new (NM_TYPE_IP6_CONFIG, NULL);
}
NMIP6Config *
nm_ip6_config_new_for_interface (int ifindex)
{
NMIP6Config *ip6;
GArray *addrs_array, *routes_array;
NMPlatformIP6Address *addrs;
NMPlatformIP6Route *routes;
NMIP6Address *addr;
NMIP6Route *route;
int i;
addrs_array = nm_platform_ip6_address_get_all (ifindex);
if (addrs_array->len == 0) {
g_array_unref (addrs_array);
return NULL;
}
ip6 = nm_ip6_config_new ();
addrs = (NMPlatformIP6Address *)addrs_array->data;
for (i = 0; i < addrs_array->len; i++) {
addr = nm_ip6_address_new ();
nm_ip6_address_set_address (addr, &addrs[i].address);
nm_ip6_address_set_prefix (addr, addrs[i].plen);
nm_ip6_config_take_address (ip6, addr);
}
g_array_unref (addrs_array);
routes_array = nm_platform_ip6_route_get_all (ifindex);
routes = (NMPlatformIP6Route *)routes_array->data;
for (i = 0; i < routes_array->len; i++) {
route = nm_ip6_route_new ();
nm_ip6_route_set_dest (route, &routes[i].network);
nm_ip6_route_set_prefix (route, routes[i].plen);
nm_ip6_route_set_next_hop (route, &routes[i].gateway);
nm_ip6_route_set_metric (route, routes[i].metric);
nm_ip6_config_take_route (ip6, route);
}
g_array_unref (routes_array);
return ip6;
}
void
nm_ip6_config_export (NMIP6Config *config)
{

View File

@@ -50,6 +50,8 @@ GType nm_ip6_config_get_type (void);
NMIP6Config * nm_ip6_config_new (void);
NMIP6Config * nm_ip6_config_new_for_interface (int ifindex);
void nm_ip6_config_export (NMIP6Config *config);
const char * nm_ip6_config_get_dbus_path (NMIP6Config *config);

View File

@@ -29,6 +29,7 @@ test_dhcp_options_LDADD = \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/src/dhcp-manager/libdhcp-manager.la \
$(top_builddir)/src/libtest-dhcp.la \
$(top_builddir)/src/platform/libnm-platform.la \
$(GLIB_LIBS) \
$(DBUS_LIBS)