libnm-core: add NMSettingIPConfig:gateway, drop NMIPAddress:gateway

The gateway is a global property of the IPv4/IPv6 configuration, not
an attribute of any particular address. So represent it as such in the
API; remove the gateway from NMIPAddress, and add it to
NMSettingIPConfig.

Behind the scenes, the gateway is still serialized along with the
first address in NMSettingIPConfig:addresses, and is deserialized from
that if the settings dictionary doesn't contain a 'gateway' key.

Adjust nmcli's interactive mode to prompt for IP addresses and gateway
separately. (Patch partly from Jirka Klimeš.)
This commit is contained in:
Dan Winship 2014-10-20 21:30:56 -04:00
parent 329791ad55
commit f17699f4e3
33 changed files with 899 additions and 628 deletions

View file

@ -92,7 +92,7 @@ static GSList *
construct_ip4_items (GSList *items, GVariant *ip4_config, const char *prefix)
{
GPtrArray *addresses, *routes;
char **dns, **wins;
char **dns, **wins, *gateway;
GString *tmp;
GVariant *val;
int i;
@ -106,26 +106,24 @@ construct_ip4_items (GSList *items, GVariant *ip4_config, const char *prefix)
/* IP addresses */
val = g_variant_lookup_value (ip4_config, "addresses", G_VARIANT_TYPE ("aau"));
if (val) {
addresses = nm_utils_ip4_addresses_from_variant (val);
addresses = nm_utils_ip4_addresses_from_variant (val, &gateway);
if (!gateway)
gateway = g_strdup ("0.0.0.0");
for (i = 0; i < addresses->len; i++) {
NMIPAddress *addr = addresses->pdata[i];
const char *gw;
char *addrtmp;
gw = nm_ip_address_get_gateway (addr);
if (!gw)
gw = "0.0.0.0";
addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, i,
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr),
gw);
gateway);
items = g_slist_prepend (items, addrtmp);
}
if (addresses->len)
items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, addresses->len));
g_ptr_array_unref (addresses);
g_free (gateway);
g_variant_unref (val);
}
@ -228,7 +226,7 @@ static GSList *
construct_ip6_items (GSList *items, GVariant *ip6_config, const char *prefix)
{
GPtrArray *addresses, *routes;
char **dns;
char **dns, *gateway = NULL;
GString *tmp;
GVariant *val;
int i;
@ -242,26 +240,24 @@ construct_ip6_items (GSList *items, GVariant *ip6_config, const char *prefix)
/* IP addresses */
val = g_variant_lookup_value (ip6_config, "addresses", G_VARIANT_TYPE ("a(ayuay)"));
if (val) {
addresses = nm_utils_ip6_addresses_from_variant (val);
addresses = nm_utils_ip6_addresses_from_variant (val, &gateway);
if (!gateway)
gateway = g_strdup ("::");
for (i = 0; i < addresses->len; i++) {
NMIPAddress *addr = addresses->pdata[i];
const char *gw;
char *addrtmp;
gw = nm_ip_address_get_gateway (addr);
if (!gw)
gw = "::";
addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, i,
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr),
gw);
gateway);
items = g_slist_prepend (items, addrtmp);
}
if (addresses->len)
items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, addresses->len));
g_ptr_array_unref (addresses);
g_free (gateway);
g_variant_unref (val);
}

View file

@ -183,6 +183,7 @@ parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **err
char *tmp;
char **split, **iter;
GPtrArray *addresses, *routes;
const char *gateway = NULL;
g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}"));
@ -221,7 +222,7 @@ parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **err
addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
for (iter = split; iter && *iter; iter++) {
NMIPAddress *addr;
char *ip, *prefix, *gw;
char *ip, *prefix;
if (strlen (g_strstrip (*iter)) == 0)
continue;
@ -232,11 +233,13 @@ parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **err
g_assert (prefix);
*prefix++ = '\0';
gw = strchr (prefix, ' ');
g_assert (gw);
gw++;
if (addresses->len == 0) {
gateway = strchr (prefix, ' ');
g_assert (gateway);
gateway++;
}
addr = nm_ip_address_new (AF_INET, ip, (guint) atoi (prefix), gw, error);
addr = nm_ip_address_new (AF_INET, ip, (guint) atoi (prefix), error);
if (!addr) {
g_ptr_array_unref (addresses);
return FALSE;
@ -245,7 +248,7 @@ parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **err
}
g_variant_builder_add (&props, "{sv}", "addresses",
nm_utils_ip4_addresses_to_variant (addresses));
nm_utils_ip4_addresses_to_variant (addresses, gateway));
g_ptr_array_unref (addresses);
}
g_strfreev (split);

View file

@ -82,6 +82,7 @@ print_ip4_config (NMIP4Config *cfg4,
const char *one_field)
{
GPtrArray *ptr_array;
const char *gw;
char **addr_arr = NULL;
char **route_arr = NULL;
char **dns_arr = NULL;
@ -103,20 +104,16 @@ print_ip4_config (NMIP4Config *cfg4,
/* addresses */
ptr_array = nm_ip4_config_get_addresses (cfg4);
gw = nm_ip4_config_get_gateway (cfg4);
if (ptr_array) {
addr_arr = g_new (char *, ptr_array->len + 1);
for (i = 0; i < ptr_array->len; i++) {
NMIPAddress *addr = (NMIPAddress *) g_ptr_array_index (ptr_array, i);
const char *gw;
gw = nm_ip_address_get_gateway (addr);
if (!gw)
gw = "0.0.0.0";
addr_arr[i] = g_strdup_printf ("ip = %s/%u, gw = %s",
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr),
gw);
(i == 0) && gw ? gw : "0.0.0.0");
}
addr_arr[i] = NULL;
}
@ -175,6 +172,7 @@ print_ip6_config (NMIP6Config *cfg6,
const char *one_field)
{
GPtrArray *ptr_array;
const char *gw;
char **addr_arr = NULL;
char **route_arr = NULL;
char **dns_arr = NULL;
@ -195,20 +193,16 @@ print_ip6_config (NMIP6Config *cfg6,
/* addresses */
ptr_array = nm_ip6_config_get_addresses (cfg6);
gw = nm_ip6_config_get_gateway (cfg6);
if (ptr_array) {
addr_arr = g_new (char *, ptr_array->len + 1);
for (i = 0; i < ptr_array->len; i++) {
NMIPAddress *addr = (NMIPAddress *) g_ptr_array_index (ptr_array, i);
const char *gw;
gw = nm_ip_address_get_gateway (addr);
if (!gw)
gw = "::";
addr_arr[i] = g_strdup_printf ("ip = %s/%u, gw = %s",
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr),
gw);
(i == 0) && gw ? gw : "::");
}
addr_arr[i] = NULL;
}
@ -355,10 +349,9 @@ print_dhcp6_config (NMDhcp6Config *dhcp6,
/*
* Parse IP address from string to NMIPAddress stucture.
* ip_str is the IP address in the form address/prefix
* gw_str is the gateway address (it is optional)
*/
NMIPAddress *
nmc_parse_and_build_address (int family, const char *ip_str, const char *gw_str, GError **error)
nmc_parse_and_build_address (int family, const char *ip_str, GError **error)
{
int max_prefix = (family == AF_INET) ? 32 : 128;
NMIPAddress *addr = NULL;
@ -387,7 +380,7 @@ nmc_parse_and_build_address (int family, const char *ip_str, const char *gw_str,
}
}
addr = nm_ip_address_new (family, ip, (guint32) prefix, gw_str, &local);
addr = nm_ip_address_new (family, ip, (guint32) prefix, &local);
if (!addr) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("invalid IP address: %s"), local->message);

View file

@ -29,7 +29,7 @@ gboolean print_ip6_config (NMIP6Config *cfg6, NmCli *nmc, const char *group_pref
gboolean print_dhcp4_config (NMDhcp4Config *dhcp4, NmCli *nmc, const char *group_prefix, const char *one_field);
gboolean print_dhcp6_config (NMDhcp6Config *dhcp6, NmCli *nmc, const char *group_prefix, const char *one_field);
NMIPAddress *nmc_parse_and_build_address (int family, const char *ip_str, const char *gw_str, GError **error);
NMIPAddress *nmc_parse_and_build_address (int family, const char *ip_str, GError **error);
NMIPRoute *nmc_parse_and_build_route (int family, const char *first, const char *second, const char *third, GError **error);
const char * nmc_device_state_to_string (NMDeviceState state);

View file

@ -3811,24 +3811,21 @@ do_questionnaire_olpc (char **channel, char **dhcp_anycast)
}
static gboolean
split_address (char* str, char **ip, char **gw, char **rest)
split_address (char* str, char **ip, char **rest)
{
size_t n1, n2, n3, n4, n5;
size_t n1, n2, n3;
*ip = *gw = *rest = NULL;
*ip = *rest = NULL;
if (!str)
return FALSE;
n1 = strspn (str, " \t");
n2 = strcspn (str+n1, " \t\0") + n1;
n3 = strspn (str+n2, " \t") + n2;
n4 = strcspn (str+n3, " \t\0") + n3;
n5 = strspn (str+n4, " \t") + n4;
str[n2] = str[n4] = '\0';
str[n2] = '\0';
*ip = str[n1] ? str + n1 : NULL;
*gw = str[n3] ? str + n3 : NULL;
*rest = str[n5] ? str + n5 : NULL;
*rest = str[n3] ? str + n3 : NULL;
return TRUE;
}
@ -3838,32 +3835,31 @@ ask_for_ip_addresses (NMConnection *connection, int family)
{
gboolean ip_loop;
GError *error = NULL;
char *str, *ip, *gw, *rest;
char *str, *ip, *rest;
const char *prompt;
gboolean added;
NMIPAddress *ipaddr;
if (family == AF_INET)
prompt =_("IPv4 address (IP[/plen] [gateway]) [none]: ");
prompt =_("IPv4 address (IP[/plen]) [none]: ");
else
prompt =_("IPv6 address (IP[/plen] [gateway]) [none]: ");
prompt =_("IPv6 address (IP[/plen]) [none]: ");
ip_loop = TRUE;
do {
str = nmc_readline ("%s", prompt);
split_address (str, &ip, &gw, &rest);
split_address (str, &ip, &rest);
if (ip) {
ipaddr = nmc_parse_and_build_address (family, ip, gw, &error);
ipaddr = nmc_parse_and_build_address (family, ip, &error);
if (ipaddr) {
if (family == AF_INET)
added = add_ip4_address_to_connection (ipaddr, connection);
else
added = add_ip6_address_to_connection (ipaddr, connection);
gw = gw ? gw : (family == AF_INET) ? "0.0.0.0" : "::";
if (added)
g_print (_(" Address successfully added: %s %s\n"), ip, gw);
g_print (_(" Address successfully added: %s\n"), ip);
else
g_print (_(" Warning: address already present: %s %s\n"), ip, gw);
g_print (_(" Warning: address already present: %s\n"), ip);
if (rest)
g_print (_(" Warning: ignoring garbage at the end: '%s'\n"), rest);
} else {
@ -3878,6 +3874,45 @@ ask_for_ip_addresses (NMConnection *connection, int family)
} while (ip_loop);
}
static void
maybe_ask_for_gateway (NMConnection *connection, int family)
{
gboolean gw_loop;
char *str, *gw, *rest;
const char *prompt;
NMSettingIPConfig *s_ip;
if (family == AF_INET) {
prompt =_("IPv4 gateway [none]: ");
s_ip = nm_connection_get_setting_ip4_config (connection);
} else {
prompt =_("IPv6 gateway [none]: ");
s_ip = nm_connection_get_setting_ip6_config (connection);
}
if (s_ip == NULL)
return;
if ( nm_setting_ip_config_get_num_addresses (s_ip) == 0
|| nm_setting_ip_config_get_gateway (s_ip) != NULL)
return;
gw_loop = TRUE;
do {
str = nmc_readline ("%s", prompt);
split_address (str, &gw, &rest);
if (gw) {
if (nm_utils_ipaddr_valid (family, gw)) {
g_object_set (s_ip,
NM_SETTING_IP_CONFIG_GATEWAY, gw,
NULL);
gw_loop = FALSE;
} else
g_print (_("Error: invalid gateway address '%s'\n"), gw);
} else
gw_loop = FALSE;
g_free (str);
} while (gw_loop);
}
static void
do_questionnaire_ip (NMConnection *connection)
{
@ -3890,14 +3925,14 @@ do_questionnaire_ip (NMConnection *connection)
g_free (answer);
return;
}
g_free (answer);
g_print (_("Press <Enter> to finish adding addresses.\n"));
ask_for_ip_addresses (connection, AF_INET);
maybe_ask_for_gateway (connection, AF_INET);
ask_for_ip_addresses (connection, AF_INET6);
g_free (answer);
return;
maybe_ask_for_gateway (connection, AF_INET6);
}
static gboolean
@ -5168,7 +5203,7 @@ cleanup_olpc:
/* coverity[dead_error_begin] */
if (ip4) {
ip4addr = nmc_parse_and_build_address (AF_INET, ip4, gw4, error);
ip4addr = nmc_parse_and_build_address (AF_INET, ip4, error);
if (!ip4addr) {
g_prefix_error (error, _("Error: "));
return FALSE;
@ -5176,15 +5211,59 @@ cleanup_olpc:
add_ip4_address_to_connection (ip4addr, connection);
}
if (gw4) {
NMSettingIPConfig *s_ip = nm_connection_get_setting_ip4_config (connection);
if (!s_ip) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: IPv4 gateway specified without IPv4 addresses"));
return FALSE;
} else if (nm_setting_ip_config_get_gateway (s_ip)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: multiple IPv4 gateways specified"));
return FALSE;
} else if (!nm_utils_ipaddr_valid (AF_INET, gw4)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: Invalid IPv4 gateway '%s'"),
gw4);
}
g_object_set (s_ip,
NM_SETTING_IP_CONFIG_GATEWAY, gw4,
NULL);
}
/* coverity[dead_error_begin] */
if (ip6) {
ip6addr = nmc_parse_and_build_address (AF_INET6, ip6, gw6, error);
ip6addr = nmc_parse_and_build_address (AF_INET6, ip6, error);
if (!ip6addr) {
g_prefix_error (error, _("Error: "));
return FALSE;
}
add_ip6_address_to_connection (ip6addr, connection);
}
if (gw6) {
NMSettingIPConfig *s_ip = nm_connection_get_setting_ip6_config (connection);
if (!s_ip) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: IPv6 gateway specified without IPv6 addresses"));
return FALSE;
} else if (nm_setting_ip_config_get_gateway (s_ip)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: multiple IPv6 gateways specified"));
return FALSE;
} else if (!nm_utils_ipaddr_valid (AF_INET, gw6)) {
g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: Invalid IPv6 gateway '%s'"),
gw6);
}
g_object_set (s_ip,
NM_SETTING_IP_CONFIG_GATEWAY, gw6,
NULL);
}
}
/* Ask for addresses if '--ask' is specified. */

