ifupdown: add support for ipv6 connections
This commit is contained in:

committed by
Dan Williams

parent
72bef29d5d
commit
2c83670ed7
@@ -432,15 +432,27 @@ eni_plugin_error_quark() {
|
|||||||
|
|
||||||
return error_quark;
|
return error_quark;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ifupdown_add_search_item(gpointer data, gpointer user_data)
|
ifupdown_ip4_add_search_item(gpointer data, gpointer user_data)
|
||||||
{
|
{
|
||||||
const char *dns_search = data;
|
const char *dns_search = data;
|
||||||
NMSettingIP4Config *ip4_setting = user_data;
|
NMSettingIP4Config *ip4_setting = user_data;
|
||||||
|
|
||||||
if (!nm_setting_ip4_config_add_dns_search (ip4_setting, dns_search))
|
if (!nm_setting_ip4_config_add_dns_search (ip4_setting, dns_search))
|
||||||
PLUGIN_WARN ("SCPlugin-Ifupdown", " warning: duplicate DNS domain '%s'", dns_search);
|
PLUGIN_WARN ("SCPlugin-Ifupdown",
|
||||||
|
" warning: duplicate DNS domain '%s'", dns_search);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ifupdown_ip6_add_search_item(gpointer data, gpointer user_data)
|
||||||
|
{
|
||||||
|
const char *dns_search = data;
|
||||||
|
NMSettingIP6Config *ip6_setting = user_data;
|
||||||
|
|
||||||
|
if (!nm_setting_ip6_config_add_dns_search (ip6_setting, dns_search))
|
||||||
|
PLUGIN_WARN ("SCPlugin-Ifupdown",
|
||||||
|
" warning: duplicate DNS domain '%s'", dns_search);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -527,8 +539,8 @@ update_ip4_setting_from_if_block(NMConnection *connection,
|
|||||||
PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
|
||||||
|
|
||||||
/* DNS searches */
|
/* DNS searches */
|
||||||
if (search_list) {
|
if (search_list) {
|
||||||
g_slist_foreach (search_list, (GFunc) ifupdown_add_search_item, ip4_setting);
|
g_slist_foreach (search_list, (GFunc) ifupdown_ip4_add_search_item, ip4_setting);
|
||||||
g_slist_foreach (search_list, (GFunc) g_free, NULL);
|
g_slist_foreach (search_list, (GFunc) g_free, NULL);
|
||||||
g_slist_free (search_list);
|
g_slist_free (search_list);
|
||||||
}
|
}
|
||||||
@@ -544,6 +556,105 @@ update_ip4_setting_from_if_block(NMConnection *connection,
|
|||||||
nm_connection_add_setting(connection, NM_SETTING(ip4_setting));
|
nm_connection_add_setting(connection, NM_SETTING(ip4_setting));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_ip6_setting_from_if_block(NMConnection *connection,
|
||||||
|
if_block *block)
|
||||||
|
{
|
||||||
|
NMSettingIP6Config *ip6_setting = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new());
|
||||||
|
const char *type = ifparser_getkey(block, "inet6");
|
||||||
|
gboolean is_static = type && (!strcmp("static", type) ||
|
||||||
|
!strcmp("v4tunnel", type));
|
||||||
|
|
||||||
|
if(!is_static) {
|
||||||
|
g_object_set(ip6_setting,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
struct in6_addr tmp_ip6_addr;
|
||||||
|
NMIP6Address *ip6_addr = nm_ip6_address_new ();
|
||||||
|
|
||||||
|
const char *address_v = ifparser_getkey(block, "address");
|
||||||
|
const char *prefix_v = ifparser_getkey(block, "netmask");
|
||||||
|
const char *gateway_v = ifparser_getkey(block, "gateway");
|
||||||
|
const char *nameserver_v = ifparser_getkey(block, "dns-nameserver");
|
||||||
|
const char *nameservers_v = ifparser_getkey(block, "dns-nameservers");
|
||||||
|
const char *search_v = ifparser_getkey(block, "dns-search");
|
||||||
|
int prefix_int;
|
||||||
|
GSList* nameservers_list = NULL;
|
||||||
|
GSList* nameservers_list_i = NULL;
|
||||||
|
GSList* search_list = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if(nameservers_v)
|
||||||
|
nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v);
|
||||||
|
if(nameserver_v)
|
||||||
|
nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v));
|
||||||
|
if(search_v)
|
||||||
|
search_list = string_to_glist_of_strings (search_v);
|
||||||
|
|
||||||
|
if (!address_v)
|
||||||
|
address_v = g_strdup ("::");
|
||||||
|
|
||||||
|
if (inet_pton (AF_INET6, address_v, &tmp_ip6_addr))
|
||||||
|
nm_ip6_address_set_address (ip6_addr, &tmp_ip6_addr);
|
||||||
|
else
|
||||||
|
g_set_error (&error, eni_plugin_error_quark (), 0,
|
||||||
|
"Invalid %s IP6 address '%s'", "address", address_v);
|
||||||
|
if (!prefix_v)
|
||||||
|
prefix_v = g_strdup( "128");
|
||||||
|
|
||||||
|
prefix_int = g_ascii_strtoll(prefix_v, NULL, 10);
|
||||||
|
nm_ip6_address_set_prefix (ip6_addr, prefix_int);
|
||||||
|
|
||||||
|
if (!gateway_v)
|
||||||
|
gateway_v = g_strdup (address_v);
|
||||||
|
|
||||||
|
if (inet_pton (AF_INET, gateway_v, &tmp_ip6_addr))
|
||||||
|
nm_ip6_address_set_gateway (ip6_addr, &tmp_ip6_addr);
|
||||||
|
else
|
||||||
|
g_set_error (&error, eni_plugin_error_quark (), 0,
|
||||||
|
"Invalid %s IP6 address '%s'", "gateway", gateway_v);
|
||||||
|
|
||||||
|
if (nm_setting_ip6_config_add_address (ip6_setting, ip6_addr)) {
|
||||||
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
|
||||||
|
nm_setting_ip6_config_get_num_addresses (ip6_setting));
|
||||||
|
} else {
|
||||||
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP6 address");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nameservers_list_i) {
|
||||||
|
gchar *dns = nameservers_list_i->data;
|
||||||
|
nameservers_list_i = nameservers_list_i->next;
|
||||||
|
if (!dns)
|
||||||
|
continue;
|
||||||
|
if (inet_pton (AF_INET6, dns, &tmp_ip6_addr)) {
|
||||||
|
if (!nm_setting_ip6_config_add_dns (ip6_setting, &tmp_ip6_addr))
|
||||||
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns);
|
||||||
|
} else
|
||||||
|
g_set_error (&error, eni_plugin_error_quark (), 0,
|
||||||
|
"Invalid %s IP6 address nameserver '%s'", "nameserver", dns);
|
||||||
|
}
|
||||||
|
if (!nm_setting_ip6_config_get_num_dns (ip6_setting))
|
||||||
|
PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
|
||||||
|
|
||||||
|
/* DNS searches */
|
||||||
|
if (search_list) {
|
||||||
|
g_slist_foreach (search_list, (GFunc) ifupdown_ip6_add_search_item, ip6_setting);
|
||||||
|
g_slist_foreach (search_list, (GFunc) g_free, NULL);
|
||||||
|
g_slist_free (search_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set (ip6_setting,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_slist_foreach (nameservers_list, (GFunc) g_free, NULL);
|
||||||
|
g_slist_free (nameservers_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_connection_add_setting(connection, NM_SETTING(ip6_setting));
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
ifupdown_update_connection_from_if_block (NMConnection *connection,
|
ifupdown_update_connection_from_if_block (NMConnection *connection,
|
||||||
if_block *block,
|
if_block *block,
|
||||||
@@ -581,13 +692,16 @@ ifupdown_update_connection_from_if_block (NMConnection *connection,
|
|||||||
block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
|
block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
|
||||||
|
|
||||||
if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type))
|
if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type))
|
||||||
update_wired_setting_from_if_block (connection, block);
|
update_wired_setting_from_if_block (connection, block);
|
||||||
else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
|
else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
|
||||||
update_wireless_setting_from_if_block (connection, block);
|
update_wireless_setting_from_if_block (connection, block);
|
||||||
update_wireless_security_setting_from_if_block (connection, block);
|
update_wireless_security_setting_from_if_block (connection, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_ip4_setting_from_if_block (connection, block);
|
if (ifparser_haskey(block, "inet6"))
|
||||||
|
update_ip6_setting_from_if_block (connection, block);
|
||||||
|
else
|
||||||
|
update_ip4_setting_from_if_block (connection, block);
|
||||||
|
|
||||||
success = nm_connection_verify (connection, error);
|
success = nm_connection_verify (connection, error);
|
||||||
|
|
||||||
|
@@ -637,6 +637,207 @@ test17_read_static_ipv4 (const char *path)
|
|||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test18_read_static_ipv6 (const char *path)
|
||||||
|
{
|
||||||
|
NMConnection *connection;
|
||||||
|
NMSettingConnection *s_con;
|
||||||
|
NMSettingIP6Config *s_ip6;
|
||||||
|
NMSettingWired *s_wired;
|
||||||
|
char *unmanaged = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
const char* tmp;
|
||||||
|
const char *expected_address = "fc00::1";
|
||||||
|
const char *expected_id = "Ifupdown (myip6tunnel)";
|
||||||
|
const char *expected_dns1 = "fc00::2";
|
||||||
|
const char *expected_dns2 = "fc00::3";
|
||||||
|
const char *expected_search1 = "example.com";
|
||||||
|
const char *expected_search2 = "foo.example.com";
|
||||||
|
guint32 expected_prefix = 64;
|
||||||
|
NMIP6Address *ip6_addr;
|
||||||
|
struct in6_addr addr;
|
||||||
|
if_block *block = NULL;
|
||||||
|
#define TEST18_NAME "wired-static-verify-ip6"
|
||||||
|
const char* file = "test18-" TEST18_NAME;
|
||||||
|
|
||||||
|
init_ifparser_with_file (path, file);
|
||||||
|
block = ifparser_getfirst ();
|
||||||
|
connection = nm_connection_new();
|
||||||
|
ifupdown_update_connection_from_if_block(connection, block, &error);
|
||||||
|
|
||||||
|
ASSERT (connection != NULL,
|
||||||
|
TEST18_NAME
|
||||||
|
"failed to read %s: %s", file, error->message);
|
||||||
|
|
||||||
|
ASSERT (nm_connection_verify (connection, &error),
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: %s", file, error->message);
|
||||||
|
|
||||||
|
ASSERT (unmanaged == NULL,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected unmanaged value", file);
|
||||||
|
|
||||||
|
/* ===== CONNECTION SETTING ===== */
|
||||||
|
|
||||||
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
|
ASSERT (s_con != NULL,
|
||||||
|
TEST18_NAME, "failed to verify %s: missing %s setting",
|
||||||
|
file,
|
||||||
|
NM_SETTING_CONNECTION_SETTING_NAME);
|
||||||
|
|
||||||
|
/* ID */
|
||||||
|
tmp = nm_setting_connection_get_id (s_con);
|
||||||
|
ASSERT (tmp != NULL,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: missing %s / %s key",
|
||||||
|
file,
|
||||||
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||||
|
NM_SETTING_CONNECTION_ID);
|
||||||
|
|
||||||
|
ASSERT (strcmp (tmp, expected_id) == 0,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected %s / %s key value",
|
||||||
|
file,
|
||||||
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
||||||
|
NM_SETTING_CONNECTION_ID);
|
||||||
|
|
||||||
|
/* ===== WIRED SETTING ===== */
|
||||||
|
|
||||||
|
s_wired = nm_connection_get_setting_wired (connection);
|
||||||
|
ASSERT (s_wired != NULL,
|
||||||
|
TEST18_NAME, "failed to verify %s: missing %s setting",
|
||||||
|
file,
|
||||||
|
NM_SETTING_WIRED_SETTING_NAME);
|
||||||
|
|
||||||
|
/* ===== IPv6 SETTING ===== */
|
||||||
|
|
||||||
|
ASSERT (inet_pton (AF_INET6, expected_address, &addr) > 0,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: couldn't convert IP address #1",
|
||||||
|
file);
|
||||||
|
|
||||||
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
||||||
|
ASSERT (s_ip6 != NULL,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: missing %s setting",
|
||||||
|
file,
|
||||||
|
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,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected %s / %s key value",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_METHOD);
|
||||||
|
|
||||||
|
/* IP addresses */
|
||||||
|
ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected number of %s / %s",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||||
|
|
||||||
|
ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
|
||||||
|
ASSERT (ip6_addr,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: missing %s / %s #1",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||||
|
|
||||||
|
ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix,
|
||||||
|
TEST18_NAME
|
||||||
|
"failed to verify %s: unexpected %s / %s prefix",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||||
|
|
||||||
|
ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr),
|
||||||
|
&addr),
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected %s / %s",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_ADDRESSES);
|
||||||
|
|
||||||
|
/* DNS Addresses */
|
||||||
|
ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected number of %s / %s values",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS);
|
||||||
|
|
||||||
|
ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: couldn't convert DNS IP address #1",
|
||||||
|
file);
|
||||||
|
|
||||||
|
ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0),
|
||||||
|
&addr),
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected %s / %s #1",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS);
|
||||||
|
|
||||||
|
ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: couldn't convert DNS IP address #2",
|
||||||
|
file);
|
||||||
|
|
||||||
|
ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1),
|
||||||
|
&addr),
|
||||||
|
TEST18_NAME, "failed to verify %s: unexpected %s / %s #2",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS);
|
||||||
|
|
||||||
|
/* DNS search domains */
|
||||||
|
ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 2,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected number of %s / %s values",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
|
||||||
|
|
||||||
|
tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 0);
|
||||||
|
ASSERT (tmp != NULL,
|
||||||
|
"wired-ipv6-manual-verify-ip6",
|
||||||
|
"failed to verify %s: missing %s / %s #1",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
|
||||||
|
|
||||||
|
ASSERT (strcmp (tmp, expected_search1) == 0,
|
||||||
|
"wired-ipv6-manual-verify-ip6",
|
||||||
|
"failed to verify %s: unexpected %s / %s #1",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
|
||||||
|
|
||||||
|
tmp = nm_setting_ip6_config_get_dns_search (s_ip6, 1);
|
||||||
|
ASSERT (tmp != NULL,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: missing %s / %s #2",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
|
||||||
|
|
||||||
|
ASSERT (strcmp (tmp, expected_search2) == 0,
|
||||||
|
TEST18_NAME,
|
||||||
|
"failed to verify %s: unexpected %s / %s #2",
|
||||||
|
file,
|
||||||
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
||||||
|
NM_SETTING_IP6_CONFIG_DNS_SEARCH);
|
||||||
|
|
||||||
|
g_free (unmanaged);
|
||||||
|
g_object_unref (connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if GLIB_CHECK_VERSION(2,25,12)
|
#if GLIB_CHECK_VERSION(2,25,12)
|
||||||
typedef GTestFixtureFunc TCFunc;
|
typedef GTestFixtureFunc TCFunc;
|
||||||
@@ -679,6 +880,7 @@ int main (int argc, char **argv)
|
|||||||
g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR));
|
g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR));
|
||||||
g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR));
|
g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR));
|
||||||
g_test_suite_add (suite, TESTCASE (test17_read_static_ipv4, TEST_ENI_DIR));
|
g_test_suite_add (suite, TESTCASE (test17_read_static_ipv4, TEST_ENI_DIR));
|
||||||
|
g_test_suite_add (suite, TESTCASE (test18_read_static_ipv6, TEST_ENI_DIR));
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
iface myip6tunnel inet6 v4tunnel
|
||||||
|
address fc00::1
|
||||||
|
netmask 64
|
||||||
|
endpoint 78.35.24.124
|
||||||
|
dns-nameservers fc00::2 fc00::3
|
||||||
|
dns-search example.com foo.example.com
|
Reference in New Issue
Block a user