Commit 51503b2d authored by Dan Williams's avatar Dan Williams

2008-05-06 Dan Williams <dcbw@redhat.com>

	* src/dhcp-manager/nm-dhcp-manager.c
		- (nm_dhcp_manager_get_ip4_config): clean up; update for changes to
			NMIP4Config to support multiple IP addresses

	* src/NetworkManagerUtils.c
		- (nm_utils_merge_ip4_config): update for multiple IP addresses

	* src/nm-ip4-config.c
	  src/nm-ip4-config.h
		- Store a list of IPv4 address/netmask/gateway tuples
		- (nm_ip4_config_get_gateway, nm_ip4_config_set_gateway,
		   nm_ip4_config_get_netmask, nm_ip4_config_set_netmask,
		   nm_ip4_config_get_broadcast, nm_ip4_config_set_broadcast,
		   nm_ip4_config_set_address): remove
		- (nm_ip4_config_take_address, nm_ip4_config_add_address,
		   nm_ip4_config_replace_address, nm_ip4_config_get_num_addresses):
			new functions; handle multiple IPv4 addresses

	* src/nm-device.c
	  src/ppp-manager/nm-ppp-manager.c
	  src/vpn-manager/nm-vpn-connection.c
	  src/NetworkManagerPolicy.c
	  test/nm-tool.c
	  libnm-glib/libnm-glib-test.c
		- update for changes to NMIP4Config for multiple IPv4 addresses

	* src/NetworkManagerSystem.c
		- (nm_system_device_set_ip4_route): don't add the route if any address
			is on the same subnet as the destination
		- (check_one_address): ignore the exact match, just match family and
			interface index
		- (add_ip4_addresses): add all IPv4 addresses in an NMIP4Config to
			an interface
		- (nm_system_device_set_from_ip4_config): use add_ip4_addresses()
		- (nm_system_vpn_device_set_from_ip4_config): use add_ip4_addresses()

	* introspection/nm-ip4-config.xml
		- Remove 'address', 'gateway', 'netmask', and 'broadcast' properties
		- Add 'addresses' property which is an array of (uuu) tuples of
			address/netmask/gateway

	* libnm-util/nm-setting-ip4-config.c
		- (set_property): use ip-address <-> GValue converters from nm-utils.c

	* libnm-glib/nm-ip4-config.c
	  libnm-glib/nm-ip4-config.h
		- Handle D-Bus interface changes to support multiple IP addresses



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3637 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
parent 3cbc2453
2008-05-06 Dan Williams <dcbw@redhat.com>
* src/dhcp-manager/nm-dhcp-manager.c
- (nm_dhcp_manager_get_ip4_config): clean up; update for changes to
NMIP4Config to support multiple IP addresses
* src/NetworkManagerUtils.c
- (nm_utils_merge_ip4_config): update for multiple IP addresses
* src/nm-ip4-config.c
src/nm-ip4-config.h
- Store a list of IPv4 address/netmask/gateway tuples
- (nm_ip4_config_get_gateway, nm_ip4_config_set_gateway,
nm_ip4_config_get_netmask, nm_ip4_config_set_netmask,
nm_ip4_config_get_broadcast, nm_ip4_config_set_broadcast,
nm_ip4_config_set_address): remove
- (nm_ip4_config_take_address, nm_ip4_config_add_address,
nm_ip4_config_replace_address, nm_ip4_config_get_num_addresses):
new functions; handle multiple IPv4 addresses
* src/nm-device.c
src/ppp-manager/nm-ppp-manager.c
src/vpn-manager/nm-vpn-connection.c
src/NetworkManagerPolicy.c
test/nm-tool.c
libnm-glib/libnm-glib-test.c
- update for changes to NMIP4Config for multiple IPv4 addresses
* src/NetworkManagerSystem.c
- (nm_system_device_set_ip4_route): don't add the route if any address
is on the same subnet as the destination
- (check_one_address): ignore the exact match, just match family and
interface index
- (add_ip4_addresses): add all IPv4 addresses in an NMIP4Config to
an interface
- (nm_system_device_set_from_ip4_config): use add_ip4_addresses()
- (nm_system_vpn_device_set_from_ip4_config): use add_ip4_addresses()
* introspection/nm-ip4-config.xml
- Remove 'address', 'gateway', 'netmask', and 'broadcast' properties
- Add 'addresses' property which is an array of (uuu) tuples of
address/netmask/gateway
* libnm-util/nm-setting-ip4-config.c
- (set_property): use ip-address <-> GValue converters from nm-utils.c
* libnm-glib/nm-ip4-config.c
libnm-glib/nm-ip4-config.h
- Handle D-Bus interface changes to support multiple IP addresses
2008-05-06 Dan Williams <dcbw@redhat.com>
* libnm-util/nm-utils.c
libnm-util/nm-utils.h
- (nm_utils_ip4_addresses_from_gvalue,
nm_utils_ip4_addresses_to_gvalue): new functions
2008-05-06 Tambet Ingo <tambet@gmail.com>
* libnm-glib/nm-dbus-settings.c (fetch_connections_done): Don't leak
......
......@@ -2,17 +2,8 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.IP4Config">
<property name="Address" type="u" access="read">
<tp:docstring>IPv4 address. FIXME: what about multiple addresses?</tp:docstring>
</property>
<property name="Gateway" type="u" access="read">
<tp:docstring>Default gateway.</tp:docstring>
</property>
<property name="Netmask" type="u" access="read">
<tp:docstring>Network mask of this network.</tp:docstring>
</property>
<property name="Broadcast" type="u" access="read">
<tp:docstring>Broadcast address of this network.</tp:docstring>
<property name="Addresses" type="aau" access="read">
<tp:docstring>Tuples of IPv4 address/netmask/gateway. The gateway is optional, if not given should be 0.</tp:docstring>
</property>
<property name="Hostname" type="s" access="read">
<tp:docstring>The hostname associated with this IPv4 address. FIXME: what about multiple hostnames?</tp:docstring>
......
......@@ -13,6 +13,7 @@
#include "nm-device-802-11-wireless.h"
#include "nm-utils.h"
#include "nm-active-connection.h"
#include "nm-setting-ip4-config.h"
static gboolean
test_wireless_enabled (NMClient *client)
......@@ -61,23 +62,24 @@ dump_ip4_config (NMIP4Config *cfg)
char *tmp;
const GArray *array;
const GPtrArray *ptr_array;
GSList *iter;
int i;
tmp = ip4_address_as_string (nm_ip4_config_get_address (cfg));
g_print ("IP4 address: %s\n", tmp);
g_free (tmp);
for (iter = (GSList *) nm_ip4_config_get_addresses (cfg); iter; iter = g_slist_next (iter)) {
NMSettingIP4Address *addr = iter->data;
tmp = ip4_address_as_string (nm_ip4_config_get_gateway (cfg));
g_print ("IP4 gateway: %s\n", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->address);
g_print ("IP4 address: %s\n", tmp);
g_free (tmp);
tmp = ip4_address_as_string (nm_ip4_config_get_netmask (cfg));
g_print ("IP4 netmask: %s\n", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->netmask);
g_print ("IP4 netmask: %s\n", tmp);
g_free (tmp);
tmp = ip4_address_as_string (nm_ip4_config_get_broadcast (cfg));
g_print ("IP4 broadcast: %s\n", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->gateway);
g_print ("IP4 gateway: %s\n\n", tmp);
g_free (tmp);
}
g_print ("IP4 hostname: %s\n", nm_ip4_config_get_hostname (cfg));
......
......@@ -4,6 +4,7 @@
#include "NetworkManager.h"
#include "nm-types-private.h"
#include "nm-object-private.h"
#include "nm-utils.h"
G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT)
......@@ -12,10 +13,7 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT)
typedef struct {
DBusGProxy *proxy;
guint32 address;
guint32 gateway;
guint32 netmask;
guint32 broadcast;
GSList *addresses;
char *hostname;
GArray *nameservers;
GPtrArray *domains;
......@@ -25,10 +23,7 @@ typedef struct {
enum {
PROP_0,
PROP_ADDRESS,
PROP_GATEWAY,
PROP_NETMASK,
PROP_BROADCAST,
PROP_ADDRESSES,
PROP_HOSTNAME,
PROP_NAMESERVERS,
PROP_DOMAINS,
......@@ -43,6 +38,21 @@ nm_ip4_config_init (NMIP4Config *config)
{
}
static gboolean
demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
g_slist_foreach (priv->addresses, (GFunc) g_free, NULL);
g_slist_free (priv->addresses);
priv->addresses = NULL;
priv->addresses = nm_utils_ip4_addresses_from_gvalue (value);
nm_object_queue_notify (object, NM_IP4_CONFIG_ADDRESSES);
return TRUE;
}
static gboolean
demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
......@@ -71,10 +81,7 @@ register_for_property_changed (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
const NMPropertiesChangedInfo property_changed_info[] = {
{ NM_IP4_CONFIG_ADDRESS, nm_object_demarshal_generic, &priv->address },
{ NM_IP4_CONFIG_GATEWAY, nm_object_demarshal_generic, &priv->gateway },
{ NM_IP4_CONFIG_NETMASK, nm_object_demarshal_generic, &priv->netmask },
{ NM_IP4_CONFIG_BROADCAST, nm_object_demarshal_generic, &priv->broadcast },
{ NM_IP4_CONFIG_ADDRESSES, demarshal_ip4_address_array, &priv->addresses },
{ NM_IP4_CONFIG_HOSTNAME, nm_object_demarshal_generic, &priv->hostname },
{ NM_IP4_CONFIG_NAMESERVERS, demarshal_ip4_array, &priv->nameservers },
{ NM_IP4_CONFIG_DOMAINS, demarshal_domains, &priv->domains },
......@@ -121,6 +128,9 @@ finalize (GObject *object)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
g_slist_foreach (priv->addresses, (GFunc) g_free, NULL);
g_slist_free (priv->addresses);
g_free (priv->hostname);
g_free (priv->nis_domain);
if (priv->nameservers)
......@@ -143,19 +153,11 @@ get_property (GObject *object,
GParamSpec *pspec)
{
NMIP4Config *self = NM_IP4_CONFIG (object);
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
switch (prop_id) {
case PROP_ADDRESS:
g_value_set_uint (value, nm_ip4_config_get_address (self));
break;
case PROP_GATEWAY:
g_value_set_uint (value, nm_ip4_config_get_gateway (self));
break;
case PROP_NETMASK:
g_value_set_uint (value, nm_ip4_config_get_netmask (self));
break;
case PROP_BROADCAST:
g_value_set_uint (value, nm_ip4_config_get_broadcast (self));
case PROP_ADDRESSES:
nm_utils_ip4_addresses_to_gvalue (priv->addresses, value);
break;
case PROP_HOSTNAME:
g_value_set_string (value, nm_ip4_config_get_hostname (self));
......@@ -192,36 +194,11 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class)
/* properties */
g_object_class_install_property
(object_class, PROP_ADDRESS,
g_param_spec_uint (NM_IP4_CONFIG_ADDRESS,
"Address",
"Address",
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_GATEWAY,
g_param_spec_uint (NM_IP4_CONFIG_GATEWAY,
"Gateway",
"Gateway",
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_NETMASK,
g_param_spec_uint (NM_IP4_CONFIG_NETMASK,
"Netmask",
"Netmask",
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_BROADCAST,
g_param_spec_uint (NM_IP4_CONFIG_BROADCAST,
"Broadcast",
"Broadcast",
0, G_MAXUINT32, 0,
G_PARAM_READABLE));
(object_class, PROP_ADDRESSES,
g_param_spec_pointer (NM_IP4_CONFIG_ADDRESSES,
"Addresses",
"Addresses",
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_HOSTNAME,
......@@ -273,72 +250,29 @@ nm_ip4_config_new (DBusGConnection *connection, const char *object_path)
NULL);
}
guint32
nm_ip4_config_get_address (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
if (!priv->address) {
priv->address = nm_object_get_uint_property (NM_OBJECT (config),
NM_DBUS_INTERFACE_IP4_CONFIG,
"Address");
}
return priv->address;
}
guint32
nm_ip4_config_get_gateway (NMIP4Config *config)
const GSList *
nm_ip4_config_get_addresses (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
GValue value = { 0, };
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
if (!priv->gateway) {
priv->gateway = nm_object_get_uint_property (NM_OBJECT (config),
NM_DBUS_INTERFACE_IP4_CONFIG,
"Gateway");
}
return priv->gateway;
}
guint32
nm_ip4_config_get_netmask (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
if (priv->addresses)
return priv->addresses;
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
if (!priv->netmask) {
priv->netmask = nm_object_get_uint_property (NM_OBJECT (config),
NM_DBUS_INTERFACE_IP4_CONFIG,
"Netmask");
if (!nm_object_get_property (NM_OBJECT (config),
"org.freedesktop.DBus.Properties",
"Addresses",
&value)) {
return NULL;
}
return priv->netmask;
}
guint32
nm_ip4_config_get_broadcast (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
if (!priv->broadcast) {
priv->broadcast = nm_object_get_uint_property (NM_OBJECT (config),
NM_DBUS_INTERFACE_IP4_CONFIG,
"Broadcast");
}
demarshal_ip4_address_array (NM_OBJECT (config), NULL, &value, &priv->addresses);
g_value_unset (&value);
return priv->broadcast;
return priv->addresses;
}
const char *
......
......@@ -23,10 +23,7 @@ typedef struct {
NMObjectClass parent;
} NMIP4ConfigClass;
#define NM_IP4_CONFIG_ADDRESS "address"
#define NM_IP4_CONFIG_GATEWAY "gateway"
#define NM_IP4_CONFIG_NETMASK "netmask"
#define NM_IP4_CONFIG_BROADCAST "broadcast"
#define NM_IP4_CONFIG_ADDRESSES "addresses"
#define NM_IP4_CONFIG_HOSTNAME "hostname"
#define NM_IP4_CONFIG_NAMESERVERS "nameservers"
#define NM_IP4_CONFIG_DOMAINS "domains"
......@@ -37,10 +34,7 @@ GType nm_ip4_config_get_type (void);
GObject *nm_ip4_config_new (DBusGConnection *connection, const char *object_path);
guint32 nm_ip4_config_get_address (NMIP4Config *config);
guint32 nm_ip4_config_get_gateway (NMIP4Config *config);
guint32 nm_ip4_config_get_netmask (NMIP4Config *config);
guint32 nm_ip4_config_get_broadcast (NMIP4Config *config);
const GSList * nm_ip4_config_get_addresses (NMIP4Config *config);
const char * nm_ip4_config_get_hostname (NMIP4Config *config);
const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config);
const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config);
......
......@@ -87,64 +87,6 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_setting_ip4_config_parent_class)->finalize (object);
}
static GSList *
ip4_addresses_from_gvalue (const GValue *value)
{
GPtrArray *addresses;
int i;
GSList *list = NULL;
addresses = (GPtrArray *) g_value_get_boxed (value);
for (i = 0; addresses && (i < addresses->len); i++) {
GArray *array = (GArray *) g_ptr_array_index (addresses, i);
if (array->len == 2 || array->len == 3) {
NMSettingIP4Address *ip4_addr;
ip4_addr = g_new0 (NMSettingIP4Address, 1);
ip4_addr->address = g_array_index (array, guint32, 0);
ip4_addr->netmask = g_array_index (array, guint32, 1);
if (array->len == 3)
ip4_addr->gateway = g_array_index (array, guint32, 2);
list = g_slist_prepend (list, ip4_addr);
} else
nm_warning ("Ignoring invalid IP4 address");
}
return g_slist_reverse (list);
}
static void
ip4_addresses_to_gvalue (GSList *list, GValue *value)
{
GPtrArray *addresses;
GSList *iter;
addresses = g_ptr_array_new ();
for (iter = list; iter; iter = iter->next) {
NMSettingIP4Address *ip4_addr = (NMSettingIP4Address *) iter->data;
GArray *array;
const guint32 empty_val = 0;
array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
g_array_append_val (array, ip4_addr->address);
g_array_append_val (array, ip4_addr->netmask);
if (ip4_addr->gateway)
g_array_append_val (array, ip4_addr->gateway);
else
g_array_append_val (array, empty_val);
g_ptr_array_add (addresses, array);
}
g_value_take_boxed (value, addresses);
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
......@@ -167,7 +109,7 @@ set_property (GObject *object, guint prop_id,
break;
case PROP_ADDRESSES:
nm_utils_slist_free (setting->addresses, g_free);
setting->addresses = ip4_addresses_from_gvalue (value);
setting->addresses = nm_utils_ip4_addresses_from_gvalue (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......@@ -192,7 +134,7 @@ get_property (GObject *object, guint prop_id,
g_value_set_boxed (value, setting->dns_search);
break;
case PROP_ADDRESSES:
ip4_addresses_to_gvalue (setting->addresses, value);
nm_utils_ip4_addresses_to_gvalue (setting->addresses, value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
......
......@@ -86,10 +86,11 @@ update_default_route (NMPolicy *policy, NMDevice *new)
nm_system_device_replace_default_ip4_route (ip_iface, 0, 0);
} else {
NMIP4Config *config;
const NMSettingIP4Address *def_addr;
config = nm_device_get_ip4_config (new);
nm_system_device_replace_default_ip4_route (ip_iface, nm_ip4_config_get_gateway (config),
nm_ip4_config_get_mss (config));
def_addr = nm_ip4_config_get_address (config, 0);
nm_system_device_replace_default_ip4_route (ip_iface, def_addr->gateway, nm_ip4_config_get_mss (config));
}
}
......@@ -129,6 +130,8 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
NMIP4Config *ip4_config;
NMSettingIP4Config *s_ip4;
guint32 prio;
guint i;
gboolean have_gateway = FALSE;
if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED)
continue;
......@@ -147,8 +150,18 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
if (s_ip4 && !strcmp (s_ip4->method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP))
continue;
/* FIXME: handle more than one IP address */
if (!nm_ip4_config_get_gateway (ip4_config))
/* Make sure at least one of this device's IP addresses has a gateway */
for (i = 0; i < nm_ip4_config_get_num_addresses (ip4_config); i++) {
const NMSettingIP4Address *addr;
addr = nm_ip4_config_get_address (ip4_config, i);
if (addr->gateway) {
have_gateway = TRUE;
break;
}
}
if (!have_gateway)
continue;
prio = get_device_priority (dev);
......
......@@ -80,7 +80,7 @@ nm_system_device_set_ip4_route (const char *iface,
struct nl_handle *nlh = NULL;
struct nl_addr *gw_addr = NULL;
struct nl_addr *dest_addr = NULL;
int err, iface_idx;
int err, iface_idx, i;
/*
* Zero is not a legal gateway and the ioctl will fail. But zero is a
......@@ -93,10 +93,15 @@ nm_system_device_set_ip4_route (const char *iface,
/*
* Do not add the route if the destination is on the same subnet.
*/
if (iface_config &&
((guint32)ip4_dest & nm_ip4_config_get_netmask (iface_config)) ==
(nm_ip4_config_get_address (iface_config) & nm_ip4_config_get_netmask (iface_config)))
return TRUE;
if (iface_config) {
for (i = 0; i < nm_ip4_config_get_num_addresses (iface_config); i++) {
const NMSettingIP4Address *cfg_addr;
cfg_addr = nm_ip4_config_get_address (iface_config, i);
if ((ip4_dest & cfg_addr->netmask) == (cfg_addr->address & cfg_addr->netmask))
return TRUE;
}
}
nlh = nm_netlink_get_default_handle ();
g_return_val_if_fail (nlh != NULL, FALSE);
......@@ -186,8 +191,9 @@ out:
typedef struct {
const char *iface;
int ifindex;
int family;
struct nl_handle *nlh;
struct rtnl_addr *match;
} AddrCheckData;
static void
......@@ -197,44 +203,26 @@ check_one_address (struct nl_object *object, void *user_data)
struct rtnl_addr *addr = (struct rtnl_addr *) object;
int err;
/* Delete addresses on this interface which don't match the one we
* are about to add to it.
*/
if (nl_object_identical ((struct nl_object *) data->match, (struct nl_object *) addr))
return;
if (rtnl_addr_get_ifindex (addr) != rtnl_addr_get_ifindex (data->match))
return;
if (rtnl_addr_get_family (addr) != rtnl_addr_get_family (data->match))
return;
err = rtnl_addr_delete (data->nlh, addr, 0);
if (err < 0) {
nm_warning ("(%s) error %d returned from rtnl_addr_delete(): %s",
data->iface, err, nl_geterror());
if (rtnl_addr_get_ifindex (addr) == data->ifindex) {
if (rtnl_addr_get_family (addr) == data->family) {
err = rtnl_addr_delete (data->nlh, addr, 0);
if (err < 0) {
nm_warning ("(%s) error %d returned from rtnl_addr_delete(): %s",
data->iface, err, nl_geterror());
}
}
}
}
/*
* nm_system_device_set_from_ip4_config
*
* Set IPv4 configuration of the device from an NMIP4Config object.
*
*/
gboolean
nm_system_device_set_from_ip4_config (const char *iface,
NMIP4Config *config,
gboolean route_to_iface)
static gboolean
add_ip4_addresses (NMIP4Config *config, const char *iface)
{
struct nl_handle *nlh = NULL;
struct rtnl_addr *addr = NULL;
struct nl_cache *addr_cache = NULL;
int len, i, err;
guint32 flags;
int i, iface_idx, err;
AddrCheckData check_data;
gboolean success = FALSE;
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
guint32 flags = 0;
gboolean did_gw = FALSE;
nlh = nm_netlink_get_default_handle ();
if (!nlh)
......@@ -242,30 +230,69 @@ nm_system_device_set_from_ip4_config (const char *iface,
addr_cache = rtnl_addr_alloc_cache (nlh);
if (!addr_cache)
goto out;
return FALSE;
nl_cache_mngt_provide (addr_cache);
flags = NM_RTNL_ADDR_DEFAULT;
if (nm_ip4_config_get_ptp_address (config))
flags |= NM_RTNL_ADDR_PTP_ADDR;
addr = nm_ip4_config_to_rtnl_addr (config, flags);
if (!addr) {
nm_warning ("couldn't create rtnl address!\n");
goto out;
}
rtnl_addr_set_ifindex (addr, nm_netlink_iface_to_index (iface));
iface_idx = nm_netlink_iface_to_index (iface);
memset (&check_data, 0, sizeof (check_data));
check_data.iface = iface;
check_data.nlh = nlh;
check_data.match = addr;
check_data.ifindex = iface_idx;
check_data.family = AF_INET;
/* Remove all addresses except the one we're about to add */
/* Remove all existing IPv4 addresses */
nl_cache_foreach (addr_cache, check_one_address, &check_data);
if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror());
for (i = 0; i < nm_ip4_config_get_num_addresses (config); i++) {
const NMSettingIP4Address *addr;
struct rtnl_addr *nl_addr = NULL;
addr = nm_ip4_config_get_address (config, i);
g_assert (addr);
flags = NM_RTNL_ADDR_DEFAULT;
if (addr->gateway && !did_gw) {
if (nm_ip4_config_get_ptp_address (config))
flags |= NM_RTNL_ADDR_PTP_ADDR;
did_gw = TRUE;
}
nl_addr = nm_ip4_config_to_rtnl_addr (config, i, flags);
if