2007-10-22 Tambet Ingo <tambet@gmail.com>

Implement support for static IP addresses, additional/overridden
DNS and
        DNS domain search lists.

        * libnm-util/nm-setting.c (uint_array_to_gvalue): Implement.
        (ip4_addresses_to_gvalue): Implement.
        (convert_array_to_byte_array): Implement.
        (nm_setting_populate_from_hash_default): Handle
NM_S_TYPE_UINT_ARRAY and
        NM_S_TYPE_IP4_ADDRESSES.
        (nm_setting_hash): Ditto.
        (default_setting_clear_secrets): Add a default case for the
switch: IP address
        shouldn't be secret, ever.
        (setting_ip4_config_verify): Update, requires addresses in case
of manual
        configurations.
        (setting_ip4_config_destroy): Free stuff.

        * src/nm-device.c (merge_ip4_config): Implement.
        (real_act_stage4_get_ip4_config): Merge IP4 configuration from
NMConnection.



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2996 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Tambet Ingo
2007-10-22 15:45:39 +00:00
parent a7f3b960f4
commit 7ba9c6e1c5
5 changed files with 188 additions and 32 deletions

View File

@@ -1,3 +1,23 @@
2007-10-22 Tambet Ingo <tambet@gmail.com>
Implement support for static IP addresses, additional/overridden DNS and
DNS domain search lists.
* libnm-util/nm-setting.c (uint_array_to_gvalue): Implement.
(ip4_addresses_to_gvalue): Implement.
(convert_array_to_byte_array): Implement.
(nm_setting_populate_from_hash_default): Handle NM_S_TYPE_UINT_ARRAY and
NM_S_TYPE_IP4_ADDRESSES.
(nm_setting_hash): Ditto.
(default_setting_clear_secrets): Add a default case for the switch: IP address
shouldn't be secret, ever.
(setting_ip4_config_verify): Update, requires addresses in case of manual
configurations.
(setting_ip4_config_destroy): Free stuff.
* src/nm-device.c (merge_ip4_config): Implement.
(real_act_stage4_get_ip4_config): Merge IP4 configuration from NMConnection.
2007-10-22 Dan Williams <dcbw@redhat.com> 2007-10-22 Dan Williams <dcbw@redhat.com>
* libnm-util/nm-setting.c * libnm-util/nm-setting.c

View File