View file

@ -257,14 +257,15 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS, 20), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH, 15), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES, 20), /* 4 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES, 20), /* 5 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, 19), /* 6 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, 16), /* 7 */
SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, 15), /* 8 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, 19), /* 9 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, 14), /* 10 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, 15), /* 11 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL, 12), /* 12 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY, 20), /* 5 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES, 20), /* 7 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, 19), /* 7 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, 16), /* 8 */
SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, 15), /* 9 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, 19), /* 10 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, 14), /* 11 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, 15), /* 12 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL, 12), /* 13 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP4_CONFIG_ALL "name"","\
@ -272,6 +273,7 @@ NmcOutputField nmc_fields_setting_ip4_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES","\
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS","\
@ -289,14 +291,15 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS, 20), /* 2 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DNS_SEARCH, 15), /* 3 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ADDRESSES, 20), /* 4 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES, 20), /* 5 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, 19), /* 6 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, 16), /* 7 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, 15), /* 8 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL, 12), /* 9 */
SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, 15), /* 10 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, 19), /* 11 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, 14), /* 12 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_GATEWAY, 20), /* 5 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_ROUTES, 20), /* 6 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, 19), /* 7 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, 16), /* 8 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, 15), /* 9 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_MAY_FAIL, 12), /* 10 */
SETTING_FIELD (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, 15), /* 11 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, 19), /* 12 */
SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, 14), /* 13 */
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
};
#define NMC_FIELDS_SETTING_IP6_CONFIG_ALL "name"","\
@ -304,6 +307,7 @@ NmcOutputField nmc_fields_setting_ip6_config[] = {
NM_SETTING_IP_CONFIG_DNS","\
NM_SETTING_IP_CONFIG_DNS_SEARCH","\
NM_SETTING_IP_CONFIG_ADDRESSES","\
NM_SETTING_IP_CONFIG_GATEWAY","\
NM_SETTING_IP_CONFIG_ROUTES","\
NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES","\
NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS","\
@ -1207,34 +1211,25 @@ DEFINE_GETTER (nmc_property_ipv4_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv4_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
static char *
nmc_property_ipv4_get_addresses (NMSetting *setting)
nmc_property_ip_get_addresses (NMSetting *setting)
{
NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (setting);
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
GString *printable;
guint32 num_addresses, i;
NMIPAddress *addr;
printable = g_string_new (NULL);
num_addresses = nm_setting_ip_config_get_num_addresses (s_ip4);
num_addresses = nm_setting_ip_config_get_num_addresses (s_ip);
for (i = 0; i < num_addresses; i++) {
addr = nm_setting_ip_config_get_address (s_ip4, i);
addr = nm_setting_ip_config_get_address (s_ip, i);
if (printable->len > 0)
g_string_append (printable, "; ");
g_string_append (printable, ", ");
g_string_append (printable, "{ ");
g_string_append_printf (printable, "ip = %s/%u",
g_string_append_printf (printable, "%s/%u",
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr));
if (nm_ip_address_get_gateway (addr)) {
g_string_append_printf (printable, ", gw = %s",
nm_ip_address_get_gateway (addr));
}
g_string_append (printable, " }");
}
return g_string_free (printable, FALSE);
@ -1277,6 +1272,7 @@ nmc_property_ipv4_get_routes (NMSetting *setting)
return g_string_free (printable, FALSE);
}
DEFINE_GETTER (nmc_property_ipv4_get_gateway, NM_SETTING_IP_CONFIG_GATEWAY)
DEFINE_GETTER (nmc_property_ipv4_get_ignore_auto_routes, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES)
DEFINE_GETTER (nmc_property_ipv4_get_ignore_auto_dns, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS)
DEFINE_GETTER (nmc_property_ipv4_get_dhcp_client_id, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID)
@ -1290,40 +1286,6 @@ DEFINE_GETTER (nmc_property_ipv6_get_method, NM_SETTING_IP_CONFIG_METHOD)
DEFINE_GETTER (nmc_property_ipv6_get_dns, NM_SETTING_IP_CONFIG_DNS)
DEFINE_GETTER (nmc_property_ipv6_get_dns_search, NM_SETTING_IP_CONFIG_DNS_SEARCH)
static char *
nmc_property_ipv6_get_addresses (NMSetting *setting)
{
NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (setting);
GString *printable;
guint32 num_addresses, i;
NMIPAddress *addr;
printable = g_string_new (NULL);
num_addresses = nm_setting_ip_config_get_num_addresses (s_ip6);
for (i = 0; i < num_addresses; i++) {
addr = nm_setting_ip_config_get_address (s_ip6, i);
if (printable->len > 0)
g_string_append (printable, "; ");
g_string_append (printable, "{ ");
g_string_append_printf (printable, "ip = %s/%u",
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr));
if (nm_ip_address_get_gateway (addr)) {
g_string_append_printf (printable, ", gw = %s",
nm_ip_address_get_gateway (addr));
}
g_string_append (printable, " }");
}
return g_string_free (printable, FALSE);
}
static char *
nmc_property_ipv6_get_routes (NMSetting *setting)
{
@ -1361,6 +1323,7 @@ nmc_property_ipv6_get_routes (NMSetting *setting)
return g_string_free (printable, FALSE);
}
DEFINE_GETTER (nmc_property_ipv6_get_gateway, NM_SETTING_IP_CONFIG_GATEWAY)
DEFINE_GETTER (nmc_property_ipv6_get_ignore_auto_routes, NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES)
DEFINE_GETTER (nmc_property_ipv6_get_ignore_auto_dns, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS)
DEFINE_GETTER (nmc_property_ipv6_get_never_default, NM_SETTING_IP_CONFIG_NEVER_DEFAULT)
@ -3075,20 +3038,10 @@ static NMIPAddress *
_parse_ip_address (int family, const char *address, GError **error)
{
char *value = g_strdup (address);
char **addrv;
NMIPAddress *ipaddr;
addrv = nmc_strsplit_set (g_strstrip (value), " \t", 0);
if (addrv[0] == NULL || g_strv_length (addrv) > 2) {
g_set_error (error, 1, 0, _("'%s' is not valid (use ip[/prefix] [gateway])"),
address);
g_free (value);
g_strfreev (addrv);
return NULL;
}
ipaddr = nmc_parse_and_build_address (family, addrv[0], addrv[1], error);
ipaddr = nmc_parse_and_build_address (family, g_strstrip (value), error);
g_free (value);
g_strfreev (addrv);
return ipaddr;
}
@ -3292,44 +3245,31 @@ static const char *
nmc_property_ipv4_describe_addresses (NMSetting *setting, const char *prop)
{
return _("Enter a list of IPv4 addresses formatted as:\n"
" ip[/prefix] [gateway], ip[/prefix] [gateway],...\n"
" ip[/prefix], ip[/prefix],...\n"
"Missing prefix is regarded as prefix of 32.\n\n"
"Example: 192.168.1.5/24 192.168.1.1, 10.0.0.11/24\n");
"Example: 192.168.1.5/24, 10.0.0.11/24\n");
}
/*
* from: { ip = 1.2.3.4/24, gw = 1.2.3.254 }; { ip = 2.2.2.2/16, gw = 5.5.5.5 }
* to: 1.2.3.4/24 1.2.3.254, 2.2.2.2/16 5.5.5.5
* from: { ip = 11::22/64, gw = 22::33 }; { ip = ab::cd/64, gw = ab::1 }
* to: 11::22/64 22:33, ab::cd/64 ab::1
*/
static char *
nmc_property_out2in_addresses (const char *out_format)
/* 'gateway' */
static gboolean
nmc_property_ipv4_set_gateway (NMSetting *setting, const char *prop, const char *val, GError **error)
{
GRegex *regex;
GString *str;
char **strv;
int i;
NMIPAddress *ip4addr;
str = g_string_sized_new (128);
regex = g_regex_new ("\\{ ip = ([^/]+)/([^,]+), gw = ([^ ]+) \\}", 0, 0, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
strv = g_regex_split (regex, out_format, 0);
for (i = 1; strv && strv[i] && strv[i+1] && strv[i+2]; i=i+4) {
g_string_append (str, strv[i]); /* IP */
g_string_append_c (str, '/');
g_string_append (str, strv[i+1]); /* prefix */
g_string_append_c (str, ' ');
g_string_append (str, strv[i+2]); /* gateway */
g_string_append (str, ", ");
if (strchr (val, '/')) {
g_set_error (error, 1, 0,
_("invalid gateway address '%s'"), val);
return FALSE;
}
if (str->len > 0)
g_string_truncate (str, str->len - 2);
ip4addr = _parse_ipv4_address (val, error);
if (!ip4addr)
return FALSE;
g_strfreev (strv);
g_regex_unref (regex);
return g_string_free (str, FALSE);
g_object_set (setting, prop, val, NULL);
nm_ip_address_unref (ip4addr);
return TRUE;
}
/* 'routes' */
@ -3611,9 +3551,31 @@ static const char *
nmc_property_ipv6_describe_addresses (NMSetting *setting, const char *prop)
{
return _("Enter a list of IPv6 addresses formatted as:\n"
" ip[/prefix] [gateway], ip[/prefix] [gateway],...\n"
" ip[/prefix], ip[/prefix],...\n"
"Missing prefix is regarded as prefix of 128.\n\n"
"Example: 2607:f0d0:1002:51::4/64 2607:f0d0:1002:51::1, 1050:0:0:0:5:600:300c:326b\n");
"Example: 2607:f0d0:1002:51::4/64, 1050:0:0:0:5:600:300c:326b\n");
}
/* 'gateway' */
static gboolean
nmc_property_ipv6_set_gateway (NMSetting *setting, const char *prop, const char *val, GError **error)
{
NMIPAddress *ip6addr;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (strchr (val, '/')) {
g_set_error (error, 1, 0,
_("invalid gateway address '%s'"), val);
return FALSE;
}
ip6addr = _parse_ipv6_address (val, error);
if (!ip6addr)
return FALSE;
g_object_set (setting, prop, val, NULL);
nm_ip_address_unref (ip6addr);
return TRUE;
}
/* 'routes' */
@ -5448,12 +5410,19 @@ nmc_properties_init (void)
NULL,
NULL);
nmc_add_prop_funcs (GLUE_IP (4, ADDRESSES),
nmc_property_ipv4_get_addresses,
nmc_property_ip_get_addresses,
nmc_property_ipv4_set_addresses,
nmc_property_ipv4_remove_addresses,
nmc_property_ipv4_describe_addresses,
NULL,
nmc_property_out2in_addresses);
NULL);
nmc_add_prop_funcs (GLUE_IP (4, GATEWAY),
nmc_property_ipv4_get_gateway,
nmc_property_ipv4_set_gateway,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE_IP (4, ROUTES),
nmc_property_ipv4_get_routes,
nmc_property_ipv4_set_routes,
@ -5534,12 +5503,19 @@ nmc_properties_init (void)
NULL,
NULL);
nmc_add_prop_funcs (GLUE_IP (6, ADDRESSES),
nmc_property_ipv6_get_addresses,
nmc_property_ip_get_addresses,
nmc_property_ipv6_set_addresses,
nmc_property_ipv6_remove_addresses,
nmc_property_ipv6_describe_addresses,
NULL,
nmc_property_out2in_addresses);
NULL);
nmc_add_prop_funcs (GLUE_IP (6, GATEWAY),
nmc_property_ipv6_get_gateway,
nmc_property_ipv6_set_gateway,
NULL,
NULL,
NULL,
NULL);
nmc_add_prop_funcs (GLUE_IP (6, ROUTES),
nmc_property_ipv6_get_routes,
nmc_property_ipv6_set_routes,
@ -6746,15 +6722,16 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 1, nmc_property_ipv4_get_method (setting));
set_val_str (arr, 2, nmc_property_ipv4_get_dns (setting));
set_val_str (arr, 3, nmc_property_ipv4_get_dns_search (setting));
set_val_str (arr, 4, nmc_property_ipv4_get_addresses (setting));
set_val_str (arr, 5, nmc_property_ipv4_get_routes (setting));
set_val_str (arr, 6, nmc_property_ipv4_get_ignore_auto_routes (setting));
set_val_str (arr, 7, nmc_property_ipv4_get_ignore_auto_dns (setting));
set_val_str (arr, 8, nmc_property_ipv4_get_dhcp_client_id (setting));
set_val_str (arr, 9, nmc_property_ipv4_get_dhcp_send_hostname (setting));
set_val_str (arr, 10, nmc_property_ipv4_get_dhcp_hostname (setting));
set_val_str (arr, 11, nmc_property_ipv4_get_never_default (setting));
set_val_str (arr, 12, nmc_property_ipv4_get_may_fail (setting));
set_val_str (arr, 4, nmc_property_ip_get_addresses (setting));
set_val_str (arr, 5, nmc_property_ipv4_get_gateway (setting));
set_val_str (arr, 6, nmc_property_ipv4_get_routes (setting));
set_val_str (arr, 7, nmc_property_ipv4_get_ignore_auto_routes (setting));
set_val_str (arr, 8, nmc_property_ipv4_get_ignore_auto_dns (setting));
set_val_str (arr, 9, nmc_property_ipv4_get_dhcp_client_id (setting));
set_val_str (arr, 10, nmc_property_ipv4_get_dhcp_send_hostname (setting));
set_val_str (arr, 11, nmc_property_ipv4_get_dhcp_hostname (setting));
set_val_str (arr, 12, nmc_property_ipv4_get_never_default (setting));
set_val_str (arr, 13, nmc_property_ipv4_get_may_fail (setting));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */
@ -6783,15 +6760,16 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro
set_val_str (arr, 1, nmc_property_ipv6_get_method (setting));
set_val_str (arr, 2, nmc_property_ipv6_get_dns (setting));
set_val_str (arr, 3, nmc_property_ipv6_get_dns_search (setting));
set_val_str (arr, 4, nmc_property_ipv6_get_addresses (setting));
set_val_str (arr, 5, nmc_property_ipv6_get_routes (setting));
set_val_str (arr, 6, nmc_property_ipv6_get_ignore_auto_routes (setting));
set_val_str (arr, 7, nmc_property_ipv6_get_ignore_auto_dns (setting));
set_val_str (arr, 8, nmc_property_ipv6_get_never_default (setting));
set_val_str (arr, 9, nmc_property_ipv6_get_may_fail (setting));
set_val_str (arr, 10, nmc_property_ipv6_get_ip6_privacy (setting));
set_val_str (arr, 11, nmc_property_ipv6_get_dhcp_send_hostname (setting));
set_val_str (arr, 12, nmc_property_ipv6_get_dhcp_hostname (setting));
set_val_str (arr, 4, nmc_property_ip_get_addresses (setting));
set_val_str (arr, 5, nmc_property_ipv6_get_gateway (setting));
set_val_str (arr, 6, nmc_property_ipv6_get_routes (setting));
set_val_str (arr, 7, nmc_property_ipv6_get_ignore_auto_routes (setting));
set_val_str (arr, 8, nmc_property_ipv6_get_ignore_auto_dns (setting));
set_val_str (arr, 9, nmc_property_ipv6_get_never_default (setting));
set_val_str (arr, 10, nmc_property_ipv6_get_may_fail (setting));
set_val_str (arr, 11, nmc_property_ipv6_get_ip6_privacy (setting));
set_val_str (arr, 12, nmc_property_ipv6_get_dhcp_send_hostname (setting));
set_val_str (arr, 13, nmc_property_ipv6_get_dhcp_hostname (setting));
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */

