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
This commit is contained in:
Dan Williams 2008-05-06 21:53:22 +00:00
parent 3cbc245395
commit 51503b2d5f
16 changed files with 567 additions and 593 deletions

View file

@ -1,3 +1,60 @@
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

View file

@ -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>

View file

@ -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));

View file

@ -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)
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->address) {
priv->address = nm_object_get_uint_property (NM_OBJECT (config),
NM_DBUS_INTERFACE_IP4_CONFIG,
"Address");
if (priv->addresses)
return priv->addresses;
if (!nm_object_get_property (NM_OBJECT (config),
"org.freedesktop.DBus.Properties",
"Addresses",
&value)) {
return NULL;
}
return priv->address;
}
demarshal_ip4_address_array (NM_OBJECT (config), NULL, &value, &priv->addresses);
g_value_unset (&value);
guint32
nm_ip4_config_get_gateway (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
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;
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");
}
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");
}
return priv->broadcast;
return priv->addresses;
}
const char *

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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,23 +203,78 @@ 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());
}
}
}
}
static gboolean
add_ip4_addresses (NMIP4Config *config, const char *iface)
{
struct nl_handle *nlh = NULL;
struct nl_cache *addr_cache = NULL;
int i, iface_idx, err;
AddrCheckData check_data;
guint32 flags = 0;
gboolean did_gw = FALSE;
nlh = nm_netlink_get_default_handle ();
if (!nlh)
return FALSE;
addr_cache = rtnl_addr_alloc_cache (nlh);
if (!addr_cache)
return FALSE;
nl_cache_mngt_provide (addr_cache);
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.ifindex = iface_idx;
check_data.family = AF_INET;
/* Remove all existing IPv4 addresses */
nl_cache_foreach (addr_cache, check_one_address, &check_data);
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 (!nl_addr) {
nm_warning ("couldn't create rtnl address!\n");
continue;
}
rtnl_addr_set_ifindex (nl_addr, iface_idx);
if ((err = rtnl_addr_add (nlh, nl_addr, 0)) < 0)
nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", iface, err, nl_geterror());
rtnl_addr_put (nl_addr);
}
nl_cache_free (addr_cache);
return TRUE;
}
/*
* nm_system_device_set_from_ip4_config
*
@ -225,48 +286,14 @@ nm_system_device_set_from_ip4_config (const char *iface,
NMIP4Config *config,
gboolean route_to_iface)
{
struct nl_handle *nlh = NULL;
struct rtnl_addr *addr = NULL;
struct nl_cache *addr_cache = NULL;
int len, i, err;
guint32 flags;
AddrCheckData check_data;
gboolean success = FALSE;
int len, i;
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
nlh = nm_netlink_get_default_handle ();
if (!nlh)
if (!add_ip4_addresses (config, iface))
return FALSE;
addr_cache = rtnl_addr_alloc_cache (nlh);
if (!addr_cache)
goto out;
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));
memset (&check_data, 0, sizeof (check_data));
check_data.iface = iface;
check_data.nlh = nlh;
check_data.match = addr;
/* Remove all addresses except the one we're about to add */
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());
sleep (1);
len = nm_ip4_config_get_num_static_routes (config);
@ -281,14 +308,7 @@ nm_system_device_set_from_ip4_config (const char *iface,
if (nm_ip4_config_get_mtu (config))
nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config));
success = TRUE;
out:
if (addr)
rtnl_addr_put (addr);
if (addr_cache)
nl_cache_free (addr_cache);
return success;
return TRUE;
}
/*
@ -303,43 +323,45 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
NMIP4Config *config,
GSList *routes)
{
NMIP4Config * ad_config = NULL;
struct nl_handle * nlh = NULL;
struct rtnl_addr * addr = NULL;
NMIP4Config *ad_config = NULL;
NMNamedManager *named_mgr;
int iface_idx;
int i;
g_return_val_if_fail (config != NULL, FALSE);
/* Set up a route to the VPN gateway through the real network device */
if (active_device && (ad_config = nm_device_get_ip4_config (active_device))) {
guint32 ad_gw = 0, vpn_gw = 0;
const NMSettingIP4Address *tmp;
for (i = 0; i < nm_ip4_config_get_num_addresses (ad_config); i++) {
tmp = nm_ip4_config_get_address (ad_config, i);
if (tmp->gateway) {
ad_gw = tmp->gateway;
break;
}
}
for (i = 0; i < nm_ip4_config_get_num_addresses (config); i++) {
tmp = nm_ip4_config_get_address (config, i);
if (tmp->gateway) {
vpn_gw = tmp->gateway;
break;
}
}
nm_system_device_set_ip4_route (nm_device_get_ip_iface (active_device),
ad_config,
nm_ip4_config_get_gateway (ad_config),
nm_ip4_config_get_gateway (config),
32,
ad_config, ad_gw, vpn_gw, 32,
nm_ip4_config_get_mss (config));
}
if (!iface || !strlen (iface))
goto out;
nlh = nm_netlink_get_default_handle ();
if (!nlh)
goto out;
nm_system_device_set_up_down_with_iface (iface, TRUE);
iface_idx = nm_netlink_iface_to_index (iface);
if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_PTP_DEFAULT))) {
int err = 0;
rtnl_addr_set_ifindex (addr, iface_idx);
if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
rtnl_addr_put (addr);
} else
nm_warning ("couldn't create rtnl address!\n");
if (!add_ip4_addresses (config, iface))
goto out;
/* Set the MTU */
if (nm_ip4_config_get_mtu (config))