@@ -252,6 +252,18 @@ byte_array_to_gvalue (GByteArray *array)
return val; return val;
} }
static GValue *
uint_array_to_gvalue (GArray *array)
{
GValue *val;
val = g_slice_new0 (GValue);
g_value_init (val, DBUS_TYPE_G_UINT_ARRAY);
g_value_set_boxed (val, array);
return val;
}
static GValue * static GValue *
slist_to_gvalue (GSList *list, GType type) slist_to_gvalue (GSList *list, GType type)
{ {
@@ -264,6 +276,36 @@ slist_to_gvalue (GSList *list, GType type)
return val; return val;
} }
static GValue *
ip4_addresses_to_gvalue (GSList *list)
{
GPtrArray *ptr_array;
GSList *iter;
GValue *val;
ptr_array = g_ptr_array_new ();
for (iter = list; iter; iter = iter->next) {
NMSettingIP4Address *ip4_addr = (NMSettingIP4Address *) iter->data;
GArray *array;
array = g_array_sized_new (FALSE, FALSE, 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);
g_ptr_array_add (ptr_array, array);
}
val = g_slice_new0 (GValue);
g_value_init (val, dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE_ARRAY));
g_value_set_boxed (val, ptr_array);
return val;
}
static GByteArray * static GByteArray *
convert_array_to_byte_array (GArray *array) convert_array_to_byte_array (GArray *array)
{ {
@@ -287,6 +329,33 @@ convert_strv_to_slist (char **str)
return g_slist_reverse (list); return g_slist_reverse (list);
} }
static GSList *
convert_ip4_addresses_to_slist (GPtrArray *array)
{
int i;
GSList *list = NULL;
for (i = 0; i < array->len; i++) {
GValueArray *value_array = (GValueArray *) g_ptr_array_index (array, i);
if (value_array->n_values == 2 || value_array->n_values == 3) {
NMSettingIP4Address *ip4_addr;
ip4_addr = g_new0 (NMSettingIP4Address, 1);
ip4_addr->address = g_value_get_uint (g_value_array_get_nth (value_array, 0));
ip4_addr->netmask = g_value_get_uint (g_value_array_get_nth (value_array, 1));
if (value_array->n_values == 3)
ip4_addr->gateway = g_value_get_uint (g_value_array_get_nth (value_array, 2));
list = g_slist_prepend (list, ip4_addr);
} else
nm_warning ("Ignoring invalid IP4 address");
}
return g_slist_reverse (list);
}
static gboolean static gboolean
string_in_list (const char *str, const char **valid_strings) string_in_list (const char *str, const char **valid_strings)
{ {
@@ -358,8 +427,16 @@ nm_setting_populate_from_hash_default (NMSetting *setting, GHashTable *table)
} else if ((m->type == NM_S_TYPE_STRING_ARRAY) && G_VALUE_HOLDS_BOXED (value)) { } else if ((m->type == NM_S_TYPE_STRING_ARRAY) && G_VALUE_HOLDS_BOXED (value)) {
GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset); GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset);
*val = convert_strv_to_slist ((char **) g_value_get_boxed (value)); *val = convert_strv_to_slist ((char **) g_value_get_boxed (value));
} } else if ((m->type == NM_S_TYPE_UINT_ARRAY) && G_VALUE_HOLDS_BOXED (value)) {
GArray **val = (GArray **) G_STRUCT_MEMBER_P (setting, m->offset);
GArray *tmp = (GArray *) g_value_get_boxed (value);
*val = g_array_sized_new (FALSE, FALSE, sizeof (guint32), tmp->len);
g_array_append_vals (*val, tmp->data, tmp->len);
} else if ((m->type == NM_S_TYPE_IP4_ADDRESSES) && G_VALUE_HOLDS_BOXED (value)) {
GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset);
*val = convert_ip4_addresses_to_slist ((GPtrArray *) g_value_get_boxed (value));
}
next: next:
m++; m++;
}; };
@@ -403,7 +480,9 @@ nm_setting_hash (NMSetting *setting)
ADD_MEMBER(NM_S_TYPE_UINT32, guint32, m->key, uint_to_gvalue) ADD_MEMBER(NM_S_TYPE_UINT32, guint32, m->key, uint_to_gvalue)
ADD_MEMBER(NM_S_TYPE_UINT64, guint64, m->key, uint64_to_gvalue) ADD_MEMBER(NM_S_TYPE_UINT64, guint64, m->key, uint64_to_gvalue)
ADD_MEMBER(NM_S_TYPE_BYTE_ARRAY, GByteArray *, m->key, byte_array_to_gvalue) ADD_MEMBER(NM_S_TYPE_BYTE_ARRAY, GByteArray *, m->key, byte_array_to_gvalue)
ADD_MEMBER(NM_S_TYPE_UINT_ARRAY, GArray *, m->key, uint_array_to_gvalue)
ADD_MEMBER_EXTRA(NM_S_TYPE_STRING_ARRAY, GSList *, m->key, slist_to_gvalue, G_TYPE_STRING) ADD_MEMBER_EXTRA(NM_S_TYPE_STRING_ARRAY, GSList *, m->key, slist_to_gvalue, G_TYPE_STRING)
ADD_MEMBER(NM_S_TYPE_IP4_ADDRESSES, GSList *, m->key, ip4_addresses_to_gvalue)
default: default:
break; break;
} }
@@ -457,6 +536,12 @@ default_setting_clear_secrets (NMSetting *setting)
*val = NULL; *val = NULL;
break; break;
} }
case NM_S_TYPE_UINT_ARRAY: {
GArray **val = (GArray **) G_STRUCT_MEMBER_P (setting, m->offset);
g_array_free (*val, TRUE);
*val = NULL;
break;
}
case NM_S_TYPE_STRING_ARRAY: { case NM_S_TYPE_STRING_ARRAY: {
GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset); GSList **val = (GSList **) G_STRUCT_MEMBER_P (setting, m->offset);
g_slist_foreach (*val, (GFunc) g_free, NULL); g_slist_foreach (*val, (GFunc) g_free, NULL);
@@ -464,6 +549,9 @@ default_setting_clear_secrets (NMSetting *setting)
*val = NULL; *val = NULL;
break; break;
} }
default:
break;
} }
next: next:
@@ -533,14 +621,11 @@ setting_ip4_config_verify (NMSetting *setting, GHashTable *all_settings)
{ {
NMSettingIP4Config *self = (NMSettingIP4Config *) setting; NMSettingIP4Config *self = (NMSettingIP4Config *) setting;
if (!self->address) { if (self->manual) {
g_warning ("address is not provided"); if (!self->addresses) {
return FALSE; g_warning ("address is not provided");
} return FALSE;
}
if (!self->netmask) {
g_warning ("netmask is not provided");
return FALSE;
} }
return TRUE; return TRUE;
@@ -551,14 +636,27 @@ setting_ip4_config_destroy (NMSetting *setting)
{ {
NMSettingIP4Config *self = (NMSettingIP4Config *) setting; NMSettingIP4Config *self = (NMSettingIP4Config *) setting;
if (self->dns)
g_array_free (self->dns, TRUE);
if (self->dns_search) {
g_slist_foreach (self->dns_search, (GFunc) g_free, NULL);
g_slist_free (self->dns_search);
}
if (self->addresses) {
g_slist_foreach (self->addresses, (GFunc) g_free, NULL);
g_slist_free (self->addresses);
}
g_slice_free (NMSettingIP4Config, self); g_slice_free (NMSettingIP4Config, self);
} }
static SettingMember ip4_config_table[] = { static SettingMember ip4_config_table[] = {
{ "manual", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingIP4Config, manual), FALSE, FALSE }, { "manual", NM_S_TYPE_BOOL, G_STRUCT_OFFSET (NMSettingIP4Config, manual), FALSE, FALSE },
{ "address", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingIP4Config, address), FALSE, FALSE }, { "dns", NM_S_TYPE_UINT_ARRAY, G_STRUCT_OFFSET (NMSettingIP4Config, dns), FALSE, FALSE },
{ "netmask", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingIP4Config, netmask), FALSE, FALSE }, { "dns-search", NM_S_TYPE_STRING_ARRAY, G_STRUCT_OFFSET (NMSettingIP4Config, dns_search), FALSE, FALSE },
{ "gateway", NM_S_TYPE_UINT32, G_STRUCT_OFFSET (NMSettingIP4Config, gateway), FALSE, FALSE }, { "addresses", NM_S_TYPE_IP4_ADDRESSES,G_STRUCT_OFFSET (NMSettingIP4Config, addresses), FALSE, FALSE },
{ NULL, 0, 0 }, { NULL, 0, 0 },
}; };