View file

@ -156,7 +156,7 @@ ip_addresses_with_prefix_from_strv (GBinding *binding,
int i;
strings = g_value_get_boxed (source_value);
/* Fetch the original property value, so as to preserve the gateway elements */
/* Fetch the original property value, so as to preserve their extra attributes */
g_object_get (g_binding_get_source (binding),
g_binding_get_source_property (binding), &addrs,
NULL);
@ -164,9 +164,9 @@ ip_addresses_with_prefix_from_strv (GBinding *binding,
for (i = 0; strings[i]; i++) {
if (i >= addrs->len) {
if (family == AF_INET)
addr = nm_ip_address_new (AF_INET, "0.0.0.0", 32, NULL, NULL);
addr = nm_ip_address_new (AF_INET, "0.0.0.0", 32, NULL);
else
addr = nm_ip_address_new (AF_INET6, "::", 128, NULL, NULL);
addr = nm_ip_address_new (AF_INET6, "::", 128, NULL);
g_ptr_array_add (addrs, addr);
} else
addr = addrs->pdata[i];
@ -202,9 +202,7 @@ ip_addresses_with_prefix_from_strv (GBinding *binding,
*
* Each #NMIPAddress in @source_property will be converted to a string of the
* form "ip.ad.dr.ess/prefix" or "ip:ad:dr:ess/prefix" in @target_property (and
* vice versa if %G_BINDING_BIDIRECTIONAL) is specified. The "gateway" fields in
* @source_property are ignored when converting to strings, and unmodified when
* converting from strings.
* vice versa if %G_BINDING_BIDIRECTIONAL) is specified.
*/
void
nm_editor_bind_ip_addresses_with_prefix_to_strv (int family,
@ -274,108 +272,6 @@ nm_editor_bind_ip_addresses_to_strv (int family,
GINT_TO_POINTER (family), NULL);
}
static gboolean
ip_gateway_to_string (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
GPtrArray *addrs;
NMIPAddress *addr;
const char *gateway = NULL;
int i;
addrs = g_value_get_boxed (source_value);
for (i = 0; i < addrs->len; i++) {
addr = addrs->pdata[i];
gateway = nm_ip_address_get_gateway (addr);
if (gateway)
break;
}
if (!gateway)
gateway = "";
g_value_set_string (target_value, gateway);
return TRUE;
}
static gboolean
ip_gateway_from_string (GBinding *binding,
const GValue *source_value,
GValue *target_value,
gpointer user_data)
{
int family = GPOINTER_TO_INT (user_data);
const char *text;
GPtrArray *addrs;
NMIPAddress *addr;
int i;
text = g_value_get_string (source_value);
if (*text) {
if (!nm_utils_ipaddr_valid (family, text))
return FALSE;
} else
text = NULL;
/* Fetch the original property value, so as to preserve the IP address elements */
g_object_get (g_binding_get_source (binding),
g_binding_get_source_property (binding), &addrs,
NULL);
if (!addrs->len) {
g_ptr_array_unref (addrs);
return FALSE;
}
addr = addrs->pdata[0];
if (!g_strcmp0 (text, nm_ip_address_get_gateway (addr))) {
g_ptr_array_unref (addrs);
return FALSE;
}
nm_ip_address_set_gateway (addr, text);
for (i = 1; i < addrs->len; i++) {
addr = addrs->pdata[i];
nm_ip_address_set_gateway (addr, NULL);
}
g_value_take_boxed (target_value, addrs);
return TRUE;
}
/**
* nm_editor_bind_ip_gateway_to_string:
* @family: the IP address family
* @source: the source object (eg, an #NMSettingIP4Config)
* @source_property: the property on @source to bind (eg,
* %NM_SETTING_IP4_CONFIG_ADDRESSES)
* @target: the target object (eg, an #NmtNewtEntry)
* @target_property: the property on @target to bind
* (eg, "text")
* @flags: %GBindingFlags
*
* Binds the #GPtrArray-of-#NMIPRoute property @source_property on @source to
* the %G_TYPE_STRING property @target_property on @target.
*
* Specifically, this binds the "gateway" field of the first address in
* @source_property; all other addresses in @source_property are ignored, and
* its "address" and "prefix" fields are unmodified.
*/
void
nm_editor_bind_ip_gateway_to_string (int family,
gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags)
{
g_object_bind_property_full (source, source_property,
target, target_property,
flags,
ip_gateway_to_string,
ip_gateway_from_string,
GINT_TO_POINTER (family), NULL);
}
static gboolean
ip_route_transform_to_dest_string (GBinding *binding,
const GValue *source_value,

View file

@ -37,12 +37,6 @@ void nm_editor_bind_ip_addresses_to_strv (int family,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip_gateway_to_string (int family,
gpointer source,
const gchar *source_property,
gpointer target,
const gchar *target_property,
GBindingFlags flags);
void nm_editor_bind_ip_route_to_strings (int family,
gpointer source,

View file

@ -145,10 +145,9 @@ nmt_page_ip4_constructed (GObject *object)
nmt_page_grid_append (grid, _("Addresses"), widget, NULL);
widget = nmt_ip_entry_new (25, AF_INET, FALSE, TRUE);
nm_editor_bind_ip_gateway_to_string (AF_INET,
s_ip4, NM_SETTING_IP_CONFIG_ADDRESSES,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Gateway"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP4);

View file

@ -145,10 +145,9 @@ nmt_page_ip6_constructed (GObject *object)
nmt_page_grid_append (grid, _("Addresses"), widget, NULL);
widget = nmt_ip_entry_new (25, AF_INET6, FALSE, TRUE);
nm_editor_bind_ip_gateway_to_string (AF_INET6,
s_ip6, NM_SETTING_IP_CONFIG_ADDRESSES,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
g_object_bind_property (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY,
widget, "text",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_page_grid_append (grid, _("Gateway"), widget, NULL);
widget = nmt_address_list_new (NMT_ADDRESS_LIST_IP6);

View file

@ -102,7 +102,7 @@ G_DEFINE_BOXED_TYPE (NMIPAddress, nm_ip_address, nm_ip_address_dup, nm_ip_addres
struct NMIPAddress {
guint refcount;
char *address, *gateway;
char *address;
int prefix, family;
GHashTable *attributes;
@ -113,7 +113,6 @@ struct NMIPAddress {
* @family: the IP address family (%AF_INET or %AF_INET6)
* @addr: the IP address
* @prefix: the address prefix length
* @gateway: (allow-none): the gateway
* @error: location to store error, or %NULL
*
* Creates a new #NMIPAddress object.
@ -122,7 +121,7 @@ struct NMIPAddress {
**/
NMIPAddress *
nm_ip_address_new (int family,
const char *addr, guint prefix, const char *gateway,
const char *addr, guint prefix,
GError **error)
{
NMIPAddress *address;
@ -134,8 +133,6 @@ nm_ip_address_new (int family,
return NULL;
if (!valid_prefix (family, prefix, error))
return NULL;
if (gateway && !valid_ip (family, gateway, error))
return NULL;
address = g_slice_new0 (NMIPAddress);
address->refcount = 1;
@ -143,7 +140,6 @@ nm_ip_address_new (int family,
address->family = family;
address->address = canonicalize_ip (family, addr, FALSE);
address->prefix = prefix;
address->gateway = canonicalize_ip (family, gateway, TRUE);
return address;
}
@ -153,17 +149,16 @@ nm_ip_address_new (int family,
* @family: the IP address family (%AF_INET or %AF_INET6)
* @addr: the IP address
* @prefix: the address prefix length
* @gateway: (allow-none): the gateway
* @error: location to store error, or %NULL
*
* Creates a new #NMIPAddress object. @addr and @gateway (if non-%NULL) must
* point to buffers of the correct size for @family.
* Creates a new #NMIPAddress object. @addr must point to a buffer of the
* correct size for @family.
*
* Returns: (transfer full): the new #NMIPAddress object, or %NULL on error
**/
NMIPAddress *
nm_ip_address_new_binary (int family,
gconstpointer addr, guint prefix, gconstpointer gateway,
gconstpointer addr, guint prefix,
GError **error)
{
NMIPAddress *address;
@ -181,8 +176,6 @@ nm_ip_address_new_binary (int family,
address->family = family;
address->address = g_strdup (inet_ntop (family, addr, string, sizeof (string)));
address->prefix = prefix;
if (gateway)
address->gateway = g_strdup (inet_ntop (family, gateway, string, sizeof (string)));
return address;
}
@ -218,7 +211,6 @@ nm_ip_address_unref (NMIPAddress *address)
address->refcount--;
if (address->refcount == 0) {
g_free (address->address);
g_free (address->gateway);
if (address->attributes)
g_hash_table_unref (address->attributes);
g_slice_free (NMIPAddress, address);
@ -230,8 +222,8 @@ nm_ip_address_unref (NMIPAddress *address)
* @address: the #NMIPAddress
* @other: the #NMIPAddress to compare @address to.
*
* Determines if two #NMIPAddress objects contain the same address, prefix, and
* gateway (attributes are not compared).
* Determines if two #NMIPAddress objects contain the same address and prefix
* (attributes are not compared).
*
* Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
**/
@ -246,8 +238,7 @@ nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
if ( address->family != other->family
|| address->prefix != other->prefix
|| strcmp (address->address, other->address) != 0
|| g_strcmp0 (address->gateway, other->gateway) != 0)
|| strcmp (address->address, other->address) != 0)
return FALSE;
return TRUE;
}
@ -269,7 +260,7 @@ nm_ip_address_dup (NMIPAddress *address)
g_return_val_if_fail (address->refcount > 0, NULL);
copy = nm_ip_address_new (address->family,
address->address, address->prefix, address->gateway,
address->address, address->prefix,
NULL);
if (address->attributes) {
GHashTableIter iter;
@ -417,46 +408,6 @@ nm_ip_address_set_prefix (NMIPAddress *address,
address->prefix = prefix;
}
/**
* nm_ip_address_get_gateway:
* @address: the #NMIPAddress
*
* Gets the gateway property of this address object; this will be %NULL if the
* address has no associated gateway.
*
* Returns: the gateway
**/
const char *
nm_ip_address_get_gateway (NMIPAddress *address)
{
g_return_val_if_fail (address != NULL, NULL);
g_return_val_if_fail (address->refcount > 0, NULL);
return address->gateway;
}
/**
* nm_ip_address_set_gateway:
* @address: the #NMIPAddress
* @gateway: (allow-none): the gateway, as a string
*
* Sets the gateway property of this address object.
*
* @gateway (if non-%NULL) must be a valid address of @address's family. If you
* aren't sure you have a valid address, use nm_utils_ipaddr_valid() to check
* it.
**/
void
nm_ip_address_set_gateway (NMIPAddress *address,
const char *gateway)
{
g_return_if_fail (address != NULL);
g_return_if_fail (!gateway || nm_utils_ipaddr_valid (address->family, gateway));
g_free (address->gateway);
address->gateway = canonicalize_ip (address->family, gateway, TRUE);
}
/**
* nm_ip_address_get_attribute_names:
* @address: the #NMIPAddress
@ -1081,6 +1032,7 @@ typedef struct {
GPtrArray *dns_search; /* array of domain name strings */
GPtrArray *addresses; /* array of NMIPAddress */
GPtrArray *routes; /* array of NMIPRoute */
char *gateway;
gboolean ignore_auto_routes;
gboolean ignore_auto_dns;
char *dhcp_hostname;
@ -1095,6 +1047,7 @@ enum {
PROP_DNS,
PROP_DNS_SEARCH,
PROP_ADDRESSES,
PROP_GATEWAY,
PROP_ROUTES,
PROP_IGNORE_AUTO_ROUTES,
PROP_IGNORE_AUTO_DNS,
@ -1543,6 +1496,21 @@ nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting)
g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
}
/**
* nm_setting_ip_config_get_gateway:
* @setting: the #NMSettingIPConfig
*
* Returns: the IP address of the gateway associated with this configuration, or
* %NULL.
**/
const char *
nm_setting_ip_config_get_gateway (NMSettingIPConfig *setting)
{
g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->gateway;
}
/**
* nm_setting_ip_config_get_num_routes:
* @setting: the #NMSettingIPConfig
@ -1882,6 +1850,27 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
/* Validate gateway */
if (priv->gateway) {
if (!priv->addresses->len) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("gateway cannot be set if there are no addresses configured"));
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY);
return FALSE;
}
if (!nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), priv->gateway)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("gateway is invalid"));
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY);
return FALSE;
}
}
/* Validate routes */
for (i = 0; i < priv->routes->len; i++) {
NMIPRoute *route = (NMIPRoute *) priv->routes->pdata[i];
@ -1919,6 +1908,7 @@ finalize (GObject *object)
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (self);
g_free (priv->method);
g_free (priv->gateway);
g_free (priv->dhcp_hostname);
g_ptr_array_unref (priv->dns);
@ -1935,6 +1925,7 @@ set_property (GObject *object, guint prop_id,
{
NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object);
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
const char *gateway;
switch (prop_id) {
case PROP_METHOD:
@ -1955,6 +1946,12 @@ set_property (GObject *object, guint prop_id,
(NMUtilsCopyFunc) nm_ip_address_dup,
(GDestroyNotify) nm_ip_address_unref);
break;
case PROP_GATEWAY:
gateway = g_value_get_string (value);
g_return_if_fail (!gateway || nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway));
g_free (priv->gateway);
priv->gateway = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway, TRUE);
break;
case PROP_ROUTES:
g_ptr_array_unref (priv->routes);
priv->routes = _nm_utils_copy_array (g_value_get_boxed (value),
@ -2008,6 +2005,9 @@ get_property (GObject *object, guint prop_id,
(NMUtilsCopyFunc) nm_ip_address_dup,
(GDestroyNotify) nm_ip_address_unref));
break;
case PROP_GATEWAY:
g_value_set_string (value, nm_setting_ip_config_get_gateway (setting));
break;
case PROP_ROUTES:
g_value_take_boxed (value, _nm_utils_copy_array (priv->routes,
(NMUtilsCopyFunc) nm_ip_route_dup,
@ -2118,6 +2118,20 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingIPConfig:gateway:
*
* The gateway associated with this configuration. This is only meaningful
* if #NMSettingIPConfig:addresses is also set.
**/
g_object_class_install_property
(object_class, PROP_GATEWAY,
g_param_spec_string (NM_SETTING_IP_CONFIG_GATEWAY, "", "",
NULL,
G_PARAM_READWRITE |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMSettingIPConfig:routes:
*

View file

@ -38,12 +38,10 @@ GType nm_ip_address_get_type (void);
NMIPAddress *nm_ip_address_new (int family,
const char *addr,
guint prefix,
const char *gateway,
GError **error);
NMIPAddress *nm_ip_address_new_binary (int family,
gconstpointer addr,
guint prefix,
gconstpointer gateway,
GError **error);
void nm_ip_address_ref (NMIPAddress *address);
@ -63,9 +61,6 @@ void nm_ip_address_set_address_binary (NMIPAddress *address,
guint nm_ip_address_get_prefix (NMIPAddress *address);
void nm_ip_address_set_prefix (NMIPAddress *address,
guint prefix);
const char *nm_ip_address_get_gateway (NMIPAddress *address);
void nm_ip_address_set_gateway (NMIPAddress *address,
const char *gateway);
char **nm_ip_address_get_attribute_names (NMIPAddress *address);
GVariant *nm_ip_address_get_attribute (NMIPAddress *address,
@ -139,6 +134,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route,
#define NM_SETTING_IP_CONFIG_DNS "dns"
#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search"
#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses"
#define NM_SETTING_IP_CONFIG_GATEWAY "gateway"
#define NM_SETTING_IP_CONFIG_ROUTES "routes"
#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes"
#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns"
@ -195,6 +191,8 @@ gboolean nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig
NMIPAddress *address);
void nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting);
const char *nm_setting_ip_config_get_gateway (NMSettingIPConfig *setting);
guint nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting);
NMIPRoute *nm_setting_ip_config_get_route (NMSettingIPConfig *setting,
int i);

View file

@ -102,10 +102,12 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting);
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
NMSettingVerifyResult ret;
const char *method;
if (!NM_SETTING_CLASS (nm_setting_ip4_config_parent_class)->verify (setting, connection, error))
return FALSE;
ret = NM_SETTING_CLASS (nm_setting_ip4_config_parent_class)->verify (setting, connection, error);
if (ret != NM_SETTING_VERIFY_SUCCESS)
return ret;
method = nm_setting_ip_config_get_method (s_ip);
/* Base class already checked that it exists */
@ -245,10 +247,12 @@ ip4_addresses_get (NMSetting *setting,
const char *property)
{
GPtrArray *addrs;
const char *gateway;
GVariant *ret;
g_object_get (setting, property, &addrs, NULL);
ret = nm_utils_ip4_addresses_to_variant (addrs);
gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
ret = nm_utils_ip4_addresses_to_variant (addrs, gateway);
g_ptr_array_unref (addrs);
return ret;
@ -262,18 +266,27 @@ ip4_addresses_set (NMSetting *setting,
{
GPtrArray *addrs;
GVariant *s_ip4;
char **labels;
char **labels, *gateway = NULL;
int i;
addrs = nm_utils_ip4_addresses_from_variant (value);
addrs = nm_utils_ip4_addresses_from_variant (value, &gateway);
s_ip4 = g_variant_lookup_value (connection_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
if (g_variant_lookup (s_ip4, "address-labels", "^as", &labels)) {
for (i = 0; i < addrs->len && labels[i]; i++)
if (*labels[i])
nm_ip_address_set_attribute (addrs->pdata[i], "label", g_variant_new_string (labels[i]));
g_strfreev (labels);
}
if (gateway && !g_variant_lookup (s_ip4, "gateway", "s", NULL)) {
g_object_set (setting,
NM_SETTING_IP_CONFIG_GATEWAY, gateway,
NULL);
}
g_free (gateway);
g_variant_unref (s_ip4);
g_object_set (setting, property, addrs, NULL);

View file

@ -100,10 +100,12 @@ static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
NMSettingVerifyResult ret;
const char *method;
if (!NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error))
return FALSE;
ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error);
if (ret != NM_SETTING_VERIFY_SUCCESS)
return ret;
method = nm_setting_ip_config_get_method (s_ip);
/* Base class already checked that it exists */
@ -187,16 +189,46 @@ ip6_dns_from_dbus (GVariant *dbus_value,
}
static GVariant *
ip6_addresses_to_dbus (const GValue *prop_value)
ip6_addresses_get (NMSetting *setting,
const char *property)
{
return nm_utils_ip6_addresses_to_variant (g_value_get_boxed (prop_value));
GPtrArray *addrs;
const char *gateway;
GVariant *ret;
g_object_get (setting, property, &addrs, NULL);
gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
ret = nm_utils_ip6_addresses_to_variant (addrs, gateway);
g_ptr_array_unref (addrs);
return ret;
}
static void
ip6_addresses_from_dbus (GVariant *dbus_value,
GValue *prop_value)
ip6_addresses_set (NMSetting *setting,
GVariant *connection_dict,
const char *property,
GVariant *value)
{
g_value_take_boxed (prop_value, nm_utils_ip6_addresses_from_variant (dbus_value));
GPtrArray *addrs;
GVariant *s_ip6;
char *gateway = NULL;
addrs = nm_utils_ip6_addresses_from_variant (value, &gateway);
s_ip6 = g_variant_lookup_value (connection_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
if (gateway && !g_variant_lookup (s_ip6, "gateway", "s", NULL)) {
g_object_set (setting,
NM_SETTING_IP_CONFIG_GATEWAY, gateway,
NULL);
}
g_free (gateway);
g_variant_unref (s_ip6);
g_object_set (setting, property, addrs, NULL);
g_ptr_array_unref (addrs);
}
static GVariant *
@ -285,11 +317,12 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
ip6_dns_to_dbus,
ip6_dns_from_dbus);
_nm_setting_class_transform_property (setting_class,
NM_SETTING_IP_CONFIG_ADDRESSES,
G_VARIANT_TYPE ("a(ayuay)"),
ip6_addresses_to_dbus,
ip6_addresses_from_dbus);
_nm_setting_class_override_property (setting_class,
NM_SETTING_IP_CONFIG_ADDRESSES,
G_VARIANT_TYPE ("a(ayuay)"),
ip6_addresses_get,
ip6_addresses_set,
NULL);
_nm_setting_class_transform_property (setting_class,
NM_SETTING_IP_CONFIG_ROUTES,

View file

@ -1136,16 +1136,18 @@ nm_utils_ip4_dns_from_variant (GVariant *value)
/**
* nm_utils_ip4_addresses_to_variant:
* @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects
* @gateway: (allow-none): the gateway IP address
*
* Utility function to convert a #GPtrArray of #NMIPAddress objects representing
* IPv4 addresses into a #GVariant of type 'aau' representing an array of
* NetworkManager IPv4 addresses (which are tuples of address, prefix, and
* gateway, although only the first "gateway" field is preserved)
* gateway). The "gateway" field of the first address will get the value of
* @gateway (if non-%NULL). In all of the other addresses, that field will be 0.
*
* Returns: (transfer none): a new floating #GVariant representing @addresses.
**/
GVariant *
nm_utils_ip4_addresses_to_variant (GPtrArray *addresses)
nm_utils_ip4_addresses_to_variant (GPtrArray *addresses, const char *gateway)
{
GVariantBuilder builder;
int i;
@ -1162,8 +1164,8 @@ nm_utils_ip4_addresses_to_variant (GPtrArray *addresses)
nm_ip_address_get_address_binary (addr, &array[0]);
array[1] = nm_ip_address_get_prefix (addr);
if (i == 0 && nm_ip_address_get_gateway (addr))
inet_pton (AF_INET, nm_ip_address_get_gateway (addr), &array[2]);
if (i == 0 && gateway)
inet_pton (AF_INET, gateway, &array[2]);
else
array[2] = 0;
@ -1179,17 +1181,19 @@ nm_utils_ip4_addresses_to_variant (GPtrArray *addresses)
/**
* nm_utils_ip4_addresses_from_variant:
* @value: a #GVariant of type 'aau'
* @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway
*
* Utility function to convert a #GVariant of type 'aau' representing a list of
* NetworkManager IPv4 addresses (which are tuples of address, prefix, and
* gateway, although only the first "gateway" field is preserved) into a
* #GPtrArray of #NMIPAddress objects.
* gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field of
* the first address (if set) will be returned in @out_gateway; the "gateway" fields
* of the other addresses are ignored.
*
* Returns: (transfer full) (element-type NMIPAddress): a newly allocated
* #GPtrArray of #NMIPAddress objects
**/
GPtrArray *
nm_utils_ip4_addresses_from_variant (GVariant *value)
nm_utils_ip4_addresses_from_variant (GVariant *value, char **out_gateway)
{
GPtrArray *addresses;
GVariantIter iter;
@ -1197,6 +1201,9 @@ nm_utils_ip4_addresses_from_variant (GVariant *value)
g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL);
if (out_gateway)
*out_gateway = NULL;
g_variant_iter_init (&iter, value);
addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
@ -1213,16 +1220,19 @@ nm_utils_ip4_addresses_from_variant (GVariant *value)
continue;
}
addr = nm_ip_address_new_binary (AF_INET,
&addr_array[0], addr_array[1],
addresses->len == 0 ? &addr_array[2] : NULL,
&error);
addr = nm_ip_address_new_binary (AF_INET, &addr_array[0], addr_array[1], &error);
if (addresses->len == 0 && out_gateway) {
if (addr_array[2])
*out_gateway = g_strdup (nm_utils_inet4_ntop (addr_array[2], NULL));
}
if (addr)
g_ptr_array_add (addresses, addr);
else {
g_warning ("Ignoring invalid IP4 address: %s", error->message);
g_clear_error (&error);
}
g_variant_unref (addr_var);
}
@ -1469,16 +1479,19 @@ nm_utils_ip6_dns_from_variant (GVariant *value)
/**
* nm_utils_ip6_addresses_to_variant:
* @addresses: (element-type NMIPAddress): an array of #NMIPAddress objects
* @gateway: (allow-none): the gateway IP address
*
* Utility function to convert a #GPtrArray of #NMIPAddress objects representing
* IPv6 addresses into a #GVariant of type 'a(ayuay)' representing an array of
* NetworkManager IPv6 addresses (which are tuples of address, prefix, and
* gateway, although only the first "gateway" field is preserved).
* gateway). The "gateway" field of the first address will get the value of
* @gateway (if non-%NULL). In all of the other addresses, that field will be
* all 0s.
*
* Returns: (transfer none): a new floating #GVariant representing @addresses.
**/
GVariant *
nm_utils_ip6_addresses_to_variant (GPtrArray *addresses)
nm_utils_ip6_addresses_to_variant (GPtrArray *addresses, const char *gateway)
{
GVariantBuilder builder;
int i;
@ -1489,24 +1502,24 @@ nm_utils_ip6_addresses_to_variant (GPtrArray *addresses)
for (i = 0; i < addresses->len; i++) {
NMIPAddress *addr = addresses->pdata[i];
struct in6_addr ip_bytes, gateway_bytes;
GVariant *ip, *gateway;
GVariant *ip_var, *gateway_var;
guint32 prefix;
if (nm_ip_address_get_family (addr) != AF_INET6)
continue;
nm_ip_address_get_address_binary (addr, &ip_bytes);
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &ip_bytes, 16, 1);
ip_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &ip_bytes, 16, 1);
prefix = nm_ip_address_get_prefix (addr);
if (i == 0 && nm_ip_address_get_gateway (addr))
inet_pton (AF_INET6, nm_ip_address_get_gateway (addr), &gateway_bytes);
if (i == 0 && gateway)
inet_pton (AF_INET6, gateway, &gateway_bytes);
else
memset (&gateway_bytes, 0, sizeof (gateway_bytes));
gateway = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &gateway_bytes, 16, 1);
gateway_var = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &gateway_bytes, 16, 1);
g_variant_builder_add (&builder, "(@ayu@ay)", ip, prefix, gateway);
g_variant_builder_add (&builder, "(@ayu@ay)", ip_var, prefix, gateway_var);
}
}
@ -1516,17 +1529,19 @@ nm_utils_ip6_addresses_to_variant (GPtrArray *addresses)
/**
* nm_utils_ip6_addresses_from_variant:
* @value: a #GVariant of type 'a(ayuay)'
* @out_gateway: (out) (allow-none) (transfer full): on return, will contain the IP gateway
*
* Utility function to convert a #GVariant of type 'a(ayuay)' representing a
* list of NetworkManager IPv6 addresses (which are tuples of address, prefix,
* and gateway, although only the first "gateway" field is preserved) into a
* #GPtrArray of #NMIPAddress objects.
* and gateway) into a #GPtrArray of #NMIPAddress objects. The "gateway" field
* of the first address (if set) will be returned in @out_gateway; the "gateway"
* fields of the other addresses are ignored.
*
* Returns: (transfer full) (element-type NMIPAddress): a newly allocated
* #GPtrArray of #NMIPAddress objects
**/
GPtrArray *
nm_utils_ip6_addresses_from_variant (GVariant *value)
nm_utils_ip6_addresses_from_variant (GVariant *value, char **out_gateway)
{
GVariantIter iter;
GVariant *addr_var, *gateway_var;
@ -1535,6 +1550,9 @@ nm_utils_ip6_addresses_from_variant (GVariant *value)
g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuay)")), NULL);
if (out_gateway)
*out_gateway = NULL;
g_variant_iter_init (&iter, value);
addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
@ -1556,16 +1574,19 @@ nm_utils_ip6_addresses_from_variant (GVariant *value)
__func__, (int) addr_len);
goto next;
}
gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1);
if (gateway_len != 16) {
g_warning ("%s: ignoring invalid IP6 address of length %d",
__func__, (int) gateway_len);
goto next;
if (addresses->len == 0 && out_gateway) {
gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1);
if (gateway_len != 16) {
g_warning ("%s: ignoring invalid IP6 address of length %d",
__func__, (int) gateway_len);
goto next;
}
if (!IN6_IS_ADDR_UNSPECIFIED (gateway_bytes))
*out_gateway = g_strdup (nm_utils_inet6_ntop (gateway_bytes, NULL));
}
addr = nm_ip_address_new_binary (AF_INET6, addr_bytes, prefix,
addresses->len == 0 ? gateway_bytes : NULL,
&error);
addr = nm_ip_address_new_binary (AF_INET6, addr_bytes, prefix, &error);
if (addr)
g_ptr_array_add (addresses, addr);
else {

View file

@ -97,8 +97,10 @@ gboolean nm_utils_wpa_psk_valid (const char *psk);
GVariant *nm_utils_ip4_dns_to_variant (char **dns);
char **nm_utils_ip4_dns_from_variant (GVariant *value);
GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses);
GPtrArray *nm_utils_ip4_addresses_from_variant (GVariant *value);
GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses,
const char *gateway);
GPtrArray *nm_utils_ip4_addresses_from_variant (GVariant *value,
char **out_gateway);
GVariant *nm_utils_ip4_routes_to_variant (GPtrArray *routes);
GPtrArray *nm_utils_ip4_routes_from_variant (GVariant *value);
@ -108,8 +110,10 @@ guint32 nm_utils_ip4_get_default_prefix (guint32 ip);
GVariant *nm_utils_ip6_dns_to_variant (char **dns);
char **nm_utils_ip6_dns_from_variant (GVariant *value);
GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses);
GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value);
GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses,
const char *gateway);
GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value,
char **out_gateway);
GVariant *nm_utils_ip6_routes_to_variant (GPtrArray *routes);
GPtrArray *nm_utils_ip6_routes_from_variant (GVariant *value);

View file

@ -338,7 +338,7 @@ test_setting_ip4_config_labels (void)
NULL);
/* addr 1 */
addr = nm_ip_address_new (AF_INET, "1.1.1.1", 24, NULL, &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.1", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
@ -351,7 +351,7 @@ test_setting_ip4_config_labels (void)
g_assert (label == NULL);
/* addr 2 */
addr = nm_ip_address_new (AF_INET, "2.2.2.2", 24, NULL, &error);
addr = nm_ip_address_new (AF_INET, "2.2.2.2", 24, &error);
g_assert_no_error (error);
nm_ip_address_set_attribute (addr, "label", g_variant_new_string ("eth0:1"));
@ -366,7 +366,7 @@ test_setting_ip4_config_labels (void)
g_assert_cmpstr (g_variant_get_string (label, NULL), ==, "eth0:1");
/* addr 3 */
addr = nm_ip_address_new (AF_INET, "3.3.3.3", 24, NULL, &error);
addr = nm_ip_address_new (AF_INET, "3.3.3.3", 24, &error);
g_assert_no_error (error);
nm_ip_address_set_attribute (addr, "label", NULL);
@ -1634,6 +1634,7 @@ test_connection_diff_a_only (void)
{ NM_SETTING_IP_CONFIG_DNS, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_DNS_SEARCH, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_GATEWAY, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, NM_SETTING_DIFF_RESULT_IN_A },
@ -2480,7 +2481,7 @@ test_setting_ip4_changed_signal (void)
ASSERT_CHANGED (nm_setting_ip_config_add_dns_search (s_ip4, "foobar.com"));
ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip4));
addr = nm_ip_address_new (AF_INET, "22.33.0.0", 24, NULL, &error);
addr = nm_ip_address_new (AF_INET, "22.33.0.0", 24, &error);
g_assert_no_error (error);
ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip4, addr));
ASSERT_CHANGED (nm_setting_ip_config_remove_address (s_ip4, 0));
@ -2549,7 +2550,7 @@ test_setting_ip6_changed_signal (void)
nm_setting_ip_config_add_dns_search (s_ip6, "foobar.com");
ASSERT_CHANGED (nm_setting_ip_config_clear_dns_searches (s_ip6));
addr = nm_ip_address_new (AF_INET6, "1:2:3::4:5:6", 64, NULL, &error);
addr = nm_ip_address_new (AF_INET6, "1:2:3::4:5:6", 64, &error);
g_assert_no_error (error);
ASSERT_CHANGED (nm_setting_ip_config_add_address (s_ip6, addr));
@ -3336,6 +3337,145 @@ test_connection_normalize_infiniband_mtu (void)
g_assert_cmpint (65520, ==, nm_setting_infiniband_get_mtu (s_infini));
}
static void
test_setting_ip4_gateway (void)
{
NMConnection *conn;
NMSettingIPConfig *s_ip4;
NMIPAddress *addr;
GVariant *conn_dict, *ip4_dict, *value;
GVariantIter iter;
GVariant *addr_var;
GError *error = NULL;
/* When serializing, ipv4.gateway is copied to the first entry of ipv4.addresses */
conn = nmtst_create_minimal_connection ("test_setting_ip4_gateway", NULL,
NM_SETTING_WIRED_SETTING_NAME, NULL);
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "192.168.1.1",
NULL);
nm_connection_add_setting (conn, NM_SETTING (s_ip4));
addr = nm_ip_address_new (AF_INET, "192.168.1.10", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL);
g_object_unref (conn);
ip4_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
g_assert (ip4_dict != NULL);
value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING);
g_assert (value != NULL);
g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "192.168.1.1");
g_variant_unref (value);
value = g_variant_lookup_value (ip4_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("aau"));
g_assert (value != NULL);
g_variant_iter_init (&iter, value);
while (g_variant_iter_next (&iter, "@au", &addr_var)) {
const guint32 *addr_array;
gsize length;
addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32));
g_assert_cmpint (length, ==, 3);
g_assert_cmpstr (nm_utils_inet4_ntop (addr_array[2], NULL), ==, "192.168.1.1");
g_variant_unref (addr_var);
}
g_variant_unref (value);
g_variant_unref (ip4_dict);
/* When deserializing, the first gateway in ipv4.addresses is copied to ipv4.gateway */
NMTST_VARIANT_EDITOR (conn_dict,
NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY);
);
conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
g_variant_unref (conn_dict);
g_assert_no_error (error);
s_ip4 = (NMSettingIPConfig *) nm_connection_get_setting_ip4_config (conn);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1");
g_object_unref (conn);
}
static void
test_setting_ip6_gateway (void)
{
NMConnection *conn;
NMSettingIPConfig *s_ip6;
NMIPAddress *addr;
GVariant *conn_dict, *ip6_dict, *value;
GVariantIter iter;
GVariant *gateway_var;
GError *error = NULL;
/* When serializing, ipv6.gateway is copied to the first entry of ipv6.addresses */
conn = nmtst_create_minimal_connection ("test_setting_ip6_gateway", NULL,
NM_SETTING_WIRED_SETTING_NAME, NULL);
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "abcd::1",
NULL);
nm_connection_add_setting (conn, NM_SETTING (s_ip6));
addr = nm_ip_address_new (AF_INET6, "abcd::10", 64, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr);
nm_ip_address_unref (addr);
conn_dict = nm_connection_to_dbus (conn, NM_CONNECTION_SERIALIZE_ALL);
g_object_unref (conn);
ip6_dict = g_variant_lookup_value (conn_dict, NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
g_assert (ip6_dict != NULL);
value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_GATEWAY, G_VARIANT_TYPE_STRING);
g_assert (value != NULL);
g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "abcd::1");
value = g_variant_lookup_value (ip6_dict, NM_SETTING_IP_CONFIG_ADDRESSES, G_VARIANT_TYPE ("a(ayuay)"));
g_assert (value != NULL);
g_variant_iter_init (&iter, value);
while (g_variant_iter_next (&iter, "(@ayu@ay)", NULL, NULL, &gateway_var)) {
const guint8 *gateway_bytes;
gsize length;
gateway_bytes = g_variant_get_fixed_array (gateway_var, &length, 1);
g_assert_cmpint (length, ==, 16);
g_assert_cmpstr (nm_utils_inet6_ntop ((struct in6_addr *) gateway_bytes, NULL), ==, "abcd::1");
g_variant_unref (gateway_var);
}
g_variant_unref (value);
g_variant_unref (ip6_dict);
/* When deserializing, the first gateway in ipv4.addresses is copied to ipv4.gateway */
NMTST_VARIANT_EDITOR (conn_dict,
NMTST_VARIANT_DROP_PROPERTY (NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY);
);
conn = nm_simple_connection_new_from_dbus (conn_dict, &error);
g_variant_unref (conn_dict);
g_assert_no_error (error);
s_ip6 = (NMSettingIPConfig *) nm_connection_get_setting_ip6_config (conn);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, "abcd::1");
g_object_unref (conn);
}
NMTST_DEFINE ();
int main (int argc, char **argv)
@ -3424,6 +3564,8 @@ int main (int argc, char **argv)
g_test_add_func ("/core/general/test_setting_wireless_changed_signal", test_setting_wireless_changed_signal);
g_test_add_func ("/core/general/test_setting_wireless_security_changed_signal", test_setting_wireless_security_changed_signal);
g_test_add_func ("/core/general/test_setting_802_1x_changed_signal", test_setting_802_1x_changed_signal);
g_test_add_func ("/core/general/test_setting_ip4_gateway", test_setting_ip4_gateway);
g_test_add_func ("/core/general/test_setting_ip6_gateway", test_setting_ip6_gateway);
return g_test_run ();
}

