libnm: change NMVariantAttributeSpec.str_type to work for attributes of any type

First of all, all of NMVariantAttributeSpec is internal API. We only
expose the typedef itself as public API, but not its fields nor
their meaning. So we can change things.

Change "str_type" to "type_detail", so that it can work for any kind of
attribute, not only for strings. Usually, we want to avoid special
cases and treat all attributes the same, based on their GVariant type.
But sometimes, it is necessary to do something special with an
attribute. This is what the "type_detail" encodes, but it's not only
relevant for strings.

(cherry picked from commit 6f277d8fa6)
This commit is contained in:
Thomas Haller
2022-02-03 17:09:53 +01:00
parent 11d4d244dd
commit 70c2478f89
3 changed files with 90 additions and 80 deletions

View File

@@ -1204,7 +1204,7 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_FROM,
G_VARIANT_TYPE_STRING,
.v6 = TRUE,
.str_type = 'p', ),
.type_detail = 'p', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_INITCWND,
G_VARIANT_TYPE_UINT32,
.v4 = TRUE,
@@ -1248,7 +1248,7 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
G_VARIANT_TYPE_STRING,
.v4 = TRUE,
.v6 = TRUE,
.str_type = 'a', ),
.type_detail = 'a', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_TABLE,
G_VARIANT_TYPE_UINT32,
.v4 = TRUE,
@@ -1258,7 +1258,7 @@ static const NMVariantAttributeSpec *const ip_route_attribute_spec[] = {
G_VARIANT_TYPE_STRING,
.v4 = TRUE,
.v6 = TRUE,
.str_type = 'T', ),
.type_detail = 'T', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_IP_ROUTE_ATTRIBUTE_WINDOW,
G_VARIANT_TYPE_UINT32,
.v4 = TRUE,
@@ -1302,6 +1302,7 @@ nm_ip_route_attribute_validate(const char *name,
GError **error)
{
const NMVariantAttributeSpec *spec;
const char *string;
g_return_val_if_fail(name, FALSE);
g_return_val_if_fail(value, FALSE);
@@ -1340,11 +1341,9 @@ nm_ip_route_attribute_validate(const char *name,
return FALSE;
}
if (g_variant_type_equal(spec->type, G_VARIANT_TYPE_STRING)) {
const char *string = g_variant_get_string(value, NULL);
switch (spec->str_type) {
switch (spec->type_detail) {
case 'a': /* IP address */
string = g_variant_get_string(value, NULL);
if (!nm_utils_ipaddr_is_valid(family, string)) {
g_set_error(error,
NM_CONNECTION_ERROR,
@@ -1358,15 +1357,17 @@ nm_ip_route_attribute_validate(const char *name,
case 'p': /* IP address + optional prefix */
{
gs_free char *addr_free = NULL;
const char *addr = string;
const char *addr;
const char *str;
string = g_variant_get_string(value, NULL);
addr = string;
str = strchr(addr, '/');
if (str) {
addr = nm_strndup_a(200, addr, str - addr, &addr_free);
str++;
if (_nm_utils_ascii_str_to_int64(str, 10, 0, family == AF_INET ? 32 : 128, -1)
< 0) {
if (_nm_utils_ascii_str_to_int64(str, 10, 0, family == AF_INET ? 32 : 128, -1) < 0) {
g_set_error(error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_FAILED,
@@ -1387,6 +1388,7 @@ nm_ip_route_attribute_validate(const char *name,
break;
}
case 'T': /* route type. */
string = g_variant_get_string(value, NULL);
if (!NM_IN_SET(nm_net_aux_rtnl_rtntype_a2n(string), RTN_UNICAST, RTN_LOCAL)) {
g_set_error(error,
NM_CONNECTION_ERROR,
@@ -1396,9 +1398,11 @@ nm_ip_route_attribute_validate(const char *name,
return FALSE;
}
break;
default:
case '\0':
break;
default:
nm_assert_not_reached();
break;
}
}
return TRUE;

View File

@@ -350,13 +350,13 @@ nm_sriov_vf_get_attribute(const NMSriovVF *vf, const char *name)
const NMVariantAttributeSpec *const _nm_sriov_vf_attribute_spec[] = {
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MAC,
G_VARIANT_TYPE_STRING,
.str_type = 'm', ),
.type_detail = 'm', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK, G_VARIANT_TYPE_BOOLEAN, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_TRUST, G_VARIANT_TYPE_BOOLEAN, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE, G_VARIANT_TYPE_UINT32, ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE, G_VARIANT_TYPE_UINT32, ),
/* D-Bus only, synthetic attributes */
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("vlans", G_VARIANT_TYPE_STRING, .str_type = 'd', ),
NM_VARIANT_ATTRIBUTE_SPEC_DEFINE("vlans", G_VARIANT_TYPE_STRING, .type_detail = 'd', ),
NULL,
};
@@ -379,6 +379,7 @@ nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *know
{
const NMVariantAttributeSpec *const *iter;
const NMVariantAttributeSpec *spec = NULL;
const char *string;
g_return_val_if_fail(name, FALSE);
g_return_val_if_fail(value, FALSE);
@@ -391,7 +392,7 @@ nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *know
}
}
if (!spec || spec->str_type == 'd') {
if (!spec || spec->type_detail == 'd') {
NM_SET_OUT(known, FALSE);
g_set_error_literal(error,
NM_CONNECTION_ERROR,
@@ -411,10 +412,7 @@ nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *know
return FALSE;
}
if (g_variant_type_equal(spec->type, G_VARIANT_TYPE_STRING)) {
const char *string;
switch (spec->str_type) {
switch (spec->type_detail) {
case 'm': /* MAC address */
string = g_variant_get_string(value, NULL);
if (!nm_utils_hwaddr_valid(string, -1)) {
@@ -426,9 +424,11 @@ nm_sriov_vf_attribute_validate(const char *name, GVariant *value, gboolean *know
return FALSE;
}
break;
default:
case '\0':
break;
default:
nm_assert_not_reached();
break;
}
}
return TRUE;

View File

@@ -3148,7 +3148,13 @@ struct _NMVariantAttributeSpec {
bool v6 : 1;
bool no_value : 1;
bool consumes_rest : 1;
char str_type;
/* This indicates a non-standard parsing behavior. What this is,
* depends on the actual validation and how to handle it.
*
* Note that the entire NMVariantAttributeSpec is internal API,
* so we can change behavior and adjust it as it fits. */
char type_detail;
};
typedef struct _NMVariantAttributeSpec NMVariantAttributeSpec;