libnm: add API to NMSettingIPConfig for routing rules
This commit is contained in:
@@ -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,
|
||||
|
@@ -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:
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 },
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user