View file

@ -289,7 +289,6 @@ global:
nm_ip_address_get_attribute;
nm_ip_address_get_attribute_names;
nm_ip_address_get_family;
nm_ip_address_get_gateway;
nm_ip_address_get_prefix;
nm_ip_address_get_type;
nm_ip_address_new;
@ -298,7 +297,6 @@ global:
nm_ip_address_set_address;
nm_ip_address_set_address_binary;
nm_ip_address_set_attribute;
nm_ip_address_set_gateway;
nm_ip_address_set_prefix;
nm_ip_address_unref;
nm_ip_route_equal;
@ -571,6 +569,7 @@ global:
nm_setting_ip_config_get_dhcp_send_hostname;
nm_setting_ip_config_get_dns;
nm_setting_ip_config_get_dns_search;
nm_setting_ip_config_get_gateway;
nm_setting_ip_config_get_ignore_auto_dns;
nm_setting_ip_config_get_ignore_auto_routes;
nm_setting_ip_config_get_may_fail;

View file

@ -74,7 +74,7 @@ demarshal_ip4_address_array (NMObject *object, GParamSpec *pspec, GVariant *valu
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object);
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip4_addresses_from_variant (value);
priv->addresses = nm_utils_ip4_addresses_from_variant (value, NULL);
_nm_object_queue_notify (object, NM_IP4_CONFIG_ADDRESSES);
return TRUE;