View File

@@ -40,6 +40,10 @@ typedef void (*NMSettingValueIterFn) (NMSetting *setting,
#define NM_S_TYPE_STRING_ARRAY 5 #define NM_S_TYPE_STRING_ARRAY 5
#define NM_S_TYPE_GVALUE_HASH 6 #define NM_S_TYPE_GVALUE_HASH 6
#define NM_S_TYPE_UINT64 7 #define NM_S_TYPE_UINT64 7
#define NM_S_TYPE_UINT_ARRAY 8
#define NM_S_TYPE_IP4_ADDRESSES 9
typedef struct SettingMember { typedef struct SettingMember {
const char *key; const char *key;
@@ -95,12 +99,18 @@ NMSetting *nm_setting_connection_new (void);
#define NM_SETTING_IP4_CONFIG "ipv4" #define NM_SETTING_IP4_CONFIG "ipv4"
typedef struct { typedef struct {
NMSetting parent;
gboolean manual;
guint32 address; guint32 address;
guint32 netmask; guint32 netmask;
guint32 gateway; guint32 gateway;
} NMSettingIP4Address;
typedef struct {
NMSetting parent;
gboolean manual;
GArray *dns;
GSList *dns_search; /* GSList of strings */
GSList *addresses; /* GSList of NMSettingIP4Address */
} NMSettingIP4Config; } NMSettingIP4Config;
NMSetting *nm_setting_ip4_config_new (void); NMSetting *nm_setting_ip4_config_new (void);

View File

@@ -680,21 +680,53 @@ nm_device_new_ip4_autoip_config (NMDevice *self)
} }
static void
merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
{
if (!setting)
return; /* Defaults are just fine */
if (setting->dns) {
int i;
for (i = 0; i < setting->dns->len; i++)
nm_ip4_config_add_nameserver (ip4_config, g_array_index (setting->dns, guint32, i));
}
if (setting->dns_search) {
GSList *iter;
for (iter = setting->dns_search; iter; iter = iter->next)
nm_ip4_config_add_domain (ip4_config, (char *) iter->data);
}
if (setting->addresses) {
/* FIXME; add support for more than one set of address/netmask/gateway for NMIP4Config */
if (setting->manual) {
NMSettingIP4Address *addr = (NMSettingIP4Address *) setting->addresses->data;
nm_ip4_config_set_address (ip4_config, addr->address);
nm_ip4_config_set_netmask (ip4_config, addr->netmask);
if (addr->gateway)
nm_ip4_config_set_gateway (ip4_config, addr->gateway);
}
}
}
static NMActStageReturn static NMActStageReturn
real_act_stage4_get_ip4_config (NMDevice *self, real_act_stage4_get_ip4_config (NMDevice *self,
NMIP4Config **config) NMIP4Config **config)
{ {
NMActRequest *req;
NMIP4Config * real_config = NULL; NMIP4Config * real_config = NULL;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMSettingIP4Config *setting;
g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
if (nm_device_get_use_dhcp (self)) { if (nm_device_get_use_dhcp (self)) {
real_config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, real_config = nm_dhcp_manager_get_ip4_config (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
nm_device_get_iface (self)); nm_device_get_iface (self));
if (real_config && nm_ip4_config_get_mtu (real_config) == 0) if (real_config && nm_ip4_config_get_mtu (real_config) == 0)
/* If the DHCP server doesn't set the MTU, get it from backend. */ /* If the DHCP server doesn't set the MTU, get it from backend. */
@@ -703,20 +735,14 @@ real_act_stage4_get_ip4_config (NMDevice *self,
real_config = nm_ip4_config_new (); real_config = nm_ip4_config_new ();
} }
req = nm_device_get_act_request (self);
setting = (NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req),
NM_SETTING_IP4_CONFIG);
if (real_config && setting) {
/* If settings are provided, use them, even if it means overriding the values we got from DHCP */
nm_ip4_config_set_address (real_config, setting->address);
nm_ip4_config_set_netmask (real_config, setting->netmask);
if (setting->gateway)
nm_ip4_config_set_gateway (real_config, setting->gateway);
}
if (real_config) { if (real_config) {
NMActRequest *req;
req = nm_device_get_act_request (self);
merge_ip4_config (real_config,
(NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req),
NM_SETTING_IP4_CONFIG));
*config = real_config; *config = real_config;
ret = NM_ACT_STAGE_RETURN_SUCCESS; ret = NM_ACT_STAGE_RETURN_SUCCESS;
} else { } else {

View File

@@ -1,3 +1,5 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager -- Network link manager /* NetworkManager -- Network link manager
* *
* Dan Williams <dcbw@redhat.com> * Dan Williams <dcbw@redhat.com>