libnm: add API to NMSettingIPConfig for routing rules

This commit is contained in:
Thomas Haller 2019-03-14 12:04:21 +01:00
parent 7fb23b0a62
commit 6e6d1e070c
6 changed files with 578 additions and 3 deletions

View file

@ -541,6 +541,7 @@ typedef struct {
typedef enum {
BUILD_LIST_TYPE_ADDRESSES,
BUILD_LIST_TYPE_ROUTES,
BUILD_LIST_TYPE_ROUTING_RULES,
} BuildListType;
static int
@ -661,6 +662,12 @@ _build_list_create (GKeyFile *keyfile,
else
continue;
break;
case BUILD_LIST_TYPE_ROUTING_RULES:
if (_build_list_match_key_w_name (s_key, "routing-rule", &key_idx))
key_type = 0;
else
continue;
break;
default:
nm_assert_not_reached ();
break;
@ -759,6 +766,63 @@ ip_address_or_route_parser (KeyfileReaderInfo *info, NMSetting *setting, const c
g_object_set (setting, "gateway", gateway, NULL);
}
static void
ip_routing_rule_parser_full (KeyfileReaderInfo *info,
const NMMetaSettingInfo *setting_info,
const NMSettInfoProperty *property_info,
const ParseInfoProperty *pip,
NMSetting *setting)
{
const char *setting_name = nm_setting_get_name (setting);
gboolean is_ipv6 = nm_streq (setting_name, "ipv6");
gs_strfreev char **keys = NULL;
gs_free BuildListData *build_list = NULL;
gsize i_build_list, build_list_len = 0;
build_list = _build_list_create (info->keyfile,
setting_name,
BUILD_LIST_TYPE_ROUTING_RULES,
&build_list_len,
&keys);
if (!build_list)
return;
for (i_build_list = 0; i_build_list < build_list_len; i_build_list++) {
nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL;
gs_free char *value = NULL;
gs_free_error GError *local = NULL;
if (_build_list_data_is_shadowed (build_list, build_list_len, i_build_list))
continue;
value = nm_keyfile_plugin_kf_get_string (info->keyfile,
setting_name,
build_list[i_build_list].s_key,
NULL);
if (!value)
continue;
rule = nm_ip_routing_rule_from_string (value,
( NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE
| ( is_ipv6
? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6
: NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET)),
NULL,
&local);
if (!rule) {
handle_warn (info, property_info->name, NM_KEYFILE_WARN_SEVERITY_WARN,
_("invalid value for \"%s\": %s"),
build_list[i_build_list].s_key,
local->message);
if (info->error)
return;
continue;
}
nm_setting_ip_config_add_routing_rule (NM_SETTING_IP_CONFIG (setting), rule);
}
}
static void
ip_dns_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
{
@ -1962,6 +2026,40 @@ bridge_vlan_writer (KeyfileWriterInfo *info,
}
}
static void
ip_routing_rule_writer_full (KeyfileWriterInfo *info,
const NMMetaSettingInfo *setting_info,
const NMSettInfoProperty *property_info,
const ParseInfoProperty *pip,
NMSetting *setting)
{
const char *setting_name = nm_setting_get_name (setting);
NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
guint i, j, n;
char key_name_full[100] = "routing-rule";
char *key_name_num = &key_name_full[NM_STRLEN ("routing-rule")];
n = nm_setting_ip_config_get_num_routing_rules (s_ip);
j = 0;
for (i = 0; i < n; i++) {
NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule (s_ip, i);
gs_free char *str = NULL;
str = nm_ip_routing_rule_to_string (rule,
NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE,
NULL,
NULL);
if (!str)
continue;
sprintf (key_name_num, "%u", ++j);
nm_keyfile_plugin_kf_set_string (info->keyfile,
setting_name,
key_name_full,
str);
}
}
static void
qdisc_writer (KeyfileWriterInfo *info,
NMSetting *setting,
@ -2463,6 +2561,13 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
.parser = ip_address_or_route_parser,
.writer = route_writer,
),
PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTING_RULES,
.parser_no_check_key = TRUE,
.parser_full = ip_routing_rule_parser_full,
.writer_full = ip_routing_rule_writer_full,
.has_parser_full = TRUE,
.has_writer_full = TRUE,
),
),
),
PARSE_INFO_SETTING (NM_META_SETTING_TYPE_IP6_CONFIG,
@ -2491,6 +2596,13 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
.parser = ip_address_or_route_parser,
.writer = route_writer,
),
PARSE_INFO_PROPERTY (NM_SETTING_IP_CONFIG_ROUTING_RULES,
.parser_no_check_key = TRUE,
.parser_full = ip_routing_rule_parser_full,
.writer_full = ip_routing_rule_writer_full,
.has_parser_full = TRUE,
.has_writer_full = TRUE,
),
),
),
PARSE_INFO_SETTING (NM_META_SETTING_TYPE_SERIAL,

View file

@ -3533,6 +3533,7 @@ typedef struct {
int dns_priority;
GPtrArray *addresses; /* array of NMIPAddress */
GPtrArray *routes; /* array of NMIPRoute */
GPtrArray *routing_rules;
gint64 route_metric;
guint32 route_table;
char *gateway;
@ -4434,6 +4435,225 @@ nm_setting_ip_config_get_route_table (NMSettingIPConfig *setting)
return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->route_table;
}
/*****************************************************************************/
static void
_routing_rules_notify (NMSettingIPConfig *setting)
{
_nm_setting_emit_property_changed (NM_SETTING (setting));
}
/**
* nm_setting_ip_config_get_num_routing_rules:
* @setting: the #NMSettingIPConfig
*
* Returns: the number of configured routing rules
*
* Since: 1.18
**/
guint
nm_setting_ip_config_get_num_routing_rules (NMSettingIPConfig *setting)
{
NMSettingIPConfigPrivate *priv;
g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
return priv->routing_rules ? priv->routing_rules->len : 0u;
}
/**
* nm_setting_ip_config_get_routing_rule:
* @setting: the #NMSettingIPConfig
* @idx: index number of the routing_rule to return
*
* Returns: (transfer none): the routing rule at index @idx
*
* Since: 1.18
**/
NMIPRoutingRule *
nm_setting_ip_config_get_routing_rule (NMSettingIPConfig *setting, guint idx)
{
NMSettingIPConfigPrivate *priv;
g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
g_return_val_if_fail (priv->routing_rules && idx < priv->routing_rules->len, NULL);
return priv->routing_rules->pdata[idx];
}
/**
* nm_setting_ip_config_add_routing_rule:
* @setting: the #NMSettingIPConfig
* @routing_rule: the #NMIPRoutingRule to add. The address family
* of the added rule must be compatible with the setting.
*
* Appends a new routing-rule and associated information to the setting. The
* given routing rules gets sealed and the reference count is incremented.
* The function does not check whether an identical rule already exists
* and always appends the rule to the end of the list.
*
* Since: 1.18
**/
void
nm_setting_ip_config_add_routing_rule (NMSettingIPConfig *setting,
NMIPRoutingRule *routing_rule)
{
NMSettingIPConfigPrivate *priv;
g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
g_return_if_fail (NM_IS_IP_ROUTING_RULE (routing_rule, TRUE));
g_return_if_fail (_ip_routing_rule_get_addr_family (routing_rule) == NM_SETTING_IP_CONFIG_GET_FAMILY (setting));
priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
if (!priv->routing_rules)
priv->routing_rules = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_routing_rule_unref);
nm_ip_routing_rule_seal (routing_rule);
g_ptr_array_add (priv->routing_rules, nm_ip_routing_rule_ref (routing_rule));
_routing_rules_notify (setting);
}
/**
* nm_setting_ip_config_remove_routing_rule:
* @setting: the #NMSettingIPConfig
* @idx: index number of the routing_rule
*
* Removes the routing_rule at index @idx.
*
* Since: 1.18
**/
void
nm_setting_ip_config_remove_routing_rule (NMSettingIPConfig *setting,
guint idx)
{
NMSettingIPConfigPrivate *priv;
g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
g_return_if_fail (priv->routing_rules && idx < priv->routing_rules->len);
g_ptr_array_remove_index (priv->routing_rules, idx);
_routing_rules_notify (setting);
}
/**
* nm_setting_ip_config_clear_routing_rules:
* @setting: the #NMSettingIPConfig
*
* Removes all configured routing rules.
*
* Since: 1.18
**/
void
nm_setting_ip_config_clear_routing_rules (NMSettingIPConfig *setting)
{
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
if ( priv->routing_rules
&& priv->routing_rules->len > 0) {
g_ptr_array_set_size (priv->routing_rules, 0);
_routing_rules_notify (setting);
}
}
static GVariant *
_routing_rules_dbus_only_synth (const NMSettInfoSetting *sett_info,
guint property_idx,
NMConnection *connection,
NMSetting *setting,
NMConnectionSerializationFlags flags)
{
NMSettingIPConfig *self = NM_SETTING_IP_CONFIG (setting);
NMSettingIPConfigPrivate *priv;
GVariantBuilder builder;
gboolean any = FALSE;
guint i;
priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (self);
if ( !priv->routing_rules
|| priv->routing_rules->len == 0)
return NULL;
for (i = 0; i < priv->routing_rules->len; i++) {
GVariant *variant;
variant = nm_ip_routing_rule_to_dbus (priv->routing_rules->pdata[i]);
if (!variant)
continue;
if (!any) {
any = TRUE;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
}
g_variant_builder_add (&builder, "@a{sv}", variant);
}
return any ? g_variant_builder_end (&builder) : NULL;
}
static gboolean
_routing_rules_dbus_only_set (NMSetting *setting,
GVariant *connection_dict,
const char *property,
GVariant *value,
NMSettingParseFlags parse_flags,
GError **error)
{
GVariantIter iter_rules;
GVariant *rule_var;
guint i_rule;
gboolean success = FALSE;
gboolean rules_changed = FALSE;
nm_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")));
g_variant_iter_init (&iter_rules, value);
i_rule = 0;
while (g_variant_iter_next (&iter_rules, "@a{sv}", &rule_var)) {
_nm_unused gs_unref_variant GVariant *rule_var_unref = rule_var;
nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL;
gs_free_error GError *local = NULL;
i_rule++;
rule = nm_ip_routing_rule_from_dbus (rule_var,
NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT),
&local);
if (!rule) {
if (NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("rule #%u is invalid: %s"),
i_rule,
local->message);
goto out;
}
continue;
}
nm_setting_ip_config_add_routing_rule (NM_SETTING_IP_CONFIG (setting), rule);
rules_changed = TRUE;
}
success = TRUE;
out:
if (rules_changed)
_routing_rules_notify (NM_SETTING_IP_CONFIG (setting));
return success;
}
/*****************************************************************************/
/**
* nm_setting_ip_config_get_ignore_auto_routes:
* @setting: the #NMSettingIPConfig
@ -4720,6 +4940,33 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
}
if (priv->routing_rules) {
for (i = 0; i < priv->routing_rules->len; i++) {
NMIPRoutingRule *rule = priv->routing_rules->pdata[i];
gs_free_error GError *local = NULL;
if (_ip_routing_rule_get_addr_family (rule) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("%u. rule has wrong address-family"),
i + 1);
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTING_RULES);
return FALSE;
}
if (!nm_ip_routing_rule_validate (rule, &local)) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("%u. rule is invalid: %s"),
i + 1,
local->message);
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES);
return FALSE;
}
}
}
if (priv->gateway && priv->never_default) {
g_set_error (error,
NM_CONNECTION_ERROR,
@ -4774,6 +5021,24 @@ compare_property (const NMSettInfoSetting *sett_info,
return TRUE;
}
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_IP_CONFIG_ROUTING_RULES)) {
if (other) {
guint n;
a_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
b_priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (other);
n = (a_priv->routing_rules) ? a_priv->routing_rules->len : 0u;
if (n != (b_priv->routing_rules ? b_priv->routing_rules->len : 0u))
return FALSE;
for (i = 0; i < n; i++) {
if (nm_ip_routing_rule_cmp (a_priv->routing_rules->pdata[i], b_priv->routing_rules->pdata[i]) != 0)
return FALSE;
}
}
return TRUE;
}
return NM_SETTING_CLASS (nm_setting_ip_config_parent_class)->compare_property (sett_info,
property_idx,
setting,
@ -4781,6 +5046,72 @@ compare_property (const NMSettInfoSetting *sett_info,
flags);
}
static void
duplicate_copy_properties (const NMSettInfoSetting *sett_info,
NMSetting *src,
NMSetting *dst)
{
NMSettingIPConfigPrivate *priv_src = NM_SETTING_IP_CONFIG_GET_PRIVATE (src);
NMSettingIPConfigPrivate *priv_dst = NM_SETTING_IP_CONFIG_GET_PRIVATE (dst);
guint i;
gboolean changed = FALSE;
NM_SETTING_CLASS (nm_setting_ip_config_parent_class)->duplicate_copy_properties (sett_info,
src,
dst);
if ( priv_dst->routing_rules
&& priv_dst->routing_rules->len > 0) {
changed = TRUE;
g_ptr_array_set_size (priv_dst->routing_rules, 0);
}
if ( priv_src->routing_rules
&& priv_src->routing_rules->len > 0) {
changed = TRUE;
if (!priv_dst->routing_rules)
priv_dst->routing_rules = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_routing_rule_unref);
for (i = 0; i < priv_src->routing_rules->len; i++) {
g_ptr_array_add (priv_dst->routing_rules,
nm_ip_routing_rule_ref (priv_src->routing_rules->pdata[i]));
}
}
if (changed)
_routing_rules_notify (NM_SETTING_IP_CONFIG (dst));
}
static void
enumerate_values (const NMSettInfoProperty *property_info,
NMSetting *setting,
NMSettingValueIterFn func,
gpointer user_data)
{
if (nm_streq (property_info->name, NM_SETTING_IP_CONFIG_ROUTING_RULES)) {
NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
nm_auto_unset_gvalue GValue value = G_VALUE_INIT;
GPtrArray *ptr = NULL;
guint i;
if (priv->routing_rules && priv->routing_rules->len > 0) {
ptr = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_routing_rule_unref);
for (i = 0; i < priv->routing_rules->len; i++)
g_ptr_array_add (ptr, nm_ip_routing_rule_ref (priv->routing_rules->pdata[i]));
}
g_value_init (&value, G_TYPE_PTR_ARRAY);
g_value_take_boxed (&value, ptr);
func (setting,
property_info->name,
&value,
0,
user_data);
return;
}
NM_SETTING_CLASS (nm_setting_ip_config_parent_class)->enumerate_values (property_info,
setting,
func,
user_data);
}
/*****************************************************************************/
static gboolean
@ -4813,6 +5144,18 @@ _nm_sett_info_property_override_create_array_ip_config (void)
ip_gateway_set,
NULL);
/* ---dbus---
* property: routing-rules
* format: array of 'a{sv}'
* description: Array of dictionaries for routing rules.
* ---end---
*/
_properties_override_add_dbus_only (properties_override,
NM_SETTING_IP_CONFIG_ROUTING_RULES,
G_VARIANT_TYPE ("aa{sv}"),
_routing_rules_dbus_only_synth,
_routing_rules_dbus_only_set);
return properties_override;
}
@ -5020,6 +5363,8 @@ finalize (GObject *object)
g_ptr_array_unref (priv->dns_options);
g_ptr_array_unref (priv->addresses);
g_ptr_array_unref (priv->routes);
if (priv->routing_rules)
g_ptr_array_unref (priv->routing_rules);
G_OBJECT_CLASS (nm_setting_ip_config_parent_class)->finalize (object);
}
@ -5036,8 +5381,10 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass)
object_class->set_property = set_property;
object_class->finalize = finalize;
setting_class->verify = verify;
setting_class->compare_property = compare_property;
setting_class->verify = verify;
setting_class->compare_property = compare_property;
setting_class->duplicate_copy_properties = duplicate_copy_properties;
setting_class->enumerate_values = enumerate_values;
/**
* NMSettingIPConfig:method:

View file

@ -334,6 +334,9 @@ char *nm_ip_routing_rule_to_string (const NMIPRoutingRule *self,
#define NM_SETTING_IP_CONFIG_DAD_TIMEOUT "dad-timeout"
#define NM_SETTING_IP_CONFIG_DHCP_TIMEOUT "dhcp-timeout"
/* these are not real GObject properties. */
#define NM_SETTING_IP_CONFIG_ROUTING_RULES "routing-rules"
#define NM_SETTING_DNS_OPTION_DEBUG "debug"
#define NM_SETTING_DNS_OPTION_NDOTS "ndots"
#define NM_SETTING_DNS_OPTION_TIMEOUT "timeout"
@ -436,6 +439,20 @@ gint64 nm_setting_ip_config_get_route_metric (NMSettingIPConfig
NM_AVAILABLE_IN_1_10
guint32 nm_setting_ip_config_get_route_table (NMSettingIPConfig *setting);
NM_AVAILABLE_IN_1_18
guint nm_setting_ip_config_get_num_routing_rules (NMSettingIPConfig *setting);
NM_AVAILABLE_IN_1_18
NMIPRoutingRule *nm_setting_ip_config_get_routing_rule (NMSettingIPConfig *setting,
guint idx);
NM_AVAILABLE_IN_1_18
void nm_setting_ip_config_add_routing_rule (NMSettingIPConfig *setting,
NMIPRoutingRule *routing_rule);
NM_AVAILABLE_IN_1_18
void nm_setting_ip_config_remove_routing_rule (NMSettingIPConfig *setting,
guint idx);
NM_AVAILABLE_IN_1_18
void nm_setting_ip_config_clear_routing_rules (NMSettingIPConfig *setting);
gboolean nm_setting_ip_config_get_ignore_auto_routes (NMSettingIPConfig *setting);
gboolean nm_setting_ip_config_get_ignore_auto_dns (NMSettingIPConfig *setting);

View file

@ -2710,6 +2710,7 @@ test_connection_diff_a_only (void)
{ NM_SETTING_IP_CONFIG_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_ROUTE_METRIC, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_ROUTE_TABLE, NM_SETTING_DIFF_RESULT_IN_A },
{ NM_SETTING_IP_CONFIG_ROUTING_RULES, 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 },
{ NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A },

View file

@ -2362,7 +2362,16 @@ test_roundtrip_conversion (gconstpointer test_data)
NMSettingConnection *s_con = NULL;
NMSettingWired *s_eth = NULL;
NMSettingWireGuard *s_wg = NULL;
union {
struct {
NMSettingIPConfig *s_6;
NMSettingIPConfig *s_4;
};
NMSettingIPConfig *s_x[2];
} s_ip;
int is_ipv4;
guint i;
gboolean success;
switch (MODE) {
case 0:
@ -2549,6 +2558,89 @@ test_roundtrip_conversion (gconstpointer test_data)
_rndt_wg_peers_assert_equal (s_wg, wg_peers, TRUE, TRUE, FALSE);
break;
case 3:
con = nmtst_create_minimal_connection (ID, UUID, NM_SETTING_WIRED_SETTING_NAME, &s_con);
g_object_set (s_con,
NM_SETTING_CONNECTION_INTERFACE_NAME,
INTERFACE_NAME,
NULL);
nmtst_connection_normalize (con);
s_eth = NM_SETTING_WIRED (nm_connection_get_setting (con, NM_TYPE_SETTING_WIRED));
g_assert (NM_IS_SETTING_WIRED (s_eth));
g_object_set (s_eth,
NM_SETTING_WIRED_MTU,
ETH_MTU,
NULL);
s_ip.s_4 = NM_SETTING_IP_CONFIG (nm_connection_get_setting (con, NM_TYPE_SETTING_IP4_CONFIG));
g_assert (NM_IS_SETTING_IP4_CONFIG (s_ip.s_4));
s_ip.s_6 = NM_SETTING_IP_CONFIG (nm_connection_get_setting (con, NM_TYPE_SETTING_IP6_CONFIG));
g_assert (NM_IS_SETTING_IP6_CONFIG (s_ip.s_6));
for (is_ipv4 = 0; is_ipv4 < 2; is_ipv4++) {
g_assert (NM_IS_SETTING_IP_CONFIG (s_ip.s_x[is_ipv4]));
for (i = 0; i < 3; i++) {
char addrstr[NM_UTILS_INET_ADDRSTRLEN];
nm_auto_unref_ip_routing_rule NMIPRoutingRule *rr = NULL;
rr = nm_ip_routing_rule_new (is_ipv4 ? AF_INET : AF_INET6);
nm_ip_routing_rule_set_priority (rr, i + 1);
if (i > 0) {
if (is_ipv4)
nm_sprintf_buf (addrstr, "192.168.%u.0", i);
else
nm_sprintf_buf (addrstr, "1:2:3:%x::", 10 + i);
nm_ip_routing_rule_set_from (rr, addrstr, is_ipv4 ? 24 + i : 64 + i);
}
nm_ip_routing_rule_set_table (rr, 1000 + i);
success = nm_ip_routing_rule_validate (rr, &error);
nmtst_assert_success (success, error);
nm_setting_ip_config_add_routing_rule (s_ip.s_x[is_ipv4], rr);
}
}
g_ptr_array_add (kf_data_arr,
g_strdup_printf ("[connection]\n"
"id=%s\n"
"uuid=%s\n"
"type=ethernet\n"
"interface-name=%s\n"
"permissions=\n"
"\n"
"[ethernet]\n"
"mac-address-blacklist=\n"
"%s" /* mtu */
"\n"
"[ipv4]\n"
"dns-search=\n"
"method=auto\n"
"routing-rule1=priority 1 from 0.0.0.0/0 table 1000\n"
"routing-rule2=priority 2 from 192.168.1.0/25 table 1001\n"
"routing-rule3=priority 3 from 192.168.2.0/26 table 1002\n"
"\n"
"[ipv6]\n"
"addr-gen-mode=stable-privacy\n"
"dns-search=\n"
"method=auto\n"
"routing-rule1=priority 1 from ::/0 table 1000\n"
"routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n"
"routing-rule3=priority 3 from 1:2:3:c::/66 table 1002\n"
"",
ID,
UUID,
INTERFACE_NAME,
(ETH_MTU != 0)
? nm_sprintf_bufa (100, "mtu=%u\n", ETH_MTU)
: ""));
break;
default:
g_assert_not_reached ();
}
@ -2951,9 +3043,10 @@ main (int argc, char **argv)
g_test_add_func ("/libnm/settings/team-port/sycn_from_config_full", test_team_port_full_config);
#endif
g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/0", GINT_TO_POINTER (0), test_roundtrip_conversion);
g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/0", GINT_TO_POINTER (0), test_roundtrip_conversion);
g_test_add_data_func ("/libnm/settings/roundtrip-conversion/wireguard/1", GINT_TO_POINTER (1), test_roundtrip_conversion);
g_test_add_data_func ("/libnm/settings/roundtrip-conversion/wireguard/2", GINT_TO_POINTER (2), test_roundtrip_conversion);
g_test_add_data_func ("/libnm/settings/roundtrip-conversion/general/3", GINT_TO_POINTER (3), test_roundtrip_conversion);
g_test_add_data_func ("/libnm/settings/routing-rule/1", GINT_TO_POINTER (0), test_routing_rule);

View file

@ -1595,4 +1595,9 @@ global:
nm_setting_bridge_port_remove_vlan_by_vid;
nm_setting_bridge_remove_vlan;
nm_setting_bridge_remove_vlan_by_vid;
nm_setting_ip_config_add_routing_rule;
nm_setting_ip_config_clear_routing_rules;
nm_setting_ip_config_get_num_routing_rules;
nm_setting_ip_config_get_routing_rule;
nm_setting_ip_config_remove_routing_rule;
} libnm_1_16_0;