View file

@ -59,7 +59,7 @@ demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GVariant *valu
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
g_ptr_array_unref (priv->addresses);
priv->addresses = nm_utils_ip6_addresses_from_variant (value);
priv->addresses = nm_utils_ip6_addresses_from_variant (value, NULL);
_nm_object_queue_notify (object, NM_IP6_CONFIG_ADDRESSES);
return TRUE;

View file

@ -319,14 +319,11 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, in
nm_ip4_config_set_never_default (config, TRUE);
else if (nm_setting_ip_config_get_ignore_auto_routes (setting))
nm_ip4_config_set_never_default (config, FALSE);
if (naddresses) {
const char *gateway_str = nm_ip_address_get_gateway (nm_setting_ip_config_get_address (setting, 0));
if (nm_setting_ip_config_get_gateway (setting)) {
guint32 gateway;
if (gateway_str) {
inet_pton (AF_INET, gateway_str, &gateway);
nm_ip4_config_set_gateway (config, gateway);
}
inet_pton (AF_INET, nm_setting_ip_config_get_gateway (setting), &gateway);
nm_ip4_config_set_gateway (config, gateway);
}
/* Addresses */
@ -425,9 +422,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
if (!method)
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
s_addr = nm_ip_address_new_binary (AF_INET, &address->address, address->plen,
i == 0 ? &gateway : NULL,
NULL);
s_addr = nm_ip_address_new_binary (AF_INET, &address->address, address->plen, NULL);
if (*address->label)
nm_ip_address_set_attribute (s_addr, "label", g_variant_new_string (address->label));
@ -435,6 +430,13 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
nm_ip_address_unref (s_addr);
}
/* Gateway */
if (gateway) {
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet4_ntop (gateway, NULL),
NULL);
}
/* Use 'disabled' if the method wasn't previously set */
if (!method)
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;

