diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h index 4b1c5d243..694e84ccd 100644 --- a/shared/nm-test-utils.h +++ b/shared/nm-test-utils.h @@ -110,23 +110,24 @@ /* general purpose functions that have no dependency on other nmtst functions */ -inline static void -nmtst_assert_error (GError *error, - GQuark expect_error_domain, - gint expect_error_code, - const char *expect_error_pattern) -{ - if (expect_error_domain) - g_assert_error (error, expect_error_domain, expect_error_code); - else - g_assert (error); - g_assert (error->message); - if ( expect_error_pattern - && !g_pattern_match_simple (expect_error_pattern, error->message)) { - g_error ("error message does not have expected pattern '%s'. Instead it is '%s' (%s, %d)", - expect_error_pattern, error->message, g_quark_to_string (error->domain), error->code); - } -} +#define nmtst_assert_error(error, expect_error_domain, expect_error_code, expect_error_pattern) \ + G_STMT_START { \ + GError *_error = (error); \ + GQuark _expect_error_domain = (expect_error_domain); \ + const char *_expect_error_pattern = (expect_error_pattern); \ + \ + if (_expect_error_domain) \ + g_assert_error (_error, _expect_error_domain, (expect_error_code)); \ + else \ + g_assert (_error); \ + g_assert (_error->message); \ + if ( _expect_error_pattern \ + && !g_pattern_match_simple (_expect_error_pattern, _error->message)) { \ + g_error ("%s:%d: error message does not have expected pattern '%s'. Instead it is '%s' (%s, %d)", \ + __FILE__, __LINE__, \ + _expect_error_pattern, _error->message, g_quark_to_string (_error->domain), _error->code); \ + } \ + } G_STMT_END #define NMTST_WAIT(max_wait_ms, wait) \ ({ \ diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c index d28e3bf6c..1fb6b7894 100644 --- a/src/settings/plugins/ifcfg-rh/plugin.c +++ b/src/settings/plugins/ifcfg-rh/plugin.c @@ -207,8 +207,10 @@ update_connection (SettingsPluginIfcfg *self, && !protect_existing_connection && (!protected_connections || !g_hash_table_contains (protected_connections, connection))) remove_connection (self, connection); - if (!source && !ignore_error) - _LOGW ("loading \"%s\" fails: %s", full_path, local ? local->message : "(unknown reason)"); + if (!source) { + _NMLOG (ignore_error ? LOGL_DEBUG : LOGL_WARN, + "loading \"%s\" fails: %s", full_path, local ? local->message : "(unknown reason)"); + } g_propagate_error (error, local); return NULL; } diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index ca512fc6c..a65ca5d7c 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -4993,14 +4993,24 @@ connection_from_file_full (const char *filename, type = svGetValue (parsed, "TYPE", FALSE); if (!type) { + gs_free char *tmp = NULL; char *device; + if ((tmp = svGetValue (parsed, "IPV6TUNNELIPV4", FALSE))) { + if (out_ignore_error) + *out_ignore_error = TRUE; + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignoring unsupported connection due to IPV6TUNNELIPV4"); + goto done; + } + device = svGetValue (parsed, "DEVICE", FALSE); if (!device) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "File '%s' had neither TYPE nor DEVICE keys.", filename); goto done; } + g_assert (device[0]); if (!strcmp (device, "lo")) { if (out_ignore_error) @@ -5018,8 +5028,51 @@ connection_from_file_full (const char *filename, type = g_strdup (TYPE_VLAN); else if (is_wifi_device (device, parsed)) type = g_strdup (TYPE_WIRELESS); - else - type = g_strdup (TYPE_ETHERNET); + else { + gs_free char *p_path = NULL; + char *p_device; + gsize i; + + /* network-functions detects DEVICETYPE based on the ifcfg-* name and the existence + * of a ifup script: + * [ -z "$DEVICETYPE" ] && DEVICETYPE=$(echo ${DEVICE} | sed "s/[0-9]*$//") + * later... + * OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${DEVICETYPE}" + * */ +#define IFUP_PATH_PREFIX "/etc/sysconfig/network-scripts/ifup-" + i = strlen (device); + p_path = g_malloc (NM_STRLEN (IFUP_PATH_PREFIX) + i + 1); + p_device = &p_path[NM_STRLEN (IFUP_PATH_PREFIX)]; + memcpy (p_device, device, i + 1); + + /* strip trailing numbers */ + while (i >= 1) { + i--; + if (p_device[i] < '0' || p_device[i] > '9') + break; + p_device[i] = '\0'; + } + + if (nm_streq (p_device, "eth")) + type = g_strdup (TYPE_ETHERNET); + else if (nm_streq (p_device, "wireless")) + type = g_strdup (TYPE_WIRELESS); + else if (p_device[0]) { + memcpy (p_path, IFUP_PATH_PREFIX, NM_STRLEN (IFUP_PATH_PREFIX)); + if (access (p_path, X_OK) == 0) { + /* for all other types, this is not something we want to handle. */ + if (out_ignore_error) + *out_ignore_error = TRUE; + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Ignore script for unknown device type which has a matching %s script", + p_path); + goto done; + } + } + + if (!type) + type = g_strdup (TYPE_ETHERNET); + } } else { /* For the unit tests, there won't necessarily be any * adapters of the connection's type in the system so the diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sit-ignore b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sit-ignore new file mode 100644 index 000000000..a2581db67 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sit-ignore @@ -0,0 +1,12 @@ +# this ifcfg-file represents a "sit" type without explicit TYPE. +# Such connection types are not supported by NetworkManager and +# the connection should be ignored based on the presence of +# IPV6TUNNELIPV4. + +DEVICE=sit1 +BOOTPROTO=none +ONBOOT=yes +IPV6INIT=yes +IPV6TUNNELIPV4=5.4.3.6 +IPV6TUNNELIPV4LOCAL=172.17.1.9 +IPV6ADDR=2001:470:2:3:4::2/64 diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index ed62ffa0f..1856a3a62 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -8735,6 +8735,20 @@ test_read_vlan_trailing_spaces (void) g_object_unref (connection); } +/*****************************************************************************/ + +static void +test_sit_read_ignore (void) +{ + gs_free_error GError *error = NULL; + + _connection_from_file_fail (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-sit-ignore", + NULL, TYPE_ETHERNET, &error); + nmtst_assert_error (error, 0, 0, "*Ignoring unsupported connection due to IPV6TUNNELIPV4*"); +} + +/*****************************************************************************/ + #define TPATH "/settings/plugins/ifcfg-rh/" @@ -8934,10 +8948,8 @@ int main (int argc, char **argv) g_test_add_func (TPATH "wired/write-missing-ipv6", test_write_ethernet_missing_ipv6); g_test_add_func (TPATH "write-dns-options", test_write_dns_options); - /* iSCSI / ibft */ g_test_add_func (TPATH "ibft/ignored", test_read_ibft_ignored); - /* Data Center Bridging (DCB) */ g_test_add_func (TPATH "dcb/read-basic", test_read_dcb_basic); g_test_add_func (TPATH "dcb/write-basic", test_write_dcb_basic); g_test_add_func (TPATH "dcb/default-app-priorities", test_read_dcb_default_app_priorities); @@ -8953,7 +8965,6 @@ int main (int argc, char **argv) g_test_add_data_func (TPATH "fcoe/write-fabric", (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, test_write_fcoe_mode); g_test_add_data_func (TPATH "fcoe/write-vn2vn", (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, test_write_fcoe_mode); - /* bonding */ g_test_add_func (TPATH "bond/read-master", test_read_bond_main); g_test_add_func (TPATH "bond/read-slave", test_read_bond_slave); g_test_add_func (TPATH "bond/read-slave-ib", test_read_bond_slave_ib); @@ -8962,20 +8973,20 @@ int main (int argc, char **argv) g_test_add_func (TPATH "bond/write-slave-ib", test_write_bond_slave_ib); g_test_add_func (TPATH "bond/bonding-opts-numeric-mode", test_read_bond_opts_mode_numeric); - /* bridging */ g_test_add_func (TPATH "bridge/read-master", test_read_bridge_main); g_test_add_func (TPATH "bridge/write-master", test_write_bridge_main); g_test_add_func (TPATH "bridge/read-component", test_read_bridge_component); g_test_add_func (TPATH "bridge/write-component", test_write_bridge_component); g_test_add_func (TPATH "bridge/read-missing-stp", test_read_bridge_missing_stp); - /* Team */ g_test_add_func (TPATH "team/read-master", test_read_team_master); g_test_add_func (TPATH "team/write-master", test_write_team_master); g_test_add_func (TPATH "team/read-port", test_read_team_port); g_test_add_func (TPATH "team/write-port", test_write_team_port); g_test_add_func (TPATH "team/read-port-empty-config", test_read_team_port_empty_config); + g_test_add_func (TPATH "sit/read/ignore", test_sit_read_ignore); + /* Stuff we expect to fail for now */ g_test_add_func (TPATH "pppoe/write-wired", test_write_wired_pppoe); g_test_add_func (TPATH "vpn/write", test_write_vpn);