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:
@@ -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,11 +817,10 @@ 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))
|
||||
@@ -834,7 +837,6 @@ show_device_info (gpointer data, gpointer user_data)
|
||||
/* 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))) {
|
||||
|
134
src/nm-device.c
134
src/nm-device.c
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user