View file

@ -404,6 +404,7 @@ void
nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, int default_route_metric)
{
guint naddresses, nroutes, nnameservers, nsearches;
const char *gateway_str;
int i;
if (!setting)
@ -423,14 +424,12 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, in
nm_ip6_config_set_never_default (config, TRUE);
else if (nm_setting_ip_config_get_ignore_auto_routes (setting))
nm_ip6_config_set_never_default (config, FALSE);
if (naddresses) {
const char *gateway_str = nm_ip_address_get_gateway (nm_setting_ip_config_get_address (setting, 0));
gateway_str = nm_setting_ip_config_get_gateway (setting);
if (gateway_str) {
struct in6_addr gateway;
if (gateway_str) {
inet_pton (AF_INET6, gateway_str, &gateway);
nm_ip6_config_set_gateway (config, &gateway);
}
inet_pton (AF_INET6, gateway_str, &gateway);
nm_ip6_config_set_gateway (config, &gateway);
}
/* Addresses */
@ -531,13 +530,18 @@ nm_ip6_config_create_setting (const NMIP6Config *config)
if (!method || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0)
method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
s_addr = nm_ip_address_new_binary (AF_INET6, &address->address, address->plen,
i == 0 ? gateway : NULL,
NULL);
s_addr = nm_ip_address_new_binary (AF_INET6, &address->address, address->plen, NULL);
nm_setting_ip_config_add_address (s_ip6, s_addr);
nm_ip_address_unref (s_addr);
}
/* Gateway */
if (gateway) {
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet6_ntop (gateway, NULL),
NULL);
}
/* Use 'ignore' if the method wasn't previously set */
if (!method)
method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE;

View file

@ -349,7 +349,7 @@ ip4_setting_add_from_block (const GPtrArray *block,
goto error;
}
addr = nm_ip_address_new (AF_INET, s_ipaddr, prefix, s_gateway, error);
addr = nm_ip_address_new (AF_INET, s_ipaddr, prefix, error);
if (!addr) {
g_prefix_error (error, "iBFT: malformed iscsiadm record: ");
goto error;
@ -358,6 +358,8 @@ ip4_setting_add_from_block (const GPtrArray *block,
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, s_gateway, NULL);
if (s_dns1)
nm_setting_ip_config_add_dns (s_ip4, s_dns1);
if (s_dns2)

View file

@ -162,7 +162,8 @@ test_read_ibft_static (void)
g_assert (ip4_addr);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.32.72");
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 22);
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, "192.168.35.254");
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.35.254");
g_object_unref (connection);
g_ptr_array_unref (block);
@ -259,7 +260,8 @@ test_read_ibft_vlan (void)
g_assert (ip4_addr);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.6.200");
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, NULL);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, NULL);
g_object_unref (connection);
g_ptr_array_ref (block);

View file