View file

@ -237,6 +237,8 @@ nm_ether_ntop (const struct ether_addr *mac)
void
nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
{
GSList *iter;
if (!setting)
return; /* Defaults are just fine */
@ -261,42 +263,44 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
}
}
if (setting->dns_search) {
GSList *iter;
/* DNS search domains */
for (iter = setting->dns_search; iter; iter = iter->next) {
int i;
gboolean found = FALSE;
for (iter = setting->dns_search; iter; iter = iter->next) {
int i;
gboolean found = FALSE;
/* Avoid dupes */
for (i = 0; i < nm_ip4_config_get_num_searches (ip4_config); i++) {
const char *search = nm_ip4_config_get_search (ip4_config, i);
/* Avoid dupes */
for (i = 0; i < nm_ip4_config_get_num_searches (ip4_config); i++) {
const char *search = nm_ip4_config_get_search (ip4_config, i);
if (!strcmp (search, (char *) iter->data)) {
found = TRUE;
break;
}
if (!strcmp (search, (char *) iter->data)) {
found = TRUE;
break;
}
if (!found)
nm_ip4_config_add_search (ip4_config, (char *) iter->data);
}
if (!found)
nm_ip4_config_add_search (ip4_config, (char *) iter->data);
}
if (setting->addresses) {
/* FIXME; add support for more than one set of address/netmask/gateway for NMIP4Config */
NMSettingIP4Address *addr = (NMSettingIP4Address *) setting->addresses->data;
/* IPv4 addresses */
for (iter = setting->addresses; iter; iter = g_slist_next (iter)) {
NMSettingIP4Address *setting_addr = (NMSettingIP4Address *) iter->data;
guint32 i, num;
/* Avoid dupes, but override if anything is different */
if ( (nm_ip4_config_get_address (ip4_config) != addr->address)
|| (nm_ip4_config_get_netmask (ip4_config) != addr->netmask)
|| (addr->gateway && (nm_ip4_config_get_gateway (ip4_config) != addr->gateway))) {
nm_ip4_config_set_address (ip4_config, addr->address);
nm_ip4_config_set_netmask (ip4_config, addr->netmask);
num = nm_ip4_config_get_num_addresses (ip4_config);
for (i = 0; i < num; i++) {
const NMSettingIP4Address *cfg_addr;
if (addr->gateway)
nm_ip4_config_set_gateway (ip4_config, addr->gateway);
cfg_addr = nm_ip4_config_get_address (ip4_config, i);
/* Dupe, override with user-specified address */
if (cfg_addr->address == setting_addr->address) {
nm_ip4_config_replace_address (ip4_config, i, setting_addr);
break;
}
}
if (i == num)
nm_ip4_config_add_address (ip4_config, setting_addr);
}
}

View file

@ -834,20 +834,10 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager,
{
NMDHCPManagerPrivate *priv;
NMDHCPDevice *device;
NMIP4Config * ip4_config = NULL;
guint32 ip4_address = 0;
guint32 ip4_netmask = 0;
guint32 ip4_broadcast = 0;
guint32 ip4_gateway = 0;
char * hostname = NULL;
char * domain = NULL;
char * search = NULL;
char * nameservers = NULL;
char * nis_domain = NULL;
char * nis_servers = NULL;
char * static_routes = NULL;
char * ip = NULL; //this is a general string that is used as a temporary place for ip(s)
char * mtu = NULL;
NMIP4Config *ip4_config = NULL;
NMSettingIP4Address *addr;
guint32 ip4_num = 0;
char *str = NULL;
g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL);
g_return_val_if_fail (iface != NULL, NULL);
@ -865,82 +855,73 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager,
return NULL;
}
ip = g_hash_table_lookup (device->options, "new_ip_address");
if (ip != NULL) {
ip4_address = inet_addr (ip);
nm_info(" address %s", ip);
}
else {
return NULL;
}
ip = g_hash_table_lookup (device->options, "new_subnet_mask");
if (ip != NULL) {
ip4_netmask = inet_addr (ip);
nm_info(" netmask %s", ip);
}
else {
return NULL;
}
ip = g_hash_table_lookup (device->options, "new_broadcast_address");
if (ip != NULL) {
ip4_broadcast = inet_addr (ip);
nm_info(" broadcast %s", ip);
}
else {
return NULL;
}
ip = g_hash_table_lookup (device->options, "new_routers");
if (ip != NULL) {
ip4_gateway = inet_addr (ip);
}
else { /* If DHCP doesn't have a 'routers', just use the DHCP server's address as our gateway for now */
ip = g_hash_table_lookup (device->options, "new_dhcp_server_identifier");
if (ip != NULL)
ip4_gateway = inet_addr (ip);
else
return NULL;
}
nm_info(" gateway %s", ip);
ip4_config = nm_ip4_config_new ();
nm_ip4_config_set_address (ip4_config, ip4_address);
nm_ip4_config_set_netmask (ip4_config, ip4_netmask);
nm_ip4_config_set_broadcast (ip4_config, ip4_broadcast);
nm_ip4_config_set_gateway (ip4_config, ip4_gateway);
if (!ip4_config) {
nm_warning ("%s: couldn't allocate memory for an IP4Config!", device->iface);
return NULL;
}
hostname = g_hash_table_lookup (device->options, "new_host_name");
nameservers = g_hash_table_lookup (device->options, "new_domain_name_servers");
domain = g_hash_table_lookup (device->options, "new_domain_name");
search = g_hash_table_lookup (device->options, "new_domain_search");
nis_domain = g_hash_table_lookup (device->options, "new_nis_domain");
nis_servers = g_hash_table_lookup (device->options, "new_nis_servers");
static_routes = g_hash_table_lookup (device->options, "new_static_routes");
addr = g_malloc0 (sizeof (NMSettingIP4Address));
if (!addr) {
nm_warning ("%s: couldn't allocate memory for an IP4 Address!", device->iface);
goto error;
}
if (nameservers) {
char **searches = g_strsplit (nameservers, " ", 0);
str = g_hash_table_lookup (device->options, "new_ip_address");
if (str != NULL) {
addr->address = inet_addr (str);
nm_info(" address %s", str);
}
if (!addr->address) {
g_free (addr);
goto error;
}
str = g_hash_table_lookup (device->options, "new_subnet_mask");
if (str != NULL) {
addr->netmask = inet_addr (str);
nm_info(" netmask %s", str);
}
str = g_hash_table_lookup (device->options, "new_routers");
if (str != NULL) {
addr->gateway = inet_addr (str);
} else { /* If DHCP doesn't have a 'routers', just use the DHCP server's address as our gateway for now */
str = g_hash_table_lookup (device->options, "new_dhcp_server_identifier");
if (str != NULL)
addr->gateway = inet_addr (str);
else {
g_free (addr);
return NULL;
}
}
nm_info(" gateway %s", str);
nm_ip4_config_take_address (ip4_config, addr);
str = g_hash_table_lookup (device->options, "new_host_name");
if (str) {
nm_ip4_config_set_hostname (ip4_config, str);
nm_info (" hostname '%s'", str);
}
str = g_hash_table_lookup (device->options, "new_domain_name_servers");
if (str) {
char **searches = g_strsplit (str, " ", 0);
char **s;
int ip4_nameserver;
for (s = searches; *s; s++) {
// FIXME: use inet_aton
ip4_nameserver = inet_addr (*s);
nm_ip4_config_add_nameserver (ip4_config, ip4_nameserver);
ip4_num = inet_addr (*s);
nm_ip4_config_add_nameserver (ip4_config, ip4_num);
nm_info (" nameserver '%s'", *s);
}
g_strfreev (searches);
}
if (hostname) {
nm_ip4_config_set_hostname (ip4_config, hostname);
nm_info (" hostname '%s'", hostname);
}
if (domain) {
char **domains = g_strsplit (domain, " ", 0);
str = g_hash_table_lookup (device->options, "new_domain_name");
if (str) {
char **domains = g_strsplit (str, " ", 0);
char **s;
for (s = domains; *s; s++) {
@ -950,8 +931,9 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager,
g_strfreev (domains);
}
if (search) {
char **searches = g_strsplit (search, " ", 0);
str = g_hash_table_lookup (device->options, "new_domain_search");
if (str) {
char **searches = g_strsplit (str, " ", 0);
char **s;
for (s = searches; *s; s++) {
@ -961,48 +943,50 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager,
g_strfreev (searches);
}
if (nis_domain) {
nm_ip4_config_set_nis_domain (ip4_config, nis_domain);
nm_info (" nis domain '%s'", nis_domain);
str = g_hash_table_lookup (device->options, "new_nis_domain");
if (str) {
nm_ip4_config_set_nis_domain (ip4_config, str);
nm_info (" nis domain '%s'", str);
}
if (nis_servers) {
char **searches = g_strsplit (nis_servers, " ", 0);
str = g_hash_table_lookup (device->options, "new_nis_servers");
if (str) {
char **searches = g_strsplit (str, " ", 0);
char **s;
int ip4_nis_server;
for (s = searches; *s; s++) {
// FIXME: use inet_aton
ip4_nis_server = inet_addr (*s);
nm_ip4_config_add_nis_server (ip4_config, ip4_nis_server);
ip4_num = inet_addr (*s);
nm_ip4_config_add_nis_server (ip4_config, ip4_num);
nm_info (" nis server '%s'", *s);
}
g_strfreev (searches);
}
if (static_routes) {
char **searches = g_strsplit (static_routes, " ", 0);
str = g_hash_table_lookup (device->options, "new_static_routes");
if (str) {
char **searches = g_strsplit (str, " ", 0);
if ((g_strv_length (searches) % 2) == 0) {
char **s;
for (s = searches; *s; s += 2) {
struct in_addr addr;
struct in_addr route;
struct in_addr rt_addr;
struct in_addr rt_route;
if (inet_aton (*s, &addr) == 0) {
if (inet_aton (*s, &rt_addr) == 0) {
nm_warning ("DHCP provided invalid static route address: '%s'", *s);
continue;
}
if (inet_aton (*(s + 1), &route) == 0) {
if (inet_aton (*(s + 1), &rt_route) == 0) {
nm_warning ("DHCP provided invalid static route gateway: '%s'", *(s + 1));
continue;
}
// FIXME: ensure the IP addresse and route are sane
nm_ip4_config_add_static_route (ip4_config,
(guint32) addr.s_addr,
(guint32) route.s_addr);
(guint32) rt_addr.s_addr,
(guint32) rt_route.s_addr);
nm_info (" static route %s gw %s", *s, *(s + 1));
}
} else {
@ -1011,13 +995,17 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager,
g_strfreev (searches);
}
mtu = g_hash_table_lookup (device->options, "new_interface_mtu");
if (mtu) {
int int_mtu = atoi (mtu);
str = g_hash_table_lookup (device->options, "new_interface_mtu");
if (str) {
int int_mtu = atoi (str);
if (int_mtu)
nm_ip4_config_set_mtu (ip4_config, int_mtu);
}
return ip4_config;
error:
g_object_unref (ip4_config);
return NULL;
}

View file

@ -618,21 +618,21 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self)
NMIP4Config *
nm_device_new_ip4_autoip_config (NMDevice *self)
{
struct in_addr ip;
NMIP4Config * config = NULL;
struct in_addr ip;
NMIP4Config *config = NULL;
NMSettingIP4Address *addr;
g_return_val_if_fail (self != NULL, NULL);
// FIXME: make our autoip implementation not suck; use avahi-autoip
if (get_autoip (self, &ip)) {
#define LINKLOCAL_BCAST 0xa9feffff
if (!get_autoip (self, &ip))
return NULL;
config = nm_ip4_config_new ();
nm_ip4_config_set_address (config, (guint32)(ip.s_addr));
nm_ip4_config_set_netmask (config, (guint32)(ntohl (0xFFFF0000)));
nm_ip4_config_set_broadcast (config, (guint32)(ntohl (LINKLOCAL_BCAST)));
nm_ip4_config_set_gateway (config, 0);
}
config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address));
addr->address = (guint32) ip.s_addr;
addr->netmask = (guint32) ntohl (0xFFFF0000);
nm_ip4_config_take_address (config, addr);
return config;
}

View file

@ -27,6 +27,7 @@
#include "nm-dbus-manager.h"
#include "NetworkManager.h"
#include "NetworkManagerUtils.h"
#include "nm-setting-ip4-config.h"
#include <netlink/route/addr.h>
#include <netlink/utils.h>
@ -41,11 +42,8 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, G_TYPE_OBJECT)
#define NM_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP4_CONFIG, NMIP4ConfigPrivate))
typedef struct {
guint32 ip4_address;
guint32 ip4_ptp_address;
guint32 ip4_gateway;
guint32 ip4_netmask;
guint32 ip4_broadcast;
GSList *addresses;
guint32 ptp_address;
guint32 mtu; /* Maximum Transmission Unit of the interface */
guint32 mss; /* Maximum Segment Size of the route */
@ -54,8 +52,8 @@ typedef struct {
GPtrArray *domains;
GPtrArray *searches;
gchar * hostname;
gchar * nis_domain;
gchar *hostname;
gchar *nis_domain;
GArray *nis_servers;
GArray *static_routes;
} NMIP4ConfigPrivate;
@ -63,10 +61,7 @@ typedef struct {
enum {
PROP_0,
PROP_ADDRESS,
PROP_GATEWAY,
PROP_NETMASK,
PROP_BROADCAST,
PROP_ADDRESSES,
PROP_HOSTNAME,
PROP_NAMESERVERS,
PROP_DOMAINS,
@ -100,20 +95,26 @@ nm_ip4_config_new (void)
NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config)
{
NMIP4Config *dst_config;
NMIP4ConfigPrivate *priv;
NMIP4ConfigPrivate *src_priv;
int i;
int len;
GSList *iter;
g_return_val_if_fail (NM_IS_IP4_CONFIG (src_config), NULL);
dst_config = nm_ip4_config_new ();
priv = NM_IP4_CONFIG_GET_PRIVATE (dst_config);
src_priv = NM_IP4_CONFIG_GET_PRIVATE (src_config);
for (iter = src_priv->addresses; iter; iter = g_slist_next (iter)) {
NMSettingIP4Address *src_addr = (NMSettingIP4Address *) iter->data;
NMSettingIP4Address *dst_addr;
dst_addr = g_malloc0 (sizeof (NMSettingIP4Address));
memcpy (dst_addr, src_addr, sizeof (NMSettingIP4Address));
nm_ip4_config_take_address (dst_config, dst_addr);
}
nm_ip4_config_set_address (dst_config, nm_ip4_config_get_address (src_config));
nm_ip4_config_set_ptp_address (dst_config, nm_ip4_config_get_ptp_address (src_config));
nm_ip4_config_set_gateway (dst_config, nm_ip4_config_get_gateway (src_config));
nm_ip4_config_set_netmask (dst_config, nm_ip4_config_get_netmask (src_config));
nm_ip4_config_set_broadcast (dst_config, nm_ip4_config_get_broadcast (src_config));
nm_ip4_config_set_hostname (dst_config, nm_ip4_config_get_hostname (src_config));
nm_ip4_config_set_nis_domain (dst_config, nm_ip4_config_get_nis_domain (src_config));
@ -140,74 +141,79 @@ NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config)
return dst_config;
}
guint32 nm_ip4_config_get_address (NMIP4Config *config)
void
nm_ip4_config_take_address (NMIP4Config *config,
NMSettingIP4Address *address)
{
NMIP4ConfigPrivate *priv;
g_return_if_fail (NM_IS_IP4_CONFIG (config));
g_return_if_fail (address != NULL);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
priv->addresses = g_slist_append (priv->addresses, address);
}
void
nm_ip4_config_add_address (NMIP4Config *config,
NMSettingIP4Address *address)
{
NMIP4ConfigPrivate *priv;
NMSettingIP4Address *copy;
g_return_if_fail (NM_IS_IP4_CONFIG (config));
g_return_if_fail (address != NULL);
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
copy = g_malloc0 (sizeof (NMSettingIP4Address));
memcpy (copy, address, sizeof (NMSettingIP4Address));
priv->addresses = g_slist_append (priv->addresses, copy);
}
void
nm_ip4_config_replace_address (NMIP4Config *config,
guint i,
NMSettingIP4Address *new_address)
{
NMIP4ConfigPrivate *priv;
GSList *old;
g_return_if_fail (NM_IS_IP4_CONFIG (config));
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
old = g_slist_nth (priv->addresses, i);
g_return_if_fail (old != NULL);
g_free (old->data);
old->data = new_address;
}
const NMSettingIP4Address *nm_ip4_config_get_address (NMIP4Config *config, guint i)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
return (const NMSettingIP4Address *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->addresses, i);
}
guint32 nm_ip4_config_get_num_addresses (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
return NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_address;
}
void nm_ip4_config_set_address (NMIP4Config *config, guint32 addr)
{
g_return_if_fail (NM_IS_IP4_CONFIG (config));
NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_address = addr;
return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->addresses);
}
guint32 nm_ip4_config_get_ptp_address (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
return NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_ptp_address;
return NM_IP4_CONFIG_GET_PRIVATE (config)->ptp_address;
}
void nm_ip4_config_set_ptp_address (NMIP4Config *config, guint32 ptp_addr)
{
g_return_if_fail (NM_IS_IP4_CONFIG (config));
NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_ptp_address = ptp_addr;
}
guint32 nm_ip4_config_get_gateway (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
return NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_gateway;
}
void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway)
{
g_return_if_fail (NM_IS_IP4_CONFIG (config));
NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_gateway = gateway;
}
guint32 nm_ip4_config_get_netmask (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
return NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_netmask;
}
void nm_ip4_config_set_netmask (NMIP4Config *config, guint32 netmask)
{
g_return_if_fail (NM_IS_IP4_CONFIG (config));
NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_netmask = netmask;
}
guint32 nm_ip4_config_get_broadcast (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0);
return NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_broadcast;
}
void nm_ip4_config_set_broadcast (NMIP4Config *config, guint32 broadcast)
{
g_return_if_fail (NM_IS_IP4_CONFIG (config));
NM_IP4_CONFIG_GET_PRIVATE (config)->ip4_broadcast = broadcast;
NM_IP4_CONFIG_GET_PRIVATE (config)->ptp_address = ptp_addr;
}
void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver)
@ -440,43 +446,42 @@ static int ip4_addr_to_rtnl_broadcast (guint32 ip4_broadcast, struct rtnl_addr *
}
struct rtnl_addr * nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 flags)
struct rtnl_addr *
nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags)
{
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
struct rtnl_addr * addr = NULL;
gboolean success = TRUE;
const NMSettingIP4Address *config_addr;
struct rtnl_addr *addr;
gboolean success = TRUE;
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
config_addr = nm_ip4_config_get_address (config, i);
g_return_val_if_fail (config_addr != NULL, NULL);
if (!(addr = rtnl_addr_alloc()))
return NULL;
if (flags & NM_RTNL_ADDR_ADDR)
success = (ip4_addr_to_rtnl_local (priv->ip4_address, addr) >= 0);
success = (ip4_addr_to_rtnl_local (config_addr->address, addr) >= 0);
if (flags & NM_RTNL_ADDR_PTP_ADDR)
success = (ip4_addr_to_rtnl_peer (priv->ip4_ptp_address, addr) >= 0);
success = (ip4_addr_to_rtnl_peer (priv->ptp_address, addr) >= 0);
if (flags & NM_RTNL_ADDR_NETMASK)
ip4_addr_to_rtnl_prefixlen (priv->ip4_netmask, addr);
ip4_addr_to_rtnl_prefixlen (config_addr->netmask, addr);
if (flags & NM_RTNL_ADDR_BROADCAST) {
guint32 bcast = priv->ip4_broadcast;
guint32 hostmask, network, bcast;
/* Calculate the broadcast address if needed */
if (!bcast) {
guint32 hostmask, network;
network = ntohl (priv->ip4_address) & ntohl (priv->ip4_netmask);
hostmask = ~ntohl (priv->ip4_netmask);
bcast = htonl (network | hostmask);
}
network = ntohl (config_addr->address) & ntohl (config_addr->netmask);
hostmask = ~ntohl (config_addr->netmask);
bcast = htonl (network | hostmask);
success = (ip4_addr_to_rtnl_broadcast (bcast, addr) >= 0);
}
if (!success)
{
if (!success) {
rtnl_addr_put (addr);
addr = NULL;
}
@ -501,6 +506,8 @@ 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);
g_array_free (priv->nameservers, TRUE);
@ -510,6 +517,35 @@ finalize (GObject *object)
g_array_free (priv->static_routes, TRUE);
}
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
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@ -517,17 +553,8 @@ get_property (GObject *object, guint prop_id,
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
switch (prop_id) {
case PROP_ADDRESS:
g_value_set_uint (value, priv->ip4_address);
break;
case PROP_GATEWAY:
g_value_set_uint (value, priv->ip4_gateway);
break;
case PROP_NETMASK:
g_value_set_uint (value, priv->ip4_netmask);
break;
case PROP_BROADCAST:
g_value_set_uint (value, priv->ip4_broadcast);
case PROP_ADDRESSES:
ip4_addresses_to_gvalue (priv->addresses, value);
break;
case PROP_HOSTNAME:
g_value_set_string (value, priv->hostname);
@ -566,32 +593,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",
"IP4 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 address",
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 address",
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 address",
0, G_MAXUINT32, 0,
(object_class, PROP_ADDRESSES,
g_param_spec_boxed (NM_IP4_CONFIG_ADDRESSES,
"Addresses",
"IP4 addresses",
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_HOSTNAME,

View file

@ -27,6 +27,8 @@
#include <glib/gtypes.h>
#include <glib-object.h>
#include "nm-setting-ip4-config.h"
#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ())
#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP4_CONFIG, NMIP4Config))
#define NM_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
@ -42,10 +44,7 @@ typedef struct {
GObjectClass 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"
@ -59,21 +58,15 @@ GType nm_ip4_config_get_type (void);
NMIP4Config * nm_ip4_config_new (void);
NMIP4Config * nm_ip4_config_copy (NMIP4Config *config);
guint32 nm_ip4_config_get_address (NMIP4Config *config);
void nm_ip4_config_set_address (NMIP4Config *config, guint32 addr);
void nm_ip4_config_take_address (NMIP4Config *config, NMSettingIP4Address *address);
void nm_ip4_config_add_address (NMIP4Config *config, NMSettingIP4Address *address);
void nm_ip4_config_replace_address (NMIP4Config *config, guint32 i, NMSettingIP4Address *new_address);
const NMSettingIP4Address * nm_ip4_config_get_address (NMIP4Config *config, guint32 i);
guint32 nm_ip4_config_get_num_addresses (NMIP4Config *config);
guint32 nm_ip4_config_get_ptp_address (NMIP4Config *config);
void nm_ip4_config_set_ptp_address (NMIP4Config *config, guint32 ptp_addr);
guint32 nm_ip4_config_get_gateway (NMIP4Config *config);
void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway);
guint32 nm_ip4_config_get_netmask (NMIP4Config *config);
void nm_ip4_config_set_netmask (NMIP4Config *config, guint32 netmask);
guint32 nm_ip4_config_get_broadcast (NMIP4Config *config);
void nm_ip4_config_set_broadcast (NMIP4Config *config, guint32 broadcast);
void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver);
guint32 nm_ip4_config_get_nameserver (NMIP4Config *config, guint i);
guint32 nm_ip4_config_get_num_nameservers (NMIP4Config *config);
@ -116,6 +109,6 @@ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss);
#define NM_RTNL_ADDR_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_NETMASK | NM_RTNL_ADDR_BROADCAST)
#define NM_RTNL_ADDR_PTP_DEFAULT (NM_RTNL_ADDR_ADDR | NM_RTNL_ADDR_NETMASK | NM_RTNL_ADDR_PTP_ADDR)
struct rtnl_addr * nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 flags);
struct rtnl_addr *nm_ip4_config_to_rtnl_addr (NMIP4Config *config, guint32 i, guint32 flags);
#endif /* NM_IP4_CONFIG_H */

View file

@ -5,6 +5,7 @@
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "nm-ppp-manager.h"
#include "nm-setting-connection.h"
@ -231,6 +232,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
GError **err)
{
NMIP4Config *config;
NMSettingIP4Address *addr;
GValue *val;
const char *iface;
int i;
@ -244,23 +246,33 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
/* priv->ipconfig_timeout = 0; */
config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address));
val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_GATEWAY);
if (val) {
nm_ip4_config_set_gateway (config, g_value_get_uint (val));
addr->gateway = g_value_get_uint (val);
nm_ip4_config_set_ptp_address (config, g_value_get_uint (val));
}
val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_ADDRESS);
if (val)
nm_ip4_config_set_address (config, g_value_get_uint (val));
addr->address = g_value_get_uint (val);
val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_NETMASK);
if (val)
nm_ip4_config_set_netmask (config, g_value_get_uint (val));
else
addr->netmask = g_value_get_uint (val);
else {
/* If no netmask, default to Class C address */
nm_ip4_config_set_netmask (config, 0x00FF);
addr->netmask = htonl (0x000000FF);
}
if (addr->netmask && addr->address) {
nm_ip4_config_take_address (config, addr);
} else {
nm_warning ("%s: invalid IPv4 address or netmask received!", __func__);
g_free (addr);
goto out;
}
val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_DNS);
if (val) {

View file

@ -271,6 +271,7 @@ print_vpn_config (NMIP4Config *config,
const char *tundev,
const char *banner)
{
const NMSettingIP4Address *addr;
struct in_addr temp_addr;
char * dns_domain = NULL;
guint32 num;
@ -278,12 +279,13 @@ print_vpn_config (NMIP4Config *config,
g_return_if_fail (config != NULL);
temp_addr.s_addr = nm_ip4_config_get_gateway (config);
addr = nm_ip4_config_get_address (config, 0);
temp_addr.s_addr = addr->gateway;
nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
nm_info ("Tunnel Device: %s", tundev);
temp_addr.s_addr = nm_ip4_config_get_address (config);
temp_addr.s_addr = addr->address;
nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
temp_addr.s_addr = nm_ip4_config_get_netmask (config);
temp_addr.s_addr = addr->netmask;
nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
temp_addr.s_addr = nm_ip4_config_get_ptp_address (config);
nm_info ("Internal IP4 Point-to-Point Address: %s", inet_ntoa (temp_addr));
@ -312,6 +314,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
NMSettingIP4Config *s_ip4;
NMSettingIP4Address *addr;
NMIP4Config *config;
GValue *val;
int i;
@ -324,13 +327,15 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
config = nm_ip4_config_new ();
addr = g_malloc0 (sizeof (NMSettingIP4Address));
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY);
if (val)
nm_ip4_config_set_gateway (config, g_value_get_uint (val));
addr->gateway = g_value_get_uint (val);
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS);
if (val)
nm_ip4_config_set_address (config, g_value_get_uint (val));
addr->address = g_value_get_uint (val);
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PTP);
if (val)
@ -338,10 +343,18 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NETMASK);
if (val)
nm_ip4_config_set_netmask (config, g_value_get_uint (val));
else
addr->netmask = g_value_get_uint (val);
else {
/* If no netmask, default to Class C address */
nm_ip4_config_set_netmask (config, 0x00FF);
addr->netmask = htonl (0x000000FF);
}
if (addr->address && addr->netmask) {
nm_ip4_config_take_address (config, addr);
} else {
g_warning ("%s: invalid IP4 config received!", __func__);
g_free (addr);
}
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DNS);
if (val) {

View file

@ -37,6 +37,7 @@
#include <nm-gsm-device.h>
#include <nm-cdma-device.h>
#include <nm-utils.h>
#include <nm-setting-ip4-config.h>
static gboolean
get_nm_state (NMClient *client)
@ -303,24 +304,26 @@ detail_device (gpointer data, gpointer user_data)
/* IP Setup info */
if (state == NM_DEVICE_STATE_ACTIVATED) {
NMIP4Config *cfg = nm_device_get_ip4_config (device);
GSList *iter;
printf ("\n IP Settings:\n");
printf ("\n IPv4 Settings:\n");
tmp = ip4_address_as_string (nm_ip4_config_get_address (cfg));
print_string (" IP Address", 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_netmask (cfg));
print_string (" Subnet Mask", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->address);
print_string (" Address", tmp);
g_free (tmp);
tmp = ip4_address_as_string (nm_ip4_config_get_broadcast (cfg));
print_string (" Broadcast", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->netmask);
print_string (" Netmask", tmp);
g_free (tmp);
tmp = ip4_address_as_string (nm_ip4_config_get_gateway (cfg));
print_string (" Gateway", tmp);
g_free (tmp);
tmp = ip4_address_as_string (addr->gateway);
print_string (" Gateway", tmp);
g_free (tmp);
printf ("\n");
}
array = nm_ip4_config_get_nameservers (cfg);
if (array) {