keyfile: support route options

This commit is contained in:
Beniamino Galvani 2017-02-16 00:14:25 +01:00
parent dad1071374
commit cdfa625102
4 changed files with 76 additions and 2 deletions

View file

@ -428,6 +428,31 @@ read_one_ip_address_or_route (KeyfileReaderInfo *info,
return result;
}
static void
fill_route_attributes (GKeyFile *kf, NMIPRoute *route, const char *setting, const char *key, int family)
{
gs_free char *value = NULL;
gs_unref_hashtable GHashTable *hash = NULL;
GHashTableIter iter;
char *name;
GVariant *variant;
value = nm_keyfile_plugin_kf_get_string (kf, setting, key, NULL);
if (!value || !value[0])
return;
hash = nm_utils_parse_variant_attributes (value, ',', '=', TRUE,
nm_ip_route_get_variant_attribute_spec (),
NULL);
if (hash) {
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &variant)) {
if (nm_ip_route_attribute_validate (name, variant, family, NULL, NULL))
nm_ip_route_set_attribute (route, name, g_variant_ref (variant));
}
}
}
static void
ip_address_or_route_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
{
@ -454,6 +479,7 @@ ip_address_or_route_parser (KeyfileReaderInfo *info, NMSetting *setting, const c
for (key_basename = key_names; *key_basename; key_basename++) {
char *key_name;
gpointer item;
char options_key[128];
/* -1 means no suffix */
if (i >= 0)
@ -463,6 +489,11 @@ ip_address_or_route_parser (KeyfileReaderInfo *info, NMSetting *setting, const c
item = read_one_ip_address_or_route (info, key, setting_name, key_name, ipv6, routes,
gateway ? NULL : &gateway, setting);
if (item && routes) {
nm_sprintf_buf (options_key, "%s_options", key_name);
fill_route_attributes (info->keyfile, item, setting_name, options_key, ipv6 ? AF_INET6 : AF_INET);
}
g_free (key_name);
if (info->error) {

View file

@ -138,7 +138,7 @@ write_ip_values (GKeyFile *file,
int family, i;
const char *addr, *gw;
guint32 plen, metric;
char key_name[30], *key_name_idx;
char key_name[64], *key_name_idx;
if (!array->len)
return;
@ -188,6 +188,23 @@ write_ip_values (GKeyFile *file,
sprintf (key_name_idx, "%d", i + 1);
nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str);
if (is_route) {
gs_free char *attributes = NULL;
gs_strfreev char **names = NULL;
gs_unref_hashtable GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
int j;
names = nm_ip_route_get_attribute_names (array->pdata[i]);
for (j = 0; names && names[j]; j++)
g_hash_table_insert (hash, names[j], nm_ip_route_get_attribute (array->pdata[i], names[j]));
attributes = nm_utils_format_variant_attributes (hash, ',', '=');
if (attributes) {
g_strlcat (key_name, "_options", sizeof (key_name));
nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, attributes);
}
}
}
g_string_free (output, TRUE);
}

View file

@ -34,6 +34,7 @@ routes8=1.1.1.8/18,0.0.0.0,
routes9=1.1.1.9/19,0.0.0.0,0
routes10=1.1.1.10/20,,0
routes11=1.1.1.11/21,,21
routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,pref-src=7.7.7.7
ignore-auto-routes=false
ignore-auto-dns=false
@ -58,5 +59,6 @@ route3=6:7:8:9:0:1:2:3/126,,1
route4=7:8:9:0:1:2:3:4/125/::,5
route5=8:9:0:1:2:3:4:5/124,6
route6=8:9:0:1:2:3:4:6/123,,
route6_options=src=abce::/63
ignore-auto-routes=false
ignore-auto-dns=false

View file

@ -224,6 +224,7 @@ test_read_valid_wired_connection (void)
NMSettingWired *s_wired;
NMSettingIPConfig *s_ip4;
NMSettingIPConfig *s_ip6;
NMIPRoute *route;
gs_free_error GError *error = NULL;
const char *mac;
char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
@ -318,6 +319,15 @@ test_read_valid_wired_connection (void)
check_ip_route (s_ip4, 10, "1.1.1.10", 20, NULL, -1);
check_ip_route (s_ip4, 11, "1.1.1.11", 21, NULL, 21);
/* Route attributes */
route = nm_setting_ip_config_get_route (s_ip4, 11);
g_assert (route);
nmtst_assert_route_attribute_uint32 (route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10);
nmtst_assert_route_attribute_uint32 (route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430);
nmtst_assert_route_attribute_boolean (route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE);
nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_PREF_SRC, "7.7.7.7");
/* ===== IPv6 SETTING ===== */
s_ip6 = nm_connection_get_setting_ip6_config (connection);
g_assert (s_ip6);
@ -357,6 +367,11 @@ test_read_valid_wired_connection (void)
check_ip_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5);
check_ip_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6);
check_ip_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1);
/* Route attributes */
route = nm_setting_ip_config_get_route (s_ip6, 6);
g_assert (route);
nmtst_assert_route_attribute_string (route, NM_IP_ROUTE_ATTRIBUTE_SRC, "abce::/63");
}
static void
@ -402,6 +417,7 @@ test_write_wired_connection (void)
NMSettingWired *s_wired;
NMSettingIPConfig *s_ip4;
NMSettingIPConfig *s_ip6;
NMIPRoute *rt;
const char *mac = "99:88:77:66:55:44";
const char *dns1 = "4.2.2.1";
const char *dns2 = "4.2.2.2";
@ -429,6 +445,7 @@ test_write_wired_connection (void)
const char *route6_4 = "5:6:7:8:9:0:1:2";
const char *route6_4_nh = "::";
guint64 timestamp = 0x12345678L;
GError *error = NULL;
connection = nm_simple_connection_new ();
@ -473,7 +490,14 @@ test_write_wired_connection (void)
add_one_ip_route (s_ip4, route1, route1_nh, 24, 3);
add_one_ip_route (s_ip4, route2, route2_nh, 8, 1);
add_one_ip_route (s_ip4, route3, route3_nh, 7, -1);
add_one_ip_route (s_ip4, route4, route4_nh, 6, 4);
rt = nm_ip_route_new (AF_INET, route4, 6, route4_nh, 4, &error);
g_assert_no_error (error);
nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32 (10));
nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32 (1492));
nm_ip_route_set_attribute (rt, NM_IP_ROUTE_ATTRIBUTE_PREF_SRC, g_variant_new_string ("1.2.3.4"));
g_assert (nm_setting_ip_config_add_route (s_ip4, rt));
nm_ip_route_unref (rt);
/* DNS servers */
nm_setting_ip_config_add_dns (s_ip4, dns1);