diff options
Diffstat (limited to 'libnm-core/nm-setting-ip-config.c')
| -rw-r--r-- | libnm-core/nm-setting-ip-config.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c index 36f09b69..bc811291 100644 --- a/libnm-core/nm-setting-ip-config.c +++ b/libnm-core/nm-setting-ip-config.c @@ -1214,6 +1214,7 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = { NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_SRC, G_VARIANT_TYPE_STRING, .v4 = TRUE, .v6 = TRUE, .str_type = 'a', ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TABLE, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TOS, G_VARIANT_TYPE_BYTE, .v4 = TRUE, ), + NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_TYPE, G_VARIANT_TYPE_STRING, .v4 = TRUE, .v6 = TRUE, .str_type = 'T', ), NM_VARIANT_ATTRIBUTE_SPEC_DEFINE (NM_IP_ROUTE_ATTRIBUTE_WINDOW, G_VARIANT_TYPE_UINT32, .v4 = TRUE, .v6 = TRUE, ), NULL, }; @@ -1339,6 +1340,18 @@ nm_ip_route_attribute_validate (const char *name, } break; } + case 'T': /* route type. */ + if (!NM_IN_SET (nm_utils_route_type_by_name (string), + RTN_UNICAST, + RTN_LOCAL)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("%s is not a valid route type"), + string); + return FALSE; + } + break; default: break; } @@ -1348,22 +1361,48 @@ nm_ip_route_attribute_validate (const char *name, } gboolean -_nm_ip_route_attribute_validate_all (const NMIPRoute *route) +_nm_ip_route_attribute_validate_all (const NMIPRoute *route, GError **error) { GHashTableIter iter; const char *key; GVariant *val; + guint8 u8; g_return_val_if_fail (route, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); if (!route->attributes) return TRUE; g_hash_table_iter_init (&iter, route->attributes); while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &val)) { - if (!nm_ip_route_attribute_validate (key, val, route->family, NULL, NULL)) + if (!nm_ip_route_attribute_validate (key, val, route->family, NULL, error)) return FALSE; } + + if ((val = g_hash_table_lookup (route->attributes, + NM_IP_ROUTE_ATTRIBUTE_TYPE))) { + nm_assert (g_variant_is_of_type (val, G_VARIANT_TYPE_STRING)); + u8 = nm_utils_route_type_by_name (g_variant_get_string (val, NULL)); + + if ( u8 == RTN_LOCAL + && route->family == AF_INET + && (val = g_hash_table_lookup (route->attributes, NM_IP_ROUTE_ATTRIBUTE_SCOPE))) { + nm_assert (g_variant_is_of_type (val, G_VARIANT_TYPE_BYTE)); + u8 = g_variant_get_byte (val); + + if (!NM_IN_SET(u8, + RT_SCOPE_HOST, + RT_SCOPE_NOWHERE)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("route scope is invalid")); + return FALSE; + } + } + } + return TRUE; } @@ -2186,7 +2225,7 @@ nm_ip_routing_rule_get_xifname_bin (const NMIPRoutingRule *self, if (!xifname) return FALSE; - bin = nm_utils_buf_utf8safe_unescape (xifname, &len, &bin_to_free); + bin = nm_utils_buf_utf8safe_unescape (xifname, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &len, &bin_to_free); strncpy (out_xifname, bin, 16 /* IFNAMSIZ */); out_xifname[15] = '\0'; @@ -5020,6 +5059,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) /* Validate routes */ for (i = 0; i < priv->routes->len; i++) { + gs_free_error GError *local = NULL; NMIPRoute *route = (NMIPRoute *) priv->routes->pdata[i]; if (nm_ip_route_get_family (route) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) { @@ -5031,6 +5071,19 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES); return FALSE; } + + if (!_nm_ip_route_attribute_validate_all (route, &local)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("invalid attribute: %s"), + local->message); + g_prefix_error (error, + "%s.%s: ", + nm_setting_get_name (setting), + NM_SETTING_IP_CONFIG_ROUTES); + return FALSE; + } } if (priv->routing_rules) { |