@ -334,13 +334,13 @@ read_full_ip4_address (shvarFile *ifcfg,
gint32 which,
NMIPAddress *base_addr,
NMIPAddress **out_address,
char **out_gateway,
GError **error)
{
char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag;
char *ip = NULL, *gw = NULL;
char *ip = NULL;
long prefix = 0;
gboolean success = FALSE;
shvarFile *network_ifcfg;
char *value;
guint32 tmp;
@ -370,21 +370,9 @@ read_full_ip4_address (shvarFile *ifcfg,
}
/* Gateway */
if (!read_ip4_address (ifcfg, gw_tag, &gw, error))
goto done;
if (!gw && base_addr)
gw = g_strdup (nm_ip_address_get_gateway (base_addr));
if (!gw) {
gboolean read_success;
/* If no gateway in the ifcfg, try /etc/sysconfig/network instead */
network_ifcfg = svOpenFile (network_file, NULL);
if (network_ifcfg) {
read_success = read_ip4_address (network_ifcfg, "GATEWAY", &gw, error);
svCloseFile (network_ifcfg);
if (!read_success)
goto done;
}
if (out_gateway && !*out_gateway) {
if (!read_ip4_address (ifcfg, gw_tag, out_gateway, error))
goto done;
}
/* Prefix */
@ -431,13 +419,12 @@ read_full_ip4_address (shvarFile *ifcfg,
goto done;
}
*out_address = nm_ip_address_new (AF_INET, ip, prefix, gw, error);
*out_address = nm_ip_address_new (AF_INET, ip, prefix, error);
if (*out_address)
success = TRUE;
done:
g_free (ip);
g_free (gw);
g_free (ip_tag);
g_free (prefix_tag);
g_free (netmask_tag);
@ -698,9 +685,8 @@ parse_full_ip6_address (shvarFile *ifcfg,
GError **error)
{
char **list;
char *ip_val, *prefix_val, *gateway_val = NULL;
char *ip_val, *prefix_val;
long prefix;
shvarFile *network_ifcfg;
gboolean success = FALSE;
g_return_val_if_fail (addr_str != NULL, FALSE);
@ -733,33 +719,12 @@ parse_full_ip6_address (shvarFile *ifcfg,
prefix = 64;
}
/* Gateway */
if (i == 0) {
char *ptr;
gateway_val = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE);
if (!gateway_val) {
/* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */
network_ifcfg = svOpenFile (network_file, NULL);
if (network_ifcfg) {
gateway_val = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
svCloseFile (network_ifcfg);
}
}
if ( gateway_val
&& (ptr = strchr (gateway_val, '%')) != NULL)
*ptr = '\0'; /* remove %interface suffix if present */
} else
gateway_val = NULL;
*out_address = nm_ip_address_new (AF_INET6, ip_val, prefix, gateway_val, error);
*out_address = nm_ip_address_new (AF_INET6, ip_val, prefix, error);
if (*out_address)
success = TRUE;
error:
g_strfreev (list);
g_free (gateway_val);
return success;
}
@ -927,6 +892,7 @@ make_ip4_setting (shvarFile *ifcfg,
char *value = NULL;
char *route_path = NULL;
char *method;
char *gateway = NULL;
gint32 i;
shvarFile *network_ifcfg;
shvarFile *route_ifcfg;
@ -1031,7 +997,7 @@ make_ip4_setting (shvarFile *ifcfg,
for (i = -1; i < 256; i++) {
NMIPAddress *addr = NULL;
if (!read_full_ip4_address (ifcfg, network_file, i, NULL, &addr, error))
if (!read_full_ip4_address (ifcfg, network_file, i, NULL, &addr, &gateway, error))
goto done;
if (!addr) {
@ -1042,14 +1008,25 @@ make_ip4_setting (shvarFile *ifcfg,
continue;
}
if (nm_setting_ip_config_get_num_addresses (s_ip4))
nm_ip_address_set_gateway (addr, NULL);
if (!nm_setting_ip_config_add_address (s_ip4, addr))
PARSE_WARNING ("duplicate IP4 address");
nm_ip_address_unref (addr);
}
/* Gateway */
if (!gateway) {
network_ifcfg = svOpenFile (network_file, NULL);
if (network_ifcfg) {
gboolean read_success;
read_success = read_ip4_address (network_ifcfg, "GATEWAY", &gateway, error);
svCloseFile (network_ifcfg);
if (!read_success)
goto done;
}
}
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL);
/* DNS servers
* Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
*/
@ -1155,6 +1132,7 @@ make_ip4_setting (shvarFile *ifcfg,
return NM_SETTING (s_ip4);
done:
g_free (gateway);
g_free (route_path);
g_object_unref (s_ip4);
return NULL;
@ -1235,7 +1213,7 @@ read_aliases (NMSettingIPConfig *s_ip4, const char *filename, const char *networ
}
addr = NULL;
ok = read_full_ip4_address (parsed, network_file, -1, base_addr, &addr, &err);
ok = read_full_ip4_address (parsed, network_file, -1, base_addr, &addr, NULL, &err);
svCloseFile (parsed);
if (ok) {
nm_ip_address_set_attribute (addr, "label", g_variant_new_string (device));
@ -1431,6 +1409,33 @@ make_ip6_setting (shvarFile *ifcfg,
}
g_strfreev (list);
/* Gateway */
if (nm_setting_ip_config_get_num_addresses (s_ip6)) {
value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE);
if (!value) {
/* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */
network_ifcfg = svOpenFile (network_file, NULL);
if (network_ifcfg) {
value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
svCloseFile (network_ifcfg);
}
}
if (value) {
char *ptr;
if ((ptr = strchr (value, '%')) != NULL)
*ptr = '\0'; /* remove %interface prefix if present */
if (!nm_utils_ipaddr_valid (AF_INET6, value)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP6 address '%s'", value);
g_free (value);
goto error;
}
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, value, NULL);
g_free (value);
}
}
/* DNS servers
* Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
*/

View file

@ -493,7 +493,9 @@ test_read_wired_static (const char *file,
g_assert (ip4_addr);
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5");
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, "192.168.1.1");
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1");
/* ===== IPv6 SETTING ===== */
s_ip6 = nm_connection_get_setting_ip6_config (connection);
@ -762,7 +764,9 @@ test_read_wired_dhcp_plus_ip (void)
g_assert (ip4_addr);
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "1.2.3.4");
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, "1.1.1.1");
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1");
ip4_addr = nm_setting_ip_config_get_address (s_ip4, 1);
g_assert (ip4_addr);
@ -836,7 +840,9 @@ test_read_wired_global_gateway (void)
g_assert (ip4_addr);
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5");
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, "192.168.1.2");
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.2");
g_object_unref (connection);
}
@ -2377,7 +2383,7 @@ test_read_wired_aliases_good (void)
int expected_num_addresses = 4;
const char *expected_address[4] = { "192.168.1.5", "192.168.1.6", "192.168.1.9", "192.168.1.99" };
const char *expected_label[4] = { NULL, "aliasem0:1", "aliasem0:2", "aliasem0:99" };
const char *expected_gateway[4] = { "192.168.1.1", "192.168.1.1", "192.168.1.1", "192.168.1.1" };
const char *expected_gateway = "192.168.1.1";
int i, j;
connection = connection_from_file (TEST_IFCFG_ALIASES_GOOD,
@ -2457,7 +2463,6 @@ test_read_wired_aliases_good (void)
g_assert (j < expected_num_addresses);
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, expected_gateway[j]);
label = nm_ip_address_get_attribute (ip4_addr, "label");
if (expected_label[j])
g_assert_cmpstr (g_variant_get_string (label, NULL), ==, expected_label[j]);
@ -2465,10 +2470,12 @@ test_read_wired_aliases_good (void)
g_assert (label == NULL);
expected_address[j] = NULL;
expected_gateway[j] = NULL;
expected_label[j] = NULL;
}
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, expected_gateway);
for (i = 0; i < expected_num_addresses; i++) {
ASSERT (expected_address[i] == NULL,
"aliases-good-verify-ip4", "failed to verify %s: did not find IP4 address %s",
@ -2561,9 +2568,11 @@ test_read_wired_aliases_bad (const char *base, const char *expected_id)
g_assert (ip4_addr != NULL);
g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "192.168.1.5");
g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_gateway (ip4_addr), ==, "192.168.1.1");
g_assert (nm_ip_address_get_attribute (ip4_addr, "label") == NULL);
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "192.168.1.1");
g_free (keyfile);
g_free (routefile);
g_free (route6file);
@ -6282,14 +6291,15 @@ test_write_wired_static (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -6310,17 +6320,17 @@ test_write_wired_static (void)
NULL);
/* Add addresses */
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, NULL, &error);
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr6);
nm_ip_address_unref (addr6);
addr6 = nm_ip_address_new (AF_INET6, "2003:1234:abcd::2", 22, NULL, &error);
addr6 = nm_ip_address_new (AF_INET6, "2003:1234:abcd::2", 22, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr6);
nm_ip_address_unref (addr6);
addr6 = nm_ip_address_new (AF_INET6, "3003:1234:abcd::3", 33, NULL, &error);
addr6 = nm_ip_address_new (AF_INET6, "3003:1234:abcd::3", 33, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr6);
nm_ip_address_unref (addr6);
@ -6689,7 +6699,7 @@ test_write_wired_static_ip6_only (void)
NULL);
/* Add addresses */
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, NULL, &error);
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr6);
nm_ip_address_unref (addr6);
@ -6815,10 +6825,11 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data)
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, gateway6,
NULL);
/* Add addresses */
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, gateway6, &error);
addr6 = nm_ip_address_new (AF_INET6, "1003:1234:abcd::1", 11, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip6, addr6);
nm_ip_address_unref (addr6);
@ -6873,11 +6884,11 @@ test_write_wired_static_ip6_only_gw (gconstpointer user_data)
/* assert that the gateway was written and reloaded as expected */
if (!gateway6 || !strcmp (gateway6, "::")) {
g_assert (nm_ip_address_get_gateway (addr6) == NULL);
g_assert (nm_setting_ip_config_get_gateway (s_ip6) == NULL);
g_assert (written_ifcfg_gateway == NULL);
} else {
g_assert (nm_ip_address_get_gateway (addr6) != NULL);
g_assert_cmpstr (nm_ip_address_get_gateway (addr6), ==, gateway6);
g_assert (nm_setting_ip_config_get_gateway (s_ip6) != NULL);
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip6), ==, gateway6);
g_assert_cmpstr (written_ifcfg_gateway, ==, gateway6);
}
@ -7092,14 +7103,15 @@ test_write_wired_static_routes (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.5", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -7610,11 +7622,12 @@ test_write_wired_aliases (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
for (i = 0; i < num_addresses; i++) {
addr = nm_ip_address_new (AF_INET, ip[i], 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, ip[i], 24, &error);
g_assert_no_error (error);
if (label[i])
nm_ip_address_set_attribute (addr, "label", g_variant_new_string (label[i]));
@ -7709,7 +7722,6 @@ test_write_wired_aliases (void)
g_assert (j < num_addresses);
g_assert_cmpint (nm_ip_address_get_prefix (addr), ==, 24);
g_assert_cmpstr (nm_ip_address_get_gateway (addr), ==, "1.1.1.1");
if (label[j])
g_assert_cmpstr (g_variant_get_string (nm_ip_address_get_attribute (addr, "label"), NULL), ==, label[j]);
else
@ -7725,6 +7737,9 @@ test_write_wired_aliases (void)
ip[i]);
}
/* Gateway */
g_assert_cmpstr (nm_setting_ip_config_get_gateway (s_ip4), ==, "1.1.1.1");
g_free (testfile);
g_free (keyfile);
g_free (routefile);
@ -7770,15 +7785,16 @@ test_write_gateway (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254",
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.254", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
addr = nm_ip_address_new (AF_INET, "2.2.2.5", 24, "2.2.2.254", &error);
addr = nm_ip_address_new (AF_INET, "2.2.2.5", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -8319,10 +8335,13 @@ test_write_wifi_wep_adhoc (void)
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NULL);
/* IP Address */
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -9313,10 +9332,13 @@ test_write_wifi_wpa_psk_adhoc (void)
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NULL);
/* IP Address */
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 25, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 25, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -11262,10 +11284,11 @@ test_write_bridge_main (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -12040,10 +12063,11 @@ test_write_bond_main (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);
@ -12380,10 +12404,11 @@ test_write_infiniband (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NULL);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, "1.1.1.1", &error);
addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, addr);
nm_ip_address_unref (addr);

View file

@ -1915,8 +1915,7 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
g_free (tmp);
svSetValue (ifcfg, netmask_key, NULL, FALSE);
svSetValue (ifcfg, gw_key, n == 0 ? nm_ip_address_get_gateway (addr) : NULL, FALSE);
svSetValue (ifcfg, gw_key, NULL, FALSE);
g_free (addr_key);
g_free (prefix_key);
@ -1943,6 +1942,8 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
g_free (gw_key);
}
svSetValue (ifcfg, "GATEWAY", nm_setting_ip_config_get_gateway (s_ip4), FALSE);
num = nm_setting_ip_config_get_num_dns (s_ip4);
for (i = 0; i < 254; i++) {
const char *dns;
@ -2172,8 +2173,6 @@ write_ip4_aliases (NMConnection *connection, char *base_ifcfg_path)
svSetValue (ifcfg, "PREFIX", tmp, FALSE);
g_free (tmp);
svSetValue (ifcfg, "GATEWAY", i == 0 ? nm_ip_address_get_gateway (addr) : NULL, FALSE);
svWriteFile (ifcfg, 0644, NULL);
svCloseFile (ifcfg);
}
@ -2237,7 +2236,6 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
char *addr_key;
guint32 i, num, num4;
GString *searches;
const char *ipv6_defaultgw;
NMIPAddress *addr;
const char *dns;
GString *ip_str1, *ip_str2, *ip_ptr;
@ -2292,7 +2290,6 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
num = nm_setting_ip_config_get_num_addresses (s_ip6);
ip_str1 = g_string_new (NULL);
ip_str2 = g_string_new (NULL);
ipv6_defaultgw = NULL;
for (i = 0; i < num; i++) {
if (i == 0)
ip_ptr = ip_str1;
@ -2306,14 +2303,10 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
g_string_append_printf (ip_ptr, "%s/%u",
nm_ip_address_get_address (addr),
nm_ip_address_get_prefix (addr));
/* We only support gateway for the first IP address */
if (i == 0)
ipv6_defaultgw = nm_ip_address_get_gateway (addr);
}
svSetValue (ifcfg, "IPV6ADDR", ip_str1->str, FALSE);
svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str, FALSE);
svSetValue (ifcfg, "IPV6_DEFAULTGW", ipv6_defaultgw, FALSE);
svSetValue (ifcfg, "IPV6_DEFAULTGW", nm_setting_ip_config_get_gateway (s_ip6), FALSE);
g_string_free (ip_str1, TRUE);
g_string_free (ip_str2, TRUE);

View file

@ -614,9 +614,7 @@ make_ip4_setting (NMConnection *connection,
NMIPAddress *ip4_addr;
GError *local = NULL;
ip4_addr = nm_ip_address_new (AF_INET, iblock->ip, iblock->prefix,
nm_setting_ip_config_get_num_addresses (ip4_setting) == 0 ? iblock->next_hop : NULL,
&local);
ip4_addr = nm_ip_address_new (AF_INET, iblock->ip, iblock->prefix, &local);
if (iblock->next_hop)
g_object_set (ip4_setting,
NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES,
@ -795,7 +793,7 @@ make_ip6_setting (NMConnection *connection,
NMIPAddress *ip6_addr;
GError *local = NULL;
ip6_addr = nm_ip_address_new (AF_INET6, iblock->ip, iblock->prefix, NULL, &local);
ip6_addr = nm_ip_address_new (AF_INET6, iblock->ip, iblock->prefix, &local);
if (ip6_addr) {
if (nm_setting_ip_config_add_address (s_ip6, ip6_addr)) {
nm_log_info (LOGD_SETTINGS, "ipv6 addresses count: %d",
@ -2408,10 +2406,10 @@ write_ip4_setting (NMConnection *connection, const char *conn_name, GError **err
nm_ip_address_get_prefix (addr));
/* only the first gateway will be written */
if (i == 0 && nm_ip_address_get_gateway (addr)) {
if (i == 0 && nm_setting_ip_config_get_gateway (s_ip4)) {
g_string_append_printf (routes,
"\"default via %s\" ",
nm_ip_address_get_gateway (addr));
nm_setting_ip_config_get_gateway (s_ip4));
}
}
ifnet_set_data (conn_name, "config", ips->str);

View file

@ -480,15 +480,8 @@ update_ip4_setting_from_if_block(NMConnection *connection,
}
}
/* gateway */
gateway_v = ifparser_getkey (block, "gateway");
if (!gateway_v)
gateway_v = address_v; /* dcbw: whaaa?? */
/* Add the new address to the setting */
addr = nm_ip_address_new (AF_INET, address_v, netmask_int,
nm_setting_ip_config_get_num_addresses (s_ip4) == 0 ? gateway_v : NULL,
error);
addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error);
if (!addr)
goto error;
@ -500,6 +493,18 @@ update_ip4_setting_from_if_block(NMConnection *connection,
}
nm_ip_address_unref (addr);
/* gateway */
gateway_v = ifparser_getkey (block, "gateway");
if (gateway_v) {
if (!nm_utils_ipaddr_valid (AF_INET, gateway_v)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IPv4 gateway '%s'", gateway_v);
goto error;
}
if (!nm_setting_ip_config_get_gateway (s_ip4))
g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL);
}
nameserver_v = ifparser_getkey (block, "dns-nameserver");
ifupdown_ip4_add_dns (s_ip4, nameserver_v);
@ -595,15 +600,8 @@ update_ip6_setting_from_if_block(NMConnection *connection,
if (prefix_v)
prefix_int = g_ascii_strtoll (prefix_v, NULL, 10);
/* Gateway */
gateway_v = ifparser_getkey (block, "gateway");
if (!gateway_v)
gateway_v = address_v; /* dcbw: whaaa?? */
/* Add the new address to the setting */
addr = nm_ip_address_new (AF_INET6, address_v, prefix_int,
nm_setting_ip_config_get_num_addresses (s_ip6) == 0 ? gateway_v : NULL,
error);
addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error);
if (!addr)
goto error;
@ -615,6 +613,18 @@ update_ip6_setting_from_if_block(NMConnection *connection,
}
nm_ip_address_unref (addr);
/* gateway */
gateway_v = ifparser_getkey (block, "gateway");
if (gateway_v) {
if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IPv6 gateway '%s'", gateway_v);
goto error;
}
if (!nm_setting_ip_config_get_gateway (s_ip6))
g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL);
}
nameserver_v = ifparser_getkey(block, "dns-nameserver");
ifupdown_ip6_add_dns (s_ip6, nameserver_v);

