ifcfg-rh: fix IPv6-only configurations (rh #538499)

This commit is contained in:
Dan Williams
2010-04-12 16:24:07 -07:00
parent 9000c68839
commit dc7fe96e3f
5 changed files with 364 additions and 27 deletions

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 - 2009 Red Hat, Inc.
* Copyright (C) 2008 - 2010 Red Hat, Inc.
*/
#include <stdlib.h>
@@ -1115,6 +1115,7 @@ static NMSetting *
make_ip4_setting (shvarFile *ifcfg,
const char *network_file,
const char *iscsiadm_path,
gboolean valid_ip6_config,
GError **error)
{
NMSettingIP4Config *s_ip4 = NULL;
@@ -1192,14 +1193,17 @@ make_ip4_setting (shvarFile *ifcfg,
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Unknown BOOTPROTO '%s'", value);
g_free (value);
goto error;
goto done;
}
g_free (value);
} else {
char *tmp_ip4, *tmp_prefix, *tmp_netmask;
/* If there is no BOOTPROTO, no IPADDR, no PREFIX, and no NETMASK,
* assume DHCP is to be used. Happens with minimal ifcfg files like:
/* If there is no BOOTPROTO, no IPADDR, no PREFIX, no NETMASK, but
* valid IPv6 configuration, assume that IPv4 is disabled. Otherwise,
* if there is no IPv6 configuration, assume DHCP is to be used.
* Happens with minimal ifcfg files like the following that anaconda
* sometimes used to write out:
*
* DEVICE=eth0
* HWADDR=11:22:33:44:55:66
@@ -1208,8 +1212,14 @@ make_ip4_setting (shvarFile *ifcfg,
tmp_ip4 = svGetValue (ifcfg, "IPADDR", FALSE);
tmp_prefix = svGetValue (ifcfg, "PREFIX", FALSE);
tmp_netmask = svGetValue (ifcfg, "NETMASK", FALSE);
if (!tmp_ip4 && !tmp_prefix && !tmp_netmask)
if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) {
if (valid_ip6_config) {
/* Nope, no IPv4 */
goto done;
}
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
}
g_free (tmp_ip4);
g_free (tmp_prefix);
g_free (tmp_netmask);
@@ -1229,7 +1239,7 @@ make_ip4_setting (shvarFile *ifcfg,
for (i = 1; i < 256; i++) {
addr = read_full_ip4_address (ifcfg, network_file, i, error);
if (error && *error)
goto error;
goto done;
if (!addr)
break;
@@ -1271,7 +1281,7 @@ make_ip4_setting (shvarFile *ifcfg,
}
if (!tmp_success) {
g_free (tag);
goto error;
goto done;
}
g_clear_error (error);
}
@@ -1305,7 +1315,7 @@ make_ip4_setting (shvarFile *ifcfg,
if (!route_path) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Could not get route file path for '%s'", ifcfg->fileName);
goto error;
goto done;
}
/* First test new/legacy syntax */
@@ -1319,7 +1329,7 @@ make_ip4_setting (shvarFile *ifcfg,
route = read_one_ip4_route (route_ifcfg, network_file, i, error);
if (error && *error) {
svCloseFile (route_ifcfg);
goto error;
goto done;
}
if (!route)
break;
@@ -1334,7 +1344,7 @@ make_ip4_setting (shvarFile *ifcfg,
read_route_file_legacy (route_path, s_ip4, error);
g_free (route_path);
if (error && *error)
goto error;
goto done;
}
/* Legacy value NM used for a while but is incorrect (rh #459370) */
@@ -1360,7 +1370,7 @@ make_ip4_setting (shvarFile *ifcfg,
return NM_SETTING (s_ip4);
error:
done:
g_object_unref (s_ip4);
return NULL;
}
@@ -3058,6 +3068,7 @@ connection_from_file (const char *filename,
NMSetting *s_ip4, *s_ip6;
const char *ifcfg_name = NULL;
gboolean nm_controlled = TRUE;
gboolean ip6_used = FALSE;
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (unmanaged != NULL, NULL);
@@ -3161,22 +3172,27 @@ connection_from_file (const char *filename,
if (!connection || *unmanaged)
goto done;
s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, error);
if (*error) {
g_object_unref (connection);
connection = NULL;
goto done;
} else if (s_ip4) {
nm_connection_add_setting (connection, s_ip4);
}
s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, error);
if (*error) {
g_object_unref (connection);
connection = NULL;
goto done;
} else if (s_ip6)
} else if (s_ip6) {
const char *method;
nm_connection_add_setting (connection, s_ip6);
method = nm_setting_ip6_config_get_method (NM_SETTING_IP6_CONFIG (s_ip6));
if (method && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
ip6_used = TRUE;
}
s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, ip6_used, error);
if (*error) {
g_object_unref (connection);
connection = NULL;
goto done;
} else if (s_ip4)
nm_connection_add_setting (connection, s_ip4);
/* iSCSI / ibft connections are read-only since their settings are
* stored in NVRAM and can only be changed in BIOS.

View File

@@ -57,7 +57,8 @@ EXTRA_DIST = \
route6-test-wired-ipv6-manual \
ifcfg-test-wired-static-no-prefix-8 \
ifcfg-test-wired-static-no-prefix-16 \
ifcfg-test-wired-static-no-prefix-24
ifcfg-test-wired-static-no-prefix-24 \
ifcfg-test-wired-ipv6-only
check-local:
@for f in $(EXTRA_DIST); do \

View File

@@ -0,0 +1,14 @@
# Intel Corporation 82567LM Gigabit Network Connection
TYPE=Ethernet
DEVICE=eth2
HWADDR=00:11:22:33:44:ee
ONBOOT=yes
USERCTL=yes
NM_CONTROLLED=yes
PEERDNS=yes
DNS1=1:2:3:4::a
DOMAIN="lorem.com ipsum.org dolor.edu"
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6ADDR="1001:abba::1234/56"

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 - 2009 Red Hat, Inc.
* Copyright (C) 2008 - 2010 Red Hat, Inc.
*/
#include <stdio.h>
@@ -2142,6 +2142,155 @@ test_read_wired_ipv6_manual (void)
g_object_unref (connection);
}
#define TEST_IFCFG_WIRED_IPV6_ONLY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-only"
static void
test_read_wired_ipv6_only (void)
{
NMConnection *connection;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
NMSettingIP4Config *s_ip4;
NMSettingIP6Config *s_ip6;
char *unmanaged = NULL;
char *keyfile = NULL;
char *routefile = NULL;
char *route6file = NULL;
gboolean ignore_error = FALSE;
GError *error = NULL;
const char *tmp;
const char *expected_id = "System test-wired-ipv6-only";
const char *expected_address1 = "1001:abba::1234";
guint32 expected_prefix1 = 56;
const char *expected_dns1 = "1:2:3:4::a";
NMIP6Address *ip6_addr;
struct in6_addr addr;
connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY,
NULL,
TYPE_ETHERNET,
NULL,
&unmanaged,
&keyfile,
&routefile,
&route6file,
&error,
&ignore_error);
ASSERT (connection != NULL,
"wired-ipv6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message);
ASSERT (nm_connection_verify (connection, &error),
"wired-ipv6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message);
ASSERT (unmanaged == FALSE,
"wired-ipv6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL);
/* ===== CONNECTION SETTING ===== */
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
ASSERT (s_con != NULL,
"wired-ipv6-only-verify-connection", "failed to verify %s: missing %s setting",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_CONNECTION_SETTING_NAME);
/* ID */
tmp = nm_setting_connection_get_id (s_con);
ASSERT (tmp != NULL,
"wired-ipv6-only-verify-connection", "failed to verify %s: missing %s / %s key",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_ID);
ASSERT (strcmp (tmp, expected_id) == 0,
"wired-ipv6-only-verify-connection", "failed to verify %s: unexpected %s / %s key value",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_CONNECTION_SETTING_NAME,
NM_SETTING_CONNECTION_ID);
/* ===== WIRED SETTING ===== */
s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
ASSERT (s_wired != NULL,
"wired-ipv6-only-verify-wired", "failed to verify %s: missing %s setting",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_WIRED_SETTING_NAME);
/* ===== IPv4 SETTING ===== */
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
ASSERT (s_ip4 == NULL,
"wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s setting",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP4_CONFIG_SETTING_NAME);
/* ===== IPv6 SETTING ===== */
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
ASSERT (s_ip6 != NULL,
"wired-ipv6-only-verify-ip6", "failed to verify %s: missing %s setting",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME);
/* Method */
tmp = nm_setting_ip6_config_get_method (s_ip6);
ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_METHOD);
/* IP addresses */
ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_ADDRESSES);
/* Address #1 */
ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
ASSERT (ip6_addr,
"wired-ipv6-only-verify-ip6", "failed to verify %s: missing IP6 address #1",
TEST_IFCFG_WIRED_IPV6_MANUAL);
ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1,
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix",
TEST_IFCFG_WIRED_IPV6_MANUAL);
ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0,
"wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert IP address #1",
TEST_IFCFG_WIRED_IPV6_MANUAL);
ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr),
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1",
TEST_IFCFG_WIRED_IPV6_MANUAL);
/* DNS Addresses */
ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 1,
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_DNS);
ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0,
"wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1",
TEST_IFCFG_WIRED_IPV6_MANUAL);
ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr),
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_DNS);
/* DNS domains - none as domains are stuffed to 'ipv4' setting */
ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0,
"wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
TEST_IFCFG_WIRED_IPV6_MANUAL,
NM_SETTING_IP6_CONFIG_SETTING_NAME,
NM_SETTING_IP6_CONFIG_DNS);
g_free (keyfile);
g_free (routefile);
g_free (route6file);
g_object_unref (connection);
}
#define TEST_IFCFG_ONBOOT_NO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-onboot-no"
static void
@@ -5108,6 +5257,140 @@ test_write_wired_dhcp (void)
g_object_unref (reread);
}
static void
test_write_wired_static_ip6_only (void)
{
NMConnection *connection;
NMConnection *reread;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
NMSettingIP6Config *s_ip6;
static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
GByteArray *mac;
char *uuid;
guint64 timestamp = 0x12344433L;
struct in6_addr ip6;
struct in6_addr dns6;
NMIP6Address *addr6;
gboolean success;
GError *error = NULL;
char *testfile = NULL;
char *unmanaged = NULL;
char *keyfile = NULL;
char *routefile = NULL;
char *route6file = NULL;
gboolean ignore_error = FALSE;
inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6);
inet_pton (AF_INET6, "fade:0102:0103::face", &dns6);
connection = nm_connection_new ();
ASSERT (connection != NULL,
"wired-static-ip6-only-write", "failed to allocate new connection");
/* Connection setting */
s_con = (NMSettingConnection *) nm_setting_connection_new ();
ASSERT (s_con != NULL,
"wired-static-ip6-only-write", "failed to allocate new %s setting",
NM_SETTING_CONNECTION_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_con));
uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, "Test Write Wired Static IP6 Only",
NM_SETTING_CONNECTION_UUID, uuid,
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
NULL);
g_free (uuid);
/* Wired setting */
s_wired = (NMSettingWired *) nm_setting_wired_new ();
ASSERT (s_wired != NULL,
"wired-static-ip6-only-write", "failed to allocate new %s setting",
NM_SETTING_WIRED_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_wired));
mac = g_byte_array_sized_new (sizeof (tmpmac));
g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
g_byte_array_free (mac, TRUE);
/* IP6 setting */
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
ASSERT (s_ip6 != NULL,
"wired-static-ip6-only-write", "failed to allocate new %s setting",
NM_SETTING_IP6_CONFIG_SETTING_NAME);
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
g_object_set (s_ip6,
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
NULL);
/* Add addresses */
addr6 = nm_ip6_address_new ();
nm_ip6_address_set_address (addr6, &ip6);
nm_ip6_address_set_prefix (addr6, 11);
nm_setting_ip6_config_add_address (s_ip6, addr6);
nm_ip6_address_unref (addr6);
/* DNS server */
nm_setting_ip6_config_add_dns (s_ip6, &dns6);
ASSERT (nm_connection_verify (connection, &error) == TRUE,
"wired-static-ip6-only-write", "failed to verify connection: %s",
(error && error->message) ? error->message : "(unknown)");
/* Save the ifcfg */
success = writer_new_connection (connection,
TEST_SCRATCH_DIR "/network-scripts/",
&testfile,
&error);
ASSERT (success == TRUE,
"wired-static-ip6-only-write", "failed to write connection to disk: %s",
(error && error->message) ? error->message : "(unknown)");
ASSERT (testfile != NULL,
"wired-static-ip6-only-write", "didn't get ifcfg file path back after writing connection");
/* re-read the connection for comparison */
reread = connection_from_file (testfile,
NULL,
TYPE_ETHERNET,
NULL,
&unmanaged,
&keyfile,
&routefile,
&route6file,
&error,
&ignore_error);
unlink (testfile);
ASSERT (reread != NULL,
"wired-static-ip6-only-write-reread", "failed to read %s: %s", testfile, error->message);
ASSERT (nm_connection_verify (reread, &error),
"wired-static-ip6-only-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
ASSERT (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG) == NULL,
"wired-static-ip6-only-write-reread-verify", "unexpected IPv4 setting");
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
"wired-static-ip6-only-write", "written and re-read connection weren't the same.");
if (route6file)
unlink (route6file);
g_free (testfile);
g_free (keyfile);
g_free (routefile);
g_free (route6file);
g_object_unref (connection);
g_object_unref (reread);
}
#define TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-static-routes-legacy"
static void
@@ -7813,6 +8096,7 @@ int main (int argc, char **argv)
test_read_wired_static_routes ();
test_read_wired_static_routes_legacy ();
test_read_wired_ipv6_manual ();
test_read_wired_ipv6_only ();
test_read_onboot_no ();
test_read_wired_8021x_peap_mschapv2 ();
test_read_wifi_open ();
@@ -7835,6 +8119,7 @@ int main (int argc, char **argv)
test_read_wifi_wep_eap_ttls_chap ();
test_write_wired_static ();
test_write_wired_static_ip6_only ();
test_write_wired_static_routes ();
test_read_write_static_routes_legacy ();
test_write_wired_dhcp ();

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2009 Red Hat, Inc.
* Copyright (C) 2009 - 2010 Red Hat, Inc.
*/
#include <ctype.h>
@@ -911,9 +911,30 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
if (!s_ip4) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Missing '%s' setting", NM_SETTING_IP4_CONFIG_SETTING_NAME);
return FALSE;
int result;
/* IPv4 disabled, clear IPv4 related parameters */
svSetValue (ifcfg, "BOOTPROTO", NULL, FALSE);
for (i = 0; i < 254; i++) {
if (i == 0) {
addr_key = g_strdup ("IPADDR");
prefix_key = g_strdup ("PREFIX");
gw_key = g_strdup ("GATEWAY");
} else {
addr_key = g_strdup_printf ("IPADDR%d", i + 1);
prefix_key = g_strdup_printf ("PREFIX%d", i + 1);
gw_key = g_strdup_printf ("GATEWAY%d", i + 1);
}
svSetValue (ifcfg, addr_key, NULL, FALSE);
svSetValue (ifcfg, prefix_key, NULL, FALSE);
svSetValue (ifcfg, gw_key, NULL, FALSE);
}
route_path = utils_get_route_path (ifcfg->fileName);
result = unlink (route_path);
g_free (route_path);
return TRUE;
}
value = nm_setting_ip4_config_get_method (s_ip4);