View file

@ -108,15 +108,37 @@ get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *ou
}
static gpointer
build_address_or_route (const char *key_name, const char *address_str, guint32 plen, const char *gateway_str, const char *metric_str, int family, gboolean route)
build_address (int family, const char *address_str, guint32 plen)
{
gpointer result;
guint32 metric = 0;
NMIPAddress *addr;
GError *error = NULL;
g_return_val_if_fail (address_str, NULL);
/* Gateway */
addr = nm_ip_address_new (family, address_str, plen, &error);
if (!addr) {
nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s address: %s", __func__,
family == AF_INET ? "IPv4" : "IPv6",
error->message);
g_error_free (error);
}
return addr;
}
static gpointer
build_route (int family,
const char *dest_str, guint32 plen,
const char *gateway_str, const char *metric_str,
const char *key_name)
{
NMIPRoute *route;
guint32 metric = 0;
GError *error = NULL;
g_return_val_if_fail (dest_str, NULL);
/* Next hop */
if (gateway_str && gateway_str[0]) {
if (!nm_utils_ipaddr_valid (family, gateway_str)) {
/* Try workaround for routes written by broken keyfile writer.
@ -128,7 +150,6 @@ build_address_or_route (const char *key_name, const char *address_str, guint32 p
* supported.
**/
if ( family == AF_INET6
&& route
&& !metric_str
&& get_one_int (gateway_str, G_MAXUINT32, NULL, &metric))
gateway_str = NULL;
@ -146,19 +167,15 @@ build_address_or_route (const char *key_name, const char *address_str, guint32 p
return NULL;
}
if (route)
result = nm_ip_route_new (family, address_str, plen, gateway_str, metric, &error);
else
result = nm_ip_address_new (family, address_str, plen, gateway_str, &error);
if (!result) {
nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s %s: %s", __func__,
route = nm_ip_route_new (family, dest_str, plen, gateway_str, metric, &error);
if (!route) {
nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid %s route: %s", __func__,
family == AF_INET ? "IPv4" : "IPv6",
route ? "route" : "address",
error->message);
g_error_free (error);
}
return result;
return route;
}
/* On success, returns pointer to the zero-terminated field (original @current).
@ -251,7 +268,8 @@ read_one_ip_address_or_route (GKeyFile *file,
const char *setting_name,
const char *key_name,
gboolean ipv6,
gboolean route)
gboolean route,
char **out_gateway)
{
guint32 plen;
gpointer result;
@ -317,8 +335,16 @@ read_one_ip_address_or_route (GKeyFile *file,
}
/* build the appropriate data structure for NetworkManager settings */
result = build_address_or_route (key_name, address_str, plen, gateway_str, metric_str,
ipv6 ? AF_INET6 : AF_INET, route);
if (route) {
result = build_route (ipv6 ? AF_INET6 : AF_INET,
address_str, plen, gateway_str, metric_str,
key_name);
} else {
result = build_address (ipv6 ? AF_INET6 : AF_INET,
address_str, plen);
if (out_gateway && gateway_str)
*out_gateway = g_strdup (gateway_str);
}
g_free (value);
return result;
@ -336,6 +362,7 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi
static const char *key_names_routes[] = { "route", "routes", NULL };
static const char *key_names_addresses[] = { "address", "addresses", NULL };
const char **key_names = routes ? key_names_routes : key_names_addresses;
char *gateway = NULL;
GPtrArray *list;
GDestroyNotify free_func;
int i;
@ -359,21 +386,23 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi
else
key_name = g_strdup (*key_basename);
item = read_one_ip_address_or_route (keyfile, setting_name, key_name, ipv6, routes);
item = read_one_ip_address_or_route (keyfile, setting_name, key_name, ipv6, routes,
gateway ? NULL : &gateway);
if (item)
g_ptr_array_add (list, item);
g_free (key_name);
if (!item)
continue;
if (!routes && list->len > 0)
nm_ip_address_set_gateway (item, NULL);
g_ptr_array_add (list, item);
}
}
if (list->len >= 1)
g_object_set (setting, key, list, NULL);
if (gateway) {
g_object_set (setting, "gateway", gateway, NULL);
g_free (gateway);
}
g_ptr_array_unref (list);
}

View file

@ -38,14 +38,13 @@
#define TEST_WIRELESS_FILE TEST_KEYFILES_DIR"/Test_Wireless_Connection"
static void
check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen, const char *gateway)
check_ip_address (NMSettingIPConfig *config, int idx, const char *address, int plen)
{
NMIPAddress *ip4 = nm_setting_ip_config_get_address (config, idx);
g_assert (ip4);
g_assert_cmpstr (nm_ip_address_get_address (ip4), ==, address);
g_assert_cmpint (nm_ip_address_get_prefix (ip4), ==, plen);
g_assert_cmpstr (nm_ip_address_get_gateway (ip4), ==, gateway);
}
static void
@ -246,12 +245,19 @@ test_read_valid_wired_connection (void)
/* IPv4 addresses */
g_assert (nm_setting_ip_config_get_num_addresses (s_ip4) == 6);
check_ip_address (s_ip4, 0, "2.3.4.5", 24, "2.3.4.6");
check_ip_address (s_ip4, 1, "192.168.0.5", 24, NULL);
check_ip_address (s_ip4, 2, "1.2.3.4", 16, NULL);
check_ip_address (s_ip4, 3, "3.4.5.6", 16, NULL);
check_ip_address (s_ip4, 4, "4.5.6.7", 24, NULL);
check_ip_address (s_ip4, 5, "5.6.7.8", 24, NULL);
check_ip_address (s_ip4, 0, "2.3.4.5", 24);
check_ip_address (s_ip4, 1, "192.168.0.5", 24);
check_ip_address (s_ip4, 2, "1.2.3.4", 16);
check_ip_address (s_ip4, 3, "3.4.5.6", 16);
check_ip_address (s_ip4, 4, "4.5.6.7", 24);
check_ip_address (s_ip4, 5, "5.6.7.8", 24);
/* IPv4 gateway */
ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip4), "2.3.4.6") == 0,
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
TEST_WIRED_FILE,
NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY);
/* IPv4 routes */
g_assert (nm_setting_ip_config_get_num_routes (s_ip4) == 12);
@ -328,16 +334,23 @@ test_read_valid_wired_connection (void)
/* IPv6 addresses */
g_assert (nm_setting_ip_config_get_num_addresses (s_ip6) == 10);
check_ip_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64, "2:3:4:5:1:2:3:4");
check_ip_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64, NULL);
check_ip_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96, NULL);
check_ip_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128, NULL);
check_ip_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64, NULL);
check_ip_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64, NULL);
check_ip_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66, NULL);
check_ip_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67, NULL);
check_ip_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68, NULL);
check_ip_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69, NULL);
check_ip_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64);
check_ip_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64);
check_ip_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96);
check_ip_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128);
check_ip_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64);
check_ip_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64);
check_ip_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66);
check_ip_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67);
check_ip_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68);
check_ip_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69);
/* IPv6 gateway */
ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip6), "2:3:4:5:1:2:3:4") == 0,
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
TEST_WIRED_FILE,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY);
/* Route #1 */
g_assert (nm_setting_ip_config_get_num_routes (s_ip6) == 7);
@ -354,14 +367,13 @@ test_read_valid_wired_connection (void)
static void
add_one_ip_address (NMSettingIPConfig *s_ip,
const char *addr,
guint32 prefix,
const char *gw)
guint32 prefix)
{
NMIPAddress *ip_addr;
GError *error = NULL;
ip_addr = nm_ip_address_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6,
addr, prefix, gw, &error);
addr, prefix, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip, ip_addr);
nm_ip_address_unref (ip_addr);
@ -404,8 +416,8 @@ test_write_wired_connection (void)
const char *dns1 = "4.2.2.1";
const char *dns2 = "4.2.2.2";
const char *address1 = "192.168.0.5";
const char *address1_gw = "192.168.0.1";
const char *address2 = "1.2.3.4";
const char *gw = "192.168.0.1";
const char *route1 = "10.10.10.2";
const char *route1_nh = "10.10.10.1";
const char *route2 = "1.1.1.1";
@ -462,11 +474,12 @@ test_write_wired_connection (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, gw,
NULL);
/* Addresses */
add_one_ip_address (s_ip4, address1, 24, address1_gw);
add_one_ip_address (s_ip4, address2, 8, NULL);
add_one_ip_address (s_ip4, address1, 24);
add_one_ip_address (s_ip4, address2, 8);
/* Routes */
add_one_ip_route (s_ip4, route1, route1_nh, 24, 3);
@ -488,8 +501,8 @@ test_write_wired_connection (void)
NULL);
/* Addresses */
add_one_ip_address (s_ip6, address6_1, 64, NULL);
add_one_ip_address (s_ip6, address6_2, 56, NULL);
add_one_ip_address (s_ip6, address6_1, 64);
add_one_ip_address (s_ip6, address6_2, 56);
/* Routes */
add_one_ip_route (s_ip6, route6_1, route6_1_nh, 64, 3);
@ -634,7 +647,14 @@ test_read_ip6_wired_connection (void)
/* IPv6 address */
g_assert (nm_setting_ip_config_get_num_addresses (s_ip6) == 1);
check_ip_address (s_ip6, 0, "abcd:1234:ffff::cdde", 64, "abcd:1234:ffff::cdd1");
check_ip_address (s_ip6, 0, "abcd:1234:ffff::cdde", 64);
/* IPv6 gateway */
ASSERT (strcmp (nm_setting_ip_config_get_gateway (s_ip6), "abcd:1234:ffff::cdd1") == 0,
"connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
TEST_WIRED_IP6_FILE,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY);
g_object_unref (connection);
}
@ -695,10 +715,11 @@ test_write_ip6_wired_connection (void)
g_object_set (s_ip6,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, gw,
NULL);
/* Addresses */
add_one_ip_address (s_ip6, address, 64, gw);
add_one_ip_address (s_ip6, address, 64);
/* DNS servers */
nm_setting_ip_config_add_dns (s_ip6, dns);
@ -2816,9 +2837,10 @@ test_write_bridge_main (void)
g_object_set (s_ip4,
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1",
NULL);
add_one_ip_address (s_ip4, "1.2.3.4", 24, "1.1.1.1");
add_one_ip_address (s_ip4, "1.2.3.4", 24);
/* IP6 setting */
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();

View file

@ -117,6 +117,7 @@ static void
write_ip_values (GKeyFile *file,
const char *setting_name,
GPtrArray *array,
const char *gateway,
gboolean is_route)
{
GString *output;
@ -147,10 +148,7 @@ write_ip_values (GKeyFile *file,
addr = nm_ip_address_get_address (address);
plen = nm_ip_address_get_prefix (address);
if (i == 0)
gw = nm_ip_address_get_gateway (address);
else
gw = NULL;
gw = i == 0 ? gateway : NULL;
metric = 0;
}
@ -190,10 +188,11 @@ addr_writer (GKeyFile *file,
{
GPtrArray *array;
const char *setting_name = nm_setting_get_name (setting);
const char *gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
array = (GPtrArray *) g_value_get_boxed (value);
if (array && array->len)
write_ip_values (file, setting_name, array, FALSE);
write_ip_values (file, setting_name, array, gateway, FALSE);
}
static void
@ -207,6 +206,17 @@ ip4_addr_label_writer (GKeyFile *file,
/* skip */
}
static void
gateway_writer (GKeyFile *file,
const char *keyfile_dir,
const char *uuid,
NMSetting *setting,
const char *key,
const GValue *value)
{
/* skip */
}
static void
route_writer (GKeyFile *file,
const char *keyfile_dir,
@ -220,7 +230,7 @@ route_writer (GKeyFile *file,
array = (GPtrArray *) g_value_get_boxed (value);
if (array && array->len)
write_ip_values (file, setting_name, array, TRUE);
write_ip_values (file, setting_name, array, NULL, TRUE);
}
static void
@ -589,6 +599,12 @@ static KeyWriter key_writers[] = {
{ NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_ADDRESSES,
addr_writer },
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY,
gateway_writer },
{ NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_GATEWAY,
gateway_writer },
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
NM_SETTING_IP_CONFIG_ROUTES,
route_writer },

View file

@ -601,8 +601,9 @@ test_connection_no_match_ip4_addr (void)
g_assert (s_ip4);
g_object_set (G_OBJECT (s_ip4),
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254",
NULL);
nm_addr = nm_ip_address_new (AF_INET, "1.1.1.4", 24, "1.1.1.254", &error);
nm_addr = nm_ip_address_new (AF_INET, "1.1.1.4", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, nm_addr);
nm_ip_address_unref (nm_addr);
@ -611,8 +612,9 @@ test_connection_no_match_ip4_addr (void)
g_assert (s_ip4);
g_object_set (G_OBJECT (s_ip4),
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
NM_SETTING_IP_CONFIG_GATEWAY, "2.2.2.254",
NULL);
nm_addr = nm_ip_address_new (AF_INET, "2.2.2.4", 24, "2.2.2.254", &error);
nm_addr = nm_ip_address_new (AF_INET, "2.2.2.4", 24, &error);
g_assert_no_error (error);
nm_setting_ip_config_add_address (s_ip4, nm_addr);
nm_ip_address_unref (nm_addr);