about summary refs log tree commit diff
path: root/libnm-core/nm-team-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-team-utils.c')
-rw-r--r--libnm-core/nm-team-utils.c4497
1 files changed, 2405 insertions, 2092 deletions
diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c
index 084547c8..2f1fba33 100644
--- a/libnm-core/nm-team-utils.c
+++ b/libnm-core/nm-team-utils.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * Copyright (C) 2019 Red Hat, Inc.
  */
@@ -11,7 +11,6 @@
 
 #include "nm-errors.h"
 #include "nm-utils-private.h"
-#include "nm-json.h"
 #include "nm-glib-aux/nm-json-aux.h"
 #include "nm-core-internal.h"
 #include "nm-setting-team.h"
@@ -20,186 +19,329 @@
 /*****************************************************************************/
 
 typedef enum {
-	SET_FIELD_MODE_UNSET              = 0,
-	SET_FIELD_MODE_SET                = 1,
-
-	/* Sets the field as set, unless the field is at the default.
-	 * This is the case for API that is called from NMSettingTeam/NMSettingTeamPort.
-	 * This means, using libnm API to reset the value of a NMSetting to the default,
-	 * will mark the field as unset.
-	 * This is different from initializing the field when parsing JSON/GVariant. In
-	 * that case an explicitly set field (even set to the default value) will be remembered
-	 * to be set. */
-	SET_FIELD_MODE_SET_UNLESS_DEFAULT = 2,
+    SET_FIELD_MODE_UNSET = 0,
+    SET_FIELD_MODE_SET   = 1,
+
+    /* Sets the field as set, unless the field is at the default.
+     * This is the case for API that is called from NMSettingTeam/NMSettingTeamPort.
+     * This means, using libnm API to reset the value of a NMSetting to the default,
+     * will mark the field as unset.
+     * This is different from initializing the field when parsing JSON/GVariant. In
+     * that case an explicitly set field (even set to the default value) will be remembered
+     * to be set. */
+    SET_FIELD_MODE_SET_UNLESS_DEFAULT = 2,
 } SetFieldModeEnum;
 
 typedef enum {
-	RESET_JSON_NO  = FALSE,
-	RESET_JSON_YES = TRUE,
+    RESET_JSON_NO  = FALSE,
+    RESET_JSON_YES = TRUE,
 } ResetJsonEnum;
 
 /* we rely on "config" being the first. At various places we iterate over attribute types,
  * starting after "config".*/
-G_STATIC_ASSERT (_NM_TEAM_ATTRIBUTE_0     == 0);
-G_STATIC_ASSERT (NM_TEAM_ATTRIBUTE_CONFIG == 1);
+G_STATIC_ASSERT(_NM_TEAM_ATTRIBUTE_0 == 0);
+G_STATIC_ASSERT(NM_TEAM_ATTRIBUTE_CONFIG == 1);
 
 static const char *const _valid_names_runner[] = {
-	NM_SETTING_TEAM_RUNNER_BROADCAST,
-	NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
-	NM_SETTING_TEAM_RUNNER_RANDOM,
-	NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
-	NM_SETTING_TEAM_RUNNER_LOADBALANCE,
-	NM_SETTING_TEAM_RUNNER_LACP,
-	NULL,
+    NM_SETTING_TEAM_RUNNER_BROADCAST,
+    NM_SETTING_TEAM_RUNNER_ROUNDROBIN,
+    NM_SETTING_TEAM_RUNNER_RANDOM,
+    NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP,
+    NM_SETTING_TEAM_RUNNER_LOADBALANCE,
+    NM_SETTING_TEAM_RUNNER_LACP,
+    NULL,
 };
 
 static const char *const _valid_names_runner_hwaddr_policy[] = {
-	NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL,
-	NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE,
-	NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE,
-	NULL,
+    NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_SAME_ALL,
+    NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_BY_ACTIVE,
+    NM_SETTING_TEAM_RUNNER_HWADDR_POLICY_ONLY_ACTIVE,
+    NULL,
 };
 
 static const char *const _valid_names_runner_tx_balancer[] = {
-	"basic",
-	NULL,
+    "basic",
+    NULL,
 };
 
 static const char *const _valid_names_runner_tx_hash[] = {
-	"eth",
-	"vlan",
-	"ipv4",
-	"ipv6",
-	"ip",
-	"l3",
-	"l4",
-	"tcp",
-	"udp",
-	"sctp",
-	NULL,
+    "eth",
+    "vlan",
+    "ipv4",
+    "ipv6",
+    "ip",
+    "l3",
+    "l4",
+    "tcp",
+    "udp",
+    "sctp",
+    NULL,
 };
 
 static const char *const _valid_names_runner_agg_select_policy[] = {
-	"lacp_prio",
-	"lacp_prio_stable",
-	"bandwidth",
-	"count",
-	"port_config",
-	NULL,
+    "lacp_prio",
+    "lacp_prio_stable",
+    "bandwidth",
+    "count",
+    "port_config",
+    NULL,
 };
 
 typedef struct {
-	NMTeamAttribute team_attr;
-	const char *const*valid_runners;
+    NMTeamAttribute    team_attr;
+    const char *const *valid_runners;
 } RunnerCompatElem;
 
 static const RunnerCompatElem _runner_compat_lst[] = {
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,        NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,              NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
-	                                                                      NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,          NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
-	                                                                      NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LOADBALANCE,
-	                                                                      NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,               NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,            NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,             NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,            NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
-	{ NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,    NM_MAKE_STRV (NM_SETTING_TEAM_RUNNER_LACP), },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_ACTIVEBACKUP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LOADBALANCE, NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP),
+    },
+    {
+        NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
+        NM_MAKE_STRV(NM_SETTING_TEAM_RUNNER_LACP),
+    },
 };
 
 typedef struct {
-	const char *const*js_keys;
-	const char *property_name;
-	NMValueTypUnion default_val;
-	union {
-		struct {
-			gint32 min;
-			gint32 max;
-		} r_int32;
-		struct {
-			const char *const*valid_names;
-		} r_string;
-	} range;
-	NMTeamAttribute team_attr;
-	NMValueType value_type;
-	guint8 field_offset;
-	guint8 js_keys_len;
-	bool for_master:1;
-	bool for_port:1;
-	bool has_range:1;
+    const char *const *js_keys;
+    const char *       property_name;
+    NMValueTypUnion    default_val;
+    union {
+        struct {
+            gint32 min;
+            gint32 max;
+        } r_int32;
+        struct {
+            const char *const *valid_names;
+        } r_string;
+    } range;
+    NMTeamAttribute team_attr;
+    NMValueType     value_type;
+    guint8          field_offset;
+    guint8          js_keys_len;
+    bool            for_master : 1;
+    bool            for_port : 1;
+    bool            has_range : 1;
 } TeamAttrData;
 
-#define TEAM_ATTR_IDX(_is_port, _team_attr) \
-	((  (!(_is_port) || (_team_attr) < _NM_TEAM_ATTRIBUTE_START) \
-	  ? (int) (_team_attr) \
-	  : (((int) (_NM_TEAM_ATTRIBUTE_MASTER_NUM - _NM_TEAM_ATTRIBUTE_START)) + ((int) (_team_attr)))) - 1)
+#define TEAM_ATTR_IDX(_is_port, _team_attr)                                     \
+    (((!(_is_port) || (_team_attr) < _NM_TEAM_ATTRIBUTE_START)                  \
+          ? (int) (_team_attr)                                                  \
+          : (((int) (_NM_TEAM_ATTRIBUTE_MASTER_NUM - _NM_TEAM_ATTRIBUTE_START)) \
+             + ((int) (_team_attr))))                                           \
+     - 1)
 
-#define TEAM_ATTR_IDX_CONFIG (TEAM_ATTR_IDX (FALSE, NM_TEAM_ATTRIBUTE_CONFIG))
+#define TEAM_ATTR_IDX_CONFIG (TEAM_ATTR_IDX(FALSE, NM_TEAM_ATTRIBUTE_CONFIG))
 
 static const TeamAttrData team_attr_datas[] = {
 
-#define _JS_KEYS(...) \
-		.js_keys = NM_MAKE_STRV (__VA_ARGS__), \
-		.js_keys_len = NM_NARG (__VA_ARGS__)
-
-#define _VAL_BOOL(_default) \
-		.default_val.v_bool = (_default)
-
-#define _VAL_INT32(_default) \
-		.default_val.v_int32 = (_default)
-
-#define _VAL_INT32_RANGE(_default, _min,_max) \
-		_VAL_INT32 (_default), \
-		.has_range = TRUE, \
-		.range.r_int32 = { .min = _min, .max = _max, }
-
-#define _VAL_STRING() \
-		.default_val.v_string = NULL
-
-#define _VAL_STRING_RANGE(_valid_names) \
-		_VAL_STRING (), \
-		.has_range = TRUE, \
-		.range.r_string = { .valid_names = (_valid_names), }
-
-#define _VAL_UNSPEC() \
-		.default_val.v_string = (NULL)
-
-#define _INIT(_is_port, _team_attr, field, _value_type, _property_name, ...) \
-	[TEAM_ATTR_IDX (_is_port, _team_attr)] = { \
-		.for_master    = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || !(_is_port), \
-		.for_port      = (_team_attr) < _NM_TEAM_ATTRIBUTE_START ||  (_is_port), \
-		.team_attr     = (_team_attr), \
-		.field_offset  = G_STRUCT_OFFSET (NMTeamSetting, _data_priv.field), \
-		.value_type    = (_value_type), \
-		.property_name = ""_property_name"", \
-		__VA_ARGS__ \
-	}
-
-	_INIT (0, NM_TEAM_ATTRIBUTE_CONFIG,                             _js_str,                            NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_CONFIG,                                                                                                                                           ),
-
-	_INIT (0, NM_TEAM_ATTRIBUTE_LINK_WATCHERS,                      link_watchers,                      NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_LINK_WATCHERS,               _JS_KEYS ("link_watch"),                                  _VAL_UNSPEC (),                                            ),
-
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,          master.notify_peers_count,          NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,          _JS_KEYS ("notify_peers", "count"),                       _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,       master.notify_peers_interval,       NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,       _JS_KEYS ("notify_peers", "interval"),                    _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,          master.mcast_rejoin_count,          NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_MCAST_REJOIN_COUNT,          _JS_KEYS ("mcast_rejoin", "count"),                       _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,       master.mcast_rejoin_interval,       NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,       _JS_KEYS ("mcast_rejoin", "interval"),                    _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER,                      master.runner,                      NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER,                      _JS_KEYS ("runner", "name"),                              _VAL_STRING_RANGE (_valid_names_runner),                   ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,        master.runner_hwaddr_policy,        NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,        _JS_KEYS ("runner", "hwaddr_policy"),                     _VAL_STRING_RANGE (_valid_names_runner_hwaddr_policy),     ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,              master.runner_tx_hash,              NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_RUNNER_TX_HASH,              _JS_KEYS ("runner", "tx_hash"),                           _VAL_UNSPEC (),                                            ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,          master.runner_tx_balancer,          NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_TX_BALANCER,          _JS_KEYS ("runner", "tx_balancer", "name"),               _VAL_STRING_RANGE (_valid_names_runner_tx_balancer),       ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL, master.runner_tx_balancer_interval, NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL, _JS_KEYS ("runner", "tx_balancer", "balancing_interval"), _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,               master.runner_active,               NM_VALUE_TYPE_BOOL,   NM_SETTING_TEAM_RUNNER_ACTIVE,               _JS_KEYS ("runner", "active"),                            _VAL_BOOL (TRUE),                                          ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,            master.runner_fast_rate,            NM_VALUE_TYPE_BOOL,   NM_SETTING_TEAM_RUNNER_FAST_RATE,            _JS_KEYS ("runner", "fast_rate"),                         _VAL_BOOL (FALSE),                                         ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,             master.runner_sys_prio,             NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_RUNNER_SYS_PRIO,             _JS_KEYS ("runner", "sys_prio"),                          _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1),                   ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,            master.runner_min_ports,            NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_RUNNER_MIN_PORTS,            _JS_KEYS ("runner", "min_ports"),                         _VAL_INT32_RANGE (-1, 1, UCHAR_MAX + 1),                   ),
-	_INIT (0, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,    master.runner_agg_select_policy,    NM_VALUE_TYPE_STRING, NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,    _JS_KEYS ("runner", "agg_select_policy"),                 _VAL_STRING_RANGE (_valid_names_runner_agg_select_policy), ),
-
-	_INIT (1, NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID,                      port.queue_id,                      NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_PORT_QUEUE_ID,               _JS_KEYS ("queue_id"),                                    _VAL_INT32_RANGE (-1, 0, G_MAXINT32),                      ),
-	_INIT (1, NM_TEAM_ATTRIBUTE_PORT_PRIO,                          port.prio,                          NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_PORT_PRIO,                   _JS_KEYS ("prio"),                                        _VAL_INT32 (0),                                            ),
-	_INIT (1, NM_TEAM_ATTRIBUTE_PORT_STICKY,                        port.sticky,                        NM_VALUE_TYPE_BOOL,   NM_SETTING_TEAM_PORT_STICKY,                 _JS_KEYS ("sticky"),                                      _VAL_BOOL (FALSE),                                         ),
-	_INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,                     port.lacp_prio,                     NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_PORT_LACP_PRIO,              _JS_KEYS ("lacp_prio"),                                   _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1),                   ),
-	_INIT (1, NM_TEAM_ATTRIBUTE_PORT_LACP_KEY,                      port.lacp_key,                      NM_VALUE_TYPE_INT32,  NM_SETTING_TEAM_PORT_LACP_KEY,               _JS_KEYS ("lacp_key"),                                    _VAL_INT32_RANGE (-1, 0, USHRT_MAX + 1),                   ),
+#define _JS_KEYS(...) .js_keys = NM_MAKE_STRV(__VA_ARGS__), .js_keys_len = NM_NARG(__VA_ARGS__)
+
+#define _VAL_BOOL(_default) .default_val.v_bool = (_default)
+
+#define _VAL_INT32(_default) .default_val.v_int32 = (_default)
+
+#define _VAL_INT32_RANGE(_default, _min, _max) \
+    _VAL_INT32(_default), .has_range = TRUE,   \
+                          .range.r_int32 = {   \
+                              .min = _min,     \
+                              .max = _max,     \
+    }
+
+#define _VAL_STRING() .default_val.v_string = NULL
+
+#define _VAL_STRING_RANGE(_valid_names)               \
+    _VAL_STRING(), .has_range = TRUE,                 \
+                   .range.r_string = {                \
+                       .valid_names = (_valid_names), \
+    }
+
+#define _VAL_UNSPEC() .default_val.v_string = (NULL)
+
+#define _INIT(_is_port, _team_attr, field, _value_type, _property_name, ...)     \
+    [TEAM_ATTR_IDX(_is_port, _team_attr)] = {                                    \
+        .for_master    = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || !(_is_port), \
+        .for_port      = (_team_attr) < _NM_TEAM_ATTRIBUTE_START || (_is_port),  \
+        .team_attr     = (_team_attr),                                           \
+        .field_offset  = G_STRUCT_OFFSET(NMTeamSetting, _data_priv.field),       \
+        .value_type    = (_value_type),                                          \
+        .property_name = ""_property_name                                        \
+                         "",                                                     \
+        __VA_ARGS__}
+
+    _INIT(0, NM_TEAM_ATTRIBUTE_CONFIG, _js_str, NM_VALUE_TYPE_UNSPEC, NM_SETTING_TEAM_CONFIG, ),
+
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
+          link_watchers,
+          NM_VALUE_TYPE_UNSPEC,
+          NM_SETTING_TEAM_LINK_WATCHERS,
+          _JS_KEYS("link_watch"),
+          _VAL_UNSPEC(), ),
+
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,
+          master.notify_peers_count,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_NOTIFY_PEERS_COUNT,
+          _JS_KEYS("notify_peers", "count"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,
+          master.notify_peers_interval,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_NOTIFY_PEERS_INTERVAL,
+          _JS_KEYS("notify_peers", "interval"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,
+          master.mcast_rejoin_count,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_MCAST_REJOIN_COUNT,
+          _JS_KEYS("mcast_rejoin", "count"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,
+          master.mcast_rejoin_interval,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_MCAST_REJOIN_INTERVAL,
+          _JS_KEYS("mcast_rejoin", "interval"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER,
+          master.runner,
+          NM_VALUE_TYPE_STRING,
+          NM_SETTING_TEAM_RUNNER,
+          _JS_KEYS("runner", "name"),
+          _VAL_STRING_RANGE(_valid_names_runner), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
+          master.runner_hwaddr_policy,
+          NM_VALUE_TYPE_STRING,
+          NM_SETTING_TEAM_RUNNER_HWADDR_POLICY,
+          _JS_KEYS("runner", "hwaddr_policy"),
+          _VAL_STRING_RANGE(_valid_names_runner_hwaddr_policy), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+          master.runner_tx_hash,
+          NM_VALUE_TYPE_UNSPEC,
+          NM_SETTING_TEAM_RUNNER_TX_HASH,
+          _JS_KEYS("runner", "tx_hash"),
+          _VAL_UNSPEC(), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
+          master.runner_tx_balancer,
+          NM_VALUE_TYPE_STRING,
+          NM_SETTING_TEAM_RUNNER_TX_BALANCER,
+          _JS_KEYS("runner", "tx_balancer", "name"),
+          _VAL_STRING_RANGE(_valid_names_runner_tx_balancer), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
+          master.runner_tx_balancer_interval,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_RUNNER_TX_BALANCER_INTERVAL,
+          _JS_KEYS("runner", "tx_balancer", "balancing_interval"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
+          master.runner_active,
+          NM_VALUE_TYPE_BOOL,
+          NM_SETTING_TEAM_RUNNER_ACTIVE,
+          _JS_KEYS("runner", "active"),
+          _VAL_BOOL(TRUE), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
+          master.runner_fast_rate,
+          NM_VALUE_TYPE_BOOL,
+          NM_SETTING_TEAM_RUNNER_FAST_RATE,
+          _JS_KEYS("runner", "fast_rate"),
+          _VAL_BOOL(FALSE), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
+          master.runner_sys_prio,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_RUNNER_SYS_PRIO,
+          _JS_KEYS("runner", "sys_prio"),
+          _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
+          master.runner_min_ports,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_RUNNER_MIN_PORTS,
+          _JS_KEYS("runner", "min_ports"),
+          _VAL_INT32_RANGE(-1, 1, UCHAR_MAX + 1), ),
+    _INIT(0,
+          NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
+          master.runner_agg_select_policy,
+          NM_VALUE_TYPE_STRING,
+          NM_SETTING_TEAM_RUNNER_AGG_SELECT_POLICY,
+          _JS_KEYS("runner", "agg_select_policy"),
+          _VAL_STRING_RANGE(_valid_names_runner_agg_select_policy), ),
+
+    _INIT(1,
+          NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID,
+          port.queue_id,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_PORT_QUEUE_ID,
+          _JS_KEYS("queue_id"),
+          _VAL_INT32_RANGE(-1, 0, G_MAXINT32), ),
+    _INIT(1,
+          NM_TEAM_ATTRIBUTE_PORT_PRIO,
+          port.prio,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_PORT_PRIO,
+          _JS_KEYS("prio"),
+          _VAL_INT32(0), ),
+    _INIT(1,
+          NM_TEAM_ATTRIBUTE_PORT_STICKY,
+          port.sticky,
+          NM_VALUE_TYPE_BOOL,
+          NM_SETTING_TEAM_PORT_STICKY,
+          _JS_KEYS("sticky"),
+          _VAL_BOOL(FALSE), ),
+    _INIT(1,
+          NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
+          port.lacp_prio,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_PORT_LACP_PRIO,
+          _JS_KEYS("lacp_prio"),
+          _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ),
+    _INIT(1,
+          NM_TEAM_ATTRIBUTE_PORT_LACP_KEY,
+          port.lacp_key,
+          NM_VALUE_TYPE_INT32,
+          NM_SETTING_TEAM_PORT_LACP_KEY,
+          _JS_KEYS("lacp_key"),
+          _VAL_INT32_RANGE(-1, 0, USHRT_MAX + 1), ),
 
 #undef _INIT
 };
@@ -207,1228 +349,1311 @@ static const TeamAttrData team_attr_datas[] = {
 /*****************************************************************************/
 
 typedef enum {
-	LINK_WATCHER_ATTRIBUTE_NAME,
-	LINK_WATCHER_ATTRIBUTE_DELAY_UP,
-	LINK_WATCHER_ATTRIBUTE_DELAY_DOWN,
-	LINK_WATCHER_ATTRIBUTE_INTERVAL,
-	LINK_WATCHER_ATTRIBUTE_INIT_WAIT,
-	LINK_WATCHER_ATTRIBUTE_MISSED_MAX,
-	LINK_WATCHER_ATTRIBUTE_SOURCE_HOST,
-	LINK_WATCHER_ATTRIBUTE_TARGET_HOST,
-	LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,
-	LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE,
-	LINK_WATCHER_ATTRIBUTE_VLANID,
-	LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS,
+    LINK_WATCHER_ATTRIBUTE_NAME,
+    LINK_WATCHER_ATTRIBUTE_DELAY_UP,
+    LINK_WATCHER_ATTRIBUTE_DELAY_DOWN,
+    LINK_WATCHER_ATTRIBUTE_INTERVAL,
+    LINK_WATCHER_ATTRIBUTE_INIT_WAIT,
+    LINK_WATCHER_ATTRIBUTE_MISSED_MAX,
+    LINK_WATCHER_ATTRIBUTE_SOURCE_HOST,
+    LINK_WATCHER_ATTRIBUTE_TARGET_HOST,
+    LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,
+    LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE,
+    LINK_WATCHER_ATTRIBUTE_VLANID,
+    LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS,
 } LinkWatcherAttribute;
 
-#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL    LINK_WATCHER_ATTRIBUTE_NAME, \
-                                                     LINK_WATCHER_ATTRIBUTE_DELAY_UP, \
-                                                     LINK_WATCHER_ATTRIBUTE_DELAY_DOWN
-#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING  LINK_WATCHER_ATTRIBUTE_NAME, \
-                                                     LINK_WATCHER_ATTRIBUTE_INTERVAL, \
-                                                     LINK_WATCHER_ATTRIBUTE_INIT_WAIT, \
-                                                     LINK_WATCHER_ATTRIBUTE_MISSED_MAX, \
-                                                     LINK_WATCHER_ATTRIBUTE_TARGET_HOST
-#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING   LINK_WATCHER_ATTRIBUTE_NAME, \
-                                                     LINK_WATCHER_ATTRIBUTE_INTERVAL, \
-                                                     LINK_WATCHER_ATTRIBUTE_INIT_WAIT, \
-                                                     LINK_WATCHER_ATTRIBUTE_MISSED_MAX, \
-                                                     LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, \
-                                                     LINK_WATCHER_ATTRIBUTE_TARGET_HOST, \
-                                                     LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, \
-                                                     LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, \
-                                                     LINK_WATCHER_ATTRIBUTE_VLANID, \
-                                                     LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS
+#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL \
+    LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_DELAY_UP, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN
+#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING                          \
+    LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_INTERVAL,            \
+        LINK_WATCHER_ATTRIBUTE_INIT_WAIT, LINK_WATCHER_ATTRIBUTE_MISSED_MAX, \
+        LINK_WATCHER_ATTRIBUTE_TARGET_HOST
+#define _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING                                        \
+    LINK_WATCHER_ATTRIBUTE_NAME, LINK_WATCHER_ATTRIBUTE_INTERVAL,                         \
+        LINK_WATCHER_ATTRIBUTE_INIT_WAIT, LINK_WATCHER_ATTRIBUTE_MISSED_MAX,              \
+        LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, LINK_WATCHER_ATTRIBUTE_TARGET_HOST,           \
+        LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, \
+        LINK_WATCHER_ATTRIBUTE_VLANID, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS
 
 typedef struct {
-	const char *js_key;
-	const char *dbus_name;
-	NMValueTypUnion default_val;
-	LinkWatcherAttribute link_watcher_attr;
-	NMValueType value_type;
+    const char *         js_key;
+    const char *         dbus_name;
+    NMValueTypUnion      default_val;
+    LinkWatcherAttribute link_watcher_attr;
+    NMValueType          value_type;
 } LinkWatcherAttrData;
 
 static const LinkWatcherAttrData link_watcher_attr_datas[] = {
 #define _INIT(_link_watcher_attr, _js_key, _dbus_name, _value_type, ...) \
-	[_link_watcher_attr] = { \
-		.link_watcher_attr = (_link_watcher_attr), \
-		.value_type = (_value_type), \
-		.js_key = (""_js_key""), \
-		.dbus_name = (""_dbus_name""), \
-		__VA_ARGS__ \
-	}
-	_INIT (LINK_WATCHER_ATTRIBUTE_NAME,              "name",              "name",              NM_VALUE_TYPE_STRING,                          ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_DELAY_UP,          "delay_up",          "delay-up",          NM_VALUE_TYPE_INT,                             ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_DELAY_DOWN,        "delay_down",        "delay-down",        NM_VALUE_TYPE_INT,                             ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_INTERVAL,          "interval",          "interval",          NM_VALUE_TYPE_INT,                             ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_INIT_WAIT,         "init_wait",         "init-wait",         NM_VALUE_TYPE_INT,                             ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_MISSED_MAX,        "missed_max",        "missed-max",        NM_VALUE_TYPE_INT,    .default_val.v_int =  3, ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_SOURCE_HOST,       "source_host",       "source-host",       NM_VALUE_TYPE_STRING,                          ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_TARGET_HOST,       "target_host",       "target-host",       NM_VALUE_TYPE_STRING,                          ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,   "validate_active",   "validate-active",   NM_VALUE_TYPE_BOOL,                            ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, "validate_inactive", "validate-inactive", NM_VALUE_TYPE_BOOL,                            ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_VLANID,            "vlanid",            "vlanid",            NM_VALUE_TYPE_INT,    .default_val.v_int = -1, ),
-	_INIT (LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS,       "send_always",       "send-always",       NM_VALUE_TYPE_BOOL,                            ),
+    [_link_watcher_attr] = {.link_watcher_attr = (_link_watcher_attr),   \
+                            .value_type        = (_value_type),          \
+                            .js_key            = (""_js_key              \
+                                       ""),                   \
+                            .dbus_name         = (""_dbus_name           \
+                                          ""),                   \
+                            __VA_ARGS__}
+    _INIT(LINK_WATCHER_ATTRIBUTE_NAME, "name", "name", NM_VALUE_TYPE_STRING, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_DELAY_UP, "delay_up", "delay-up", NM_VALUE_TYPE_INT, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_DELAY_DOWN, "delay_down", "delay-down", NM_VALUE_TYPE_INT, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_INTERVAL, "interval", "interval", NM_VALUE_TYPE_INT, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_INIT_WAIT, "init_wait", "init-wait", NM_VALUE_TYPE_INT, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_MISSED_MAX,
+          "missed_max",
+          "missed-max",
+          NM_VALUE_TYPE_INT,
+          .default_val.v_int = 3, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_SOURCE_HOST, "source_host", "source-host", NM_VALUE_TYPE_STRING, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_TARGET_HOST, "target_host", "target-host", NM_VALUE_TYPE_STRING, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,
+          "validate_active",
+          "validate-active",
+          NM_VALUE_TYPE_BOOL, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE,
+          "validate_inactive",
+          "validate-inactive",
+          NM_VALUE_TYPE_BOOL, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_VLANID,
+          "vlanid",
+          "vlanid",
+          NM_VALUE_TYPE_INT,
+          .default_val.v_int = -1, ),
+    _INIT(LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS, "send_always", "send-always", NM_VALUE_TYPE_BOOL, ),
 #undef _INIT
 };
 
 /*****************************************************************************/
 
-static const TeamAttrData *_team_attr_data_get (gboolean is_port,
-                                                NMTeamAttribute team_attr);
-static gpointer _team_setting_get_field (const NMTeamSetting *self,
-                                         const TeamAttrData *attr_data);
-static void _link_watcher_to_json (const NMTeamLinkWatcher *link_watcher,
-                                   GString *gstr);
+static const TeamAttrData *_team_attr_data_get(gboolean is_port, NMTeamAttribute team_attr);
+static gpointer _team_setting_get_field(const NMTeamSetting *self, const TeamAttrData *attr_data);
+static void     _link_watcher_to_json(const NMTeamLinkWatcher *link_watcher, GString *gstr);
 
 /*****************************************************************************/
 
 static void
-_team_attr_data_ASSERT (const TeamAttrData *attr_data)
+_team_attr_data_ASSERT(const TeamAttrData *attr_data)
 {
 #if NM_MORE_ASSERTS > 5
-	nm_assert (attr_data);
-	if (attr_data->for_port)
-		nm_assert (attr_data == _team_attr_data_get (TRUE, attr_data->team_attr));
-	if (attr_data->for_master)
-		nm_assert (attr_data == _team_attr_data_get (FALSE, attr_data->team_attr));
-	nm_assert ((attr_data - team_attr_datas) == TEAM_ATTR_IDX (attr_data->for_port, attr_data->team_attr));
-	nm_assert (attr_data->value_type > 0);
-	nm_assert (attr_data->field_offset < sizeof (NMTeamSetting));
-	nm_assert (attr_data->js_keys_len == NM_PTRARRAY_LEN (attr_data->js_keys));
-	nm_assert (attr_data->property_name);
-	{
-		static int checked = 0;
-
-		if (checked == 0) {
-			checked = 1;
-
-			for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++)
-				_team_attr_data_ASSERT (attr_data);
-		}
-	}
+    nm_assert(attr_data);
+    if (attr_data->for_port)
+        nm_assert(attr_data == _team_attr_data_get(TRUE, attr_data->team_attr));
+    if (attr_data->for_master)
+        nm_assert(attr_data == _team_attr_data_get(FALSE, attr_data->team_attr));
+    nm_assert((attr_data - team_attr_datas)
+              == TEAM_ATTR_IDX(attr_data->for_port, attr_data->team_attr));
+    nm_assert(attr_data->value_type > 0);
+    nm_assert(attr_data->field_offset < sizeof(NMTeamSetting));
+    nm_assert(attr_data->js_keys_len == NM_PTRARRAY_LEN(attr_data->js_keys));
+    nm_assert(attr_data->property_name);
+    {
+        static int checked = 0;
+
+        if (checked == 0) {
+            checked = 1;
+
+            for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+                 attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+                 attr_data++)
+                _team_attr_data_ASSERT(attr_data);
+        }
+    }
 #endif
 }
 
 static gboolean
-_team_attr_data_is_relevant (const TeamAttrData *attr_data,
-                             gboolean is_port)
+_team_attr_data_is_relevant(const TeamAttrData *attr_data, gboolean is_port)
 {
-	return   is_port
-	       ? attr_data->for_port
-	       : attr_data->for_master;
+    return is_port ? attr_data->for_port : attr_data->for_master;
 }
 
 static const TeamAttrData *
-_team_attr_data_get (gboolean is_port,
-                     NMTeamAttribute team_attr)
+_team_attr_data_get(gboolean is_port, NMTeamAttribute team_attr)
 {
-	const int idx = TEAM_ATTR_IDX (is_port, team_attr);
+    const int idx = TEAM_ATTR_IDX(is_port, team_attr);
 
-	nm_assert (   idx >= 0
-	           && idx < G_N_ELEMENTS (team_attr_datas));
-	nm_assert (team_attr_datas[idx].team_attr == team_attr);
-	nm_assert (_team_attr_data_is_relevant (&team_attr_datas[idx], is_port));
+    nm_assert(idx >= 0 && idx < G_N_ELEMENTS(team_attr_datas));
+    nm_assert(team_attr_datas[idx].team_attr == team_attr);
+    nm_assert(_team_attr_data_is_relevant(&team_attr_datas[idx], is_port));
 
-	return &team_attr_datas[idx];
+    return &team_attr_datas[idx];
 }
 
 static const TeamAttrData *
-_team_attr_data_find_for_property_name (gboolean is_port,
-                                        const char *property_name)
+_team_attr_data_find_for_property_name(gboolean is_port, const char *property_name)
 {
-	const TeamAttrData *attr_data;
-
-	for (attr_data = team_attr_datas; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		if (   _team_attr_data_is_relevant (attr_data, is_port)
-		    && nm_streq (property_name, attr_data->property_name))
-			return attr_data;
-	}
-	return NULL;
+    const TeamAttrData *attr_data;
+
+    for (attr_data = team_attr_datas; attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        if (_team_attr_data_is_relevant(attr_data, is_port)
+            && nm_streq(property_name, attr_data->property_name))
+            return attr_data;
+    }
+    return NULL;
 }
 
 static int
-_team_attr_data_cmp (const TeamAttrData *attr_data,
-                     gboolean is_port,
-                     gconstpointer val_a,
-                     gconstpointer val_b)
+_team_attr_data_cmp(const TeamAttrData *attr_data,
+                    gboolean            is_port,
+                    gconstpointer       val_a,
+                    gconstpointer       val_b)
 {
-	const GPtrArray *v_ptrarray_a;
-	const GPtrArray *v_ptrarray_b;
-	guint len;
-
-	_team_attr_data_ASSERT (attr_data);
-	nm_assert (val_a);
-	nm_assert (val_b);
-
-	if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
-		NM_CMP_RETURN (nm_value_type_cmp (attr_data->value_type, val_a, val_b));
-	else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
-		v_ptrarray_a = *((const GPtrArray *const*) val_a);
-		v_ptrarray_b = *((const GPtrArray *const*) val_b);
-		len = v_ptrarray_a ? v_ptrarray_a->len : 0u;
-		NM_CMP_DIRECT (len, (v_ptrarray_b ? v_ptrarray_b->len : 0u));
-		if (len > 0) {
-			NM_CMP_RETURN (nm_team_link_watchers_cmp ((const NMTeamLinkWatcher *const*) v_ptrarray_a->pdata,
-		                                              (const NMTeamLinkWatcher *const*) v_ptrarray_b->pdata,
-		                                              len,
-		                                              FALSE));
-		}
-	} else if (   !is_port
-	           && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-		v_ptrarray_a = *((const GPtrArray *const*) val_a);
-		v_ptrarray_b = *((const GPtrArray *const*) val_b);
-		NM_CMP_RETURN (_nm_utils_strv_cmp_n (v_ptrarray_a ? (const char *const*) v_ptrarray_a->pdata : NULL,
-		                                     v_ptrarray_a ? v_ptrarray_a->len : 0u,
-		                                     v_ptrarray_b ? (const char *const*) v_ptrarray_b->pdata : NULL,
-		                                     v_ptrarray_b ? v_ptrarray_b->len : 0u));
-	} else
-		nm_assert_not_reached ();
-	return 0;
+    const GPtrArray *v_ptrarray_a;
+    const GPtrArray *v_ptrarray_b;
+    guint            len;
+
+    _team_attr_data_ASSERT(attr_data);
+    nm_assert(val_a);
+    nm_assert(val_b);
+
+    if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
+        NM_CMP_RETURN(nm_value_type_cmp(attr_data->value_type, val_a, val_b));
+    else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
+        v_ptrarray_a = *((const GPtrArray *const *) val_a);
+        v_ptrarray_b = *((const GPtrArray *const *) val_b);
+        len          = v_ptrarray_a ? v_ptrarray_a->len : 0u;
+        NM_CMP_DIRECT(len, (v_ptrarray_b ? v_ptrarray_b->len : 0u));
+        if (len > 0) {
+            NM_CMP_RETURN(
+                nm_team_link_watchers_cmp((const NMTeamLinkWatcher *const *) v_ptrarray_a->pdata,
+                                          (const NMTeamLinkWatcher *const *) v_ptrarray_b->pdata,
+                                          len,
+                                          FALSE));
+        }
+    } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+        v_ptrarray_a = *((const GPtrArray *const *) val_a);
+        v_ptrarray_b = *((const GPtrArray *const *) val_b);
+        NM_CMP_RETURN(
+            _nm_utils_strv_cmp_n(v_ptrarray_a ? (const char *const *) v_ptrarray_a->pdata : NULL,
+                                 v_ptrarray_a ? v_ptrarray_a->len : 0u,
+                                 v_ptrarray_b ? (const char *const *) v_ptrarray_b->pdata : NULL,
+                                 v_ptrarray_b ? v_ptrarray_b->len : 0u));
+    } else
+        nm_assert_not_reached();
+    return 0;
 }
 
 static gboolean
-_team_attr_data_equal (const TeamAttrData *attr_data,
-                       gboolean is_port,
-                       gconstpointer val_a,
-                       gconstpointer val_b)
+_team_attr_data_equal(const TeamAttrData *attr_data,
+                      gboolean            is_port,
+                      gconstpointer       val_a,
+                      gconstpointer       val_b)
 {
-	return _team_attr_data_cmp (attr_data, is_port, val_a, val_b) == 0;
+    return _team_attr_data_cmp(attr_data, is_port, val_a, val_b) == 0;
 }
 
 static void
-_team_attr_data_copy (const TeamAttrData *attr_data,
-                      gboolean is_port,
-                      gpointer dst,
-                      gconstpointer src)
+_team_attr_data_copy(const TeamAttrData *attr_data,
+                     gboolean            is_port,
+                     gpointer            dst,
+                     gconstpointer       src)
 {
-	GPtrArray *v_ptrarray_dst;
-	const GPtrArray *v_ptrarray_src;
-	GPtrArray *dst_array;
-	guint i, len;
-
-	if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
-		nm_value_type_copy (attr_data->value_type, dst, src);
-	else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
-		v_ptrarray_src = *((const GPtrArray *const *) src);
-		v_ptrarray_dst = *((GPtrArray **) dst);
-		len = (v_ptrarray_src ? v_ptrarray_src->len : 0u);
-
-		if (len == 0) {
-			if (v_ptrarray_dst)
-				g_ptr_array_set_size (v_ptrarray_dst, 0);
-		} else {
-			dst_array = g_ptr_array_new_full (len, (GDestroyNotify) nm_team_link_watcher_unref);
-			for (i = 0; i < len; i++) {
-				if (v_ptrarray_src->pdata[i]) {
-					nm_team_link_watcher_ref (v_ptrarray_src->pdata[i]);
-					g_ptr_array_add (dst_array,v_ptrarray_src->pdata[i]);
-				}
-			}
-			if (v_ptrarray_dst)
-				g_ptr_array_unref (v_ptrarray_dst);
-			*((GPtrArray **) dst) = dst_array;
-		}
-	} else if (   !is_port
-	           && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-		v_ptrarray_src = *((const GPtrArray *const *) src);
-		v_ptrarray_dst = *((GPtrArray **) dst);
-		len = (v_ptrarray_src ? v_ptrarray_src->len : 0u);
-
-		if (   v_ptrarray_src
-		    && v_ptrarray_src->len > 0) {
-			dst_array = g_ptr_array_new_full (v_ptrarray_src->len, g_free);
-			for (i = 0; i < v_ptrarray_src->len; i++)
-				g_ptr_array_add (dst_array, g_strdup (v_ptrarray_src->pdata[i]));
-		} else
-			dst_array = NULL;
-		if (v_ptrarray_dst)
-			g_ptr_array_unref (v_ptrarray_dst);
-		*((GPtrArray **) dst) = dst_array;
-	} else
-		nm_assert_not_reached ();
+    GPtrArray *      v_ptrarray_dst;
+    const GPtrArray *v_ptrarray_src;
+    GPtrArray *      dst_array;
+    guint            i, len;
+
+    if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
+        nm_value_type_copy(attr_data->value_type, dst, src);
+    else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
+        v_ptrarray_src = *((const GPtrArray *const *) src);
+        v_ptrarray_dst = *((GPtrArray **) dst);
+        len            = (v_ptrarray_src ? v_ptrarray_src->len : 0u);
+
+        if (len == 0) {
+            if (v_ptrarray_dst)
+                g_ptr_array_set_size(v_ptrarray_dst, 0);
+        } else {
+            dst_array = g_ptr_array_new_full(len, (GDestroyNotify) nm_team_link_watcher_unref);
+            for (i = 0; i < len; i++) {
+                if (v_ptrarray_src->pdata[i]) {
+                    nm_team_link_watcher_ref(v_ptrarray_src->pdata[i]);
+                    g_ptr_array_add(dst_array, v_ptrarray_src->pdata[i]);
+                }
+            }
+            if (v_ptrarray_dst)
+                g_ptr_array_unref(v_ptrarray_dst);
+            *((GPtrArray **) dst) = dst_array;
+        }
+    } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+        v_ptrarray_src = *((const GPtrArray *const *) src);
+        v_ptrarray_dst = *((GPtrArray **) dst);
+        len            = (v_ptrarray_src ? v_ptrarray_src->len : 0u);
+
+        if (v_ptrarray_src && v_ptrarray_src->len > 0) {
+            dst_array = g_ptr_array_new_full(v_ptrarray_src->len, g_free);
+            for (i = 0; i < v_ptrarray_src->len; i++)
+                g_ptr_array_add(dst_array, g_strdup(v_ptrarray_src->pdata[i]));
+        } else
+            dst_array = NULL;
+        if (v_ptrarray_dst)
+            g_ptr_array_unref(v_ptrarray_dst);
+        *((GPtrArray **) dst) = dst_array;
+    } else
+        nm_assert_not_reached();
 }
 
 static void
-_team_attr_data_to_json (const TeamAttrData *attr_data,
-                         gboolean is_port,
-                         GString *gstr,
-                         gconstpointer p_field)
+_team_attr_data_to_json(const TeamAttrData *attr_data,
+                        gboolean            is_port,
+                        GString *           gstr,
+                        gconstpointer       p_field)
 {
-	guint i;
-
-	_team_attr_data_ASSERT (attr_data);
-	nm_assert (p_field);
-
-	nm_json_aux_gstr_append_obj_name (gstr,
-	                                  attr_data->js_keys[attr_data->js_keys_len - 1],
-	                                  '\0');
-
-	if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
-		nm_value_type_to_json (attr_data->value_type, gstr, p_field);
-		return;
-	}
-
-	if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
-		const GPtrArray *v_ptrarray = *((const GPtrArray *const*) p_field);
-
-		if (!v_ptrarray)
-			g_string_append (gstr, "null");
-		else if (v_ptrarray->len == 0)
-			g_string_append (gstr, "[ ]");
-		else if (v_ptrarray->len == 1)
-			_link_watcher_to_json (v_ptrarray->pdata[0], gstr);
-		else {
-			g_string_append (gstr, "[ ");
-			for (i = 0; i < v_ptrarray->len; i++) {
-				if (i > 0)
-					nm_json_aux_gstr_append_delimiter (gstr);
-				_link_watcher_to_json (v_ptrarray->pdata[i], gstr);
-			}
-			g_string_append (gstr, " ]");
-		}
-		return;
-	}
-
-	if (   !is_port
-	    && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-		const GPtrArray *v_ptrarray = *((const GPtrArray *const*) p_field);
-
-		if (!v_ptrarray)
-			g_string_append (gstr, "null");
-		else {
-			g_string_append (gstr, "[ ");
-			for (i = 0; i < v_ptrarray->len; i++) {
-				if (i > 0)
-					nm_json_aux_gstr_append_delimiter (gstr);
-				nm_json_aux_gstr_append_string (gstr, v_ptrarray->pdata[i]);
-			}
-			g_string_append (gstr, i > 0 ? " ]" : "]");
-		}
-		return;
-	}
-
-	nm_assert_not_reached ();
+    guint i;
+
+    _team_attr_data_ASSERT(attr_data);
+    nm_assert(p_field);
+
+    nm_json_gstr_append_obj_name(gstr, attr_data->js_keys[attr_data->js_keys_len - 1], '\0');
+
+    if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
+        nm_value_type_to_json(attr_data->value_type, gstr, p_field);
+        return;
+    }
+
+    if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
+        const GPtrArray *v_ptrarray = *((const GPtrArray *const *) p_field);
+
+        if (!v_ptrarray)
+            g_string_append(gstr, "null");
+        else if (v_ptrarray->len == 0)
+            g_string_append(gstr, "[ ]");
+        else if (v_ptrarray->len == 1)
+            _link_watcher_to_json(v_ptrarray->pdata[0], gstr);
+        else {
+            g_string_append(gstr, "[ ");
+            for (i = 0; i < v_ptrarray->len; i++) {
+                if (i > 0)
+                    nm_json_gstr_append_delimiter(gstr);
+                _link_watcher_to_json(v_ptrarray->pdata[i], gstr);
+            }
+            g_string_append(gstr, " ]");
+        }
+        return;
+    }
+
+    if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+        const GPtrArray *v_ptrarray = *((const GPtrArray *const *) p_field);
+
+        if (!v_ptrarray)
+            g_string_append(gstr, "null");
+        else {
+            g_string_append(gstr, "[ ");
+            for (i = 0; i < v_ptrarray->len; i++) {
+                if (i > 0)
+                    nm_json_gstr_append_delimiter(gstr);
+                nm_json_gstr_append_string(gstr, v_ptrarray->pdata[i]);
+            }
+            g_string_append(gstr, i > 0 ? " ]" : "]");
+        }
+        return;
+    }
+
+    nm_assert_not_reached();
 }
 
 /*****************************************************************************/
 
 static void
-_team_setting_ASSERT (const NMTeamSetting *self)
+_team_setting_ASSERT(const NMTeamSetting *self)
 {
-	nm_assert (self);
-	nm_assert (!self->d._js_str_need_synthetize || !self->d._js_str);
+    nm_assert(self);
+    nm_assert(!self->d._js_str_need_synthetize || !self->d._js_str);
 #if NM_MORE_ASSERTS > 2
-	if (!self->d.strict_validated) {
-		nm_assert (!self->d._js_str_need_synthetize);
-		nm_assert (self->d._js_str);
-	}
-	nm_assert (self->d.link_watchers);
-	nm_assert (   self->d.is_port
-	           || !self->d.master.runner_tx_hash
-	           || self->d.master.runner_tx_hash->len > 0);
+    if (!self->d.strict_validated) {
+        nm_assert(!self->d._js_str_need_synthetize);
+        nm_assert(self->d._js_str);
+    }
+    nm_assert(self->d.link_watchers);
+    nm_assert(self->d.is_port || !self->d.master.runner_tx_hash
+              || self->d.master.runner_tx_hash->len > 0);
 #endif
 }
 
 static gboolean
-_team_setting_has_field (const NMTeamSetting *self,
-                         const TeamAttrData *attr_data)
+_team_setting_has_field(const NMTeamSetting *self, const TeamAttrData *attr_data)
 {
-	_team_setting_ASSERT (self);
-	return NM_FLAGS_ALL (self->d.has_fields_mask, nm_team_attribute_to_flags (attr_data->team_attr));
+    _team_setting_ASSERT(self);
+    return NM_FLAGS_ALL(self->d.has_fields_mask, nm_team_attribute_to_flags(attr_data->team_attr));
 }
 
 static gboolean
-_team_setting_has_fields_any_v (const NMTeamSetting *self,
-                                const NMTeamAttribute *team_attrs,
-                                gsize n_team_attrs)
+_team_setting_has_fields_any_v(const NMTeamSetting *  self,
+                               const NMTeamAttribute *team_attrs,
+                               gsize                  n_team_attrs)
 {
-	gsize i;
+    gsize i;
 
-	for (i = 0; i < n_team_attrs; i++) {
-		const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, team_attrs[i]);
+    for (i = 0; i < n_team_attrs; i++) {
+        const TeamAttrData *attr_data = _team_attr_data_get(self->d.is_port, team_attrs[i]);
 
-		if (_team_setting_has_field (self, attr_data))
-			return TRUE;
-	}
-	return FALSE;
+        if (_team_setting_has_field(self, attr_data))
+            return TRUE;
+    }
+    return FALSE;
 }
 
-#define _team_setting_has_fields_any(self, ...) \
-   _team_setting_has_fields_any_v ((self), ((const NMTeamAttribute []) { __VA_ARGS__ }), NM_NARG (__VA_ARGS__))
+#define _team_setting_has_fields_any(self, ...)                              \
+    _team_setting_has_fields_any_v((self),                                   \
+                                   ((const NMTeamAttribute[]){__VA_ARGS__}), \
+                                   NM_NARG(__VA_ARGS__))
 
 static void
-_team_setting_has_field_set (NMTeamSetting *self,
-                             const TeamAttrData *attr_data,
-                             SetFieldModeEnum set_field_mode)
+_team_setting_has_field_set(NMTeamSetting *     self,
+                            const TeamAttrData *attr_data,
+                            SetFieldModeEnum    set_field_mode)
 {
-	guint32 mask = nm_team_attribute_to_flags (attr_data->team_attr);
-
-	_team_setting_ASSERT (self);
-
-	switch (set_field_mode) {
-	case SET_FIELD_MODE_UNSET:
-		goto do_unset;
-	case SET_FIELD_MODE_SET:
-		goto do_set;
-	case SET_FIELD_MODE_SET_UNLESS_DEFAULT:
-		if (_team_attr_data_equal (attr_data,
-		                           self->d.is_port,
-		                           _team_setting_get_field (self, attr_data),
-		                           &attr_data->default_val))
-			goto do_unset;
-		goto do_set;
-	}
-	nm_assert_not_reached ();
+    guint32 mask = nm_team_attribute_to_flags(attr_data->team_attr);
+
+    _team_setting_ASSERT(self);
+
+    switch (set_field_mode) {
+    case SET_FIELD_MODE_UNSET:
+        goto do_unset;
+    case SET_FIELD_MODE_SET:
+        goto do_set;
+    case SET_FIELD_MODE_SET_UNLESS_DEFAULT:
+        if (_team_attr_data_equal(attr_data,
+                                  self->d.is_port,
+                                  _team_setting_get_field(self, attr_data),
+                                  &attr_data->default_val))
+            goto do_unset;
+        goto do_set;
+    }
+    nm_assert_not_reached();
 
 do_unset:
-	self->_data_priv.has_fields_mask &= ~mask;
-	return;
+    self->_data_priv.has_fields_mask &= ~mask;
+    return;
 do_set:
-	self->_data_priv.has_fields_mask |= mask;
+    self->_data_priv.has_fields_mask |= mask;
 }
 
 static gpointer
-_team_setting_get_field (const NMTeamSetting *self,
-                         const TeamAttrData *attr_data)
+_team_setting_get_field(const NMTeamSetting *self, const TeamAttrData *attr_data)
 {
-	_team_setting_ASSERT (self);
-	_team_attr_data_ASSERT (attr_data);
-	nm_assert (_team_attr_data_is_relevant (attr_data, self->d.is_port));
+    _team_setting_ASSERT(self);
+    _team_attr_data_ASSERT(attr_data);
+    nm_assert(_team_attr_data_is_relevant(attr_data, self->d.is_port));
 
 #if NM_MORE_ASSERTS > 5
-	if (   attr_data->for_master
-	    && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO )
-		nm_assert ((gpointer) (((char *) self) + attr_data->field_offset) == &self->d.master.runner_sys_prio);
+    if (attr_data->for_master && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO)
+        nm_assert((gpointer)(((char *) self) + attr_data->field_offset)
+                  == &self->d.master.runner_sys_prio);
 #endif
 
-	return (((char *) self) + attr_data->field_offset);
+    return (((char *) self) + attr_data->field_offset);
 }
 
 static guint32
-_team_setting_attribute_changed (NMTeamSetting *self,
-                                 const TeamAttrData *attr_data,
-                                 gboolean changed,
-                                 SetFieldModeEnum set_field_mode,
-                                 ResetJsonEnum reset_json)
+_team_setting_attribute_changed(NMTeamSetting *     self,
+                                const TeamAttrData *attr_data,
+                                gboolean            changed,
+                                SetFieldModeEnum    set_field_mode,
+                                ResetJsonEnum       reset_json)
 {
-	guint32 changed_flags;
-
-	_team_setting_has_field_set (self, attr_data, set_field_mode);
-
-	if (!reset_json) {
-		return   changed
-		       ? nm_team_attribute_to_flags (attr_data->team_attr)
-		       : 0u;
-	}
-
-	if (!changed) {
-		/* a regular attribute was set, but the value did not change.
-		 *
-		 * If we previously were in non-strict mode, then
-		 *
-		 * - switch to strict-mode. Clearly the user set a regular attribute
-		 *   and hence now we want to validate the setting.
-		 *
-		 * - clear the JSON string. We need to regenerate it.
-		 */
-		if (self->_data_priv.strict_validated)
-			return 0;
-		changed_flags = nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-	} else {
-		changed_flags =   nm_team_attribute_to_flags (attr_data->team_attr)
-		                | nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-	}
-
-	nm_clear_g_free ((char **) &self->_data_priv._js_str);
-	self->_data_priv.strict_validated = TRUE;
-	self->_data_priv._js_str_need_synthetize = TRUE;
-
-	return changed_flags;
+    guint32 changed_flags;
+
+    _team_setting_has_field_set(self, attr_data, set_field_mode);
+
+    if (!reset_json) {
+        return changed ? nm_team_attribute_to_flags(attr_data->team_attr) : 0u;
+    }
+
+    if (!changed) {
+        /* a regular attribute was set, but the value did not change.
+         *
+         * If we previously were in non-strict mode, then
+         *
+         * - switch to strict-mode. Clearly the user set a regular attribute
+         *   and hence now we want to validate the setting.
+         *
+         * - clear the JSON string. We need to regenerate it.
+         */
+        if (self->_data_priv.strict_validated)
+            return 0;
+        changed_flags = nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+    } else {
+        changed_flags = nm_team_attribute_to_flags(attr_data->team_attr)
+                        | nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+    }
+
+    nm_clear_g_free((char **) &self->_data_priv._js_str);
+    self->_data_priv.strict_validated        = TRUE;
+    self->_data_priv._js_str_need_synthetize = TRUE;
+
+    return changed_flags;
 }
 
 static guint32
-_team_setting_attribute_changed_attr (NMTeamSetting *self,
-                                      NMTeamAttribute team_attr,
-                                      gboolean changed,
-                                      SetFieldModeEnum set_field_mode,
-                                      ResetJsonEnum reset_json)
+_team_setting_attribute_changed_attr(NMTeamSetting *  self,
+                                     NMTeamAttribute  team_attr,
+                                     gboolean         changed,
+                                     SetFieldModeEnum set_field_mode,
+                                     ResetJsonEnum    reset_json)
 {
-	return _team_setting_attribute_changed (self,
-	                                        _team_attr_data_get (self->d.is_port, team_attr),
-	                                        changed,
-	                                        set_field_mode,
-	                                        reset_json);
+    return _team_setting_attribute_changed(self,
+                                           _team_attr_data_get(self->d.is_port, team_attr),
+                                           changed,
+                                           set_field_mode,
+                                           reset_json);
 }
 
 static gboolean
-_team_setting_field_to_json (const NMTeamSetting *self,
-                             GString *gstr,
-                             gboolean prepend_delimiter,
-                             const TeamAttrData *attr_data)
+_team_setting_field_to_json(const NMTeamSetting *self,
+                            GString *            gstr,
+                            gboolean             prepend_delimiter,
+                            const TeamAttrData * attr_data)
 {
-	if (!_team_setting_has_field (self, attr_data))
-		return FALSE;
-
-	if (prepend_delimiter)
-		nm_json_aux_gstr_append_delimiter (gstr);
-	_team_attr_data_to_json (attr_data,
-	                         self->d.is_port,
-	                         gstr,
-	                         _team_setting_get_field (self, attr_data));
-	return TRUE;
+    if (!_team_setting_has_field(self, attr_data))
+        return FALSE;
+
+    if (prepend_delimiter)
+        nm_json_gstr_append_delimiter(gstr);
+    _team_attr_data_to_json(attr_data,
+                            self->d.is_port,
+                            gstr,
+                            _team_setting_get_field(self, attr_data));
+    return TRUE;
 }
 
 static gboolean
-_team_setting_fields_to_json_maybe (const NMTeamSetting *self,
-                                    GString *gstr,
-                                    gboolean prepend_delimiter,
-                                    const NMTeamAttribute *team_attrs_lst,
-                                    gsize team_attrs_lst_len)
+_team_setting_fields_to_json_maybe(const NMTeamSetting *  self,
+                                   GString *              gstr,
+                                   gboolean               prepend_delimiter,
+                                   const NMTeamAttribute *team_attrs_lst,
+                                   gsize                  team_attrs_lst_len)
 {
-	gsize i;
-	gboolean any_added = FALSE;
-
-	for (i = 0; i < team_attrs_lst_len; i++) {
-		if (_team_setting_field_to_json (self,
-		                                 gstr,
-		                                 prepend_delimiter,
-		                                 _team_attr_data_get (self->d.is_port, team_attrs_lst[i]))) {
-			any_added = TRUE;
-			prepend_delimiter = TRUE;
-		}
-	}
-	return any_added;
+    gsize    i;
+    gboolean any_added = FALSE;
+
+    for (i = 0; i < team_attrs_lst_len; i++) {
+        if (_team_setting_field_to_json(self,
+                                        gstr,
+                                        prepend_delimiter,
+                                        _team_attr_data_get(self->d.is_port, team_attrs_lst[i]))) {
+            any_added         = TRUE;
+            prepend_delimiter = TRUE;
+        }
+    }
+    return any_added;
 }
 
 static guint32
-_team_setting_set (NMTeamSetting *self,
-                   gboolean modify,
-                   const bool *has_lst,
-                   const NMValueTypUnion *val_lst)
+_team_setting_set(NMTeamSetting *        self,
+                  gboolean               modify,
+                  const bool *           has_lst,
+                  const NMValueTypUnion *val_lst)
 {
-	guint32 changed_flags = 0;
-	const TeamAttrData *attr_data;
-
-	nm_assert ((!has_lst) == (!val_lst));
-
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		const NMValueTypUnion *p_val;
-		gconstpointer p_field;
-		gboolean has_field;
-
-		if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
-			continue;
-
-		has_field = (has_lst && has_lst[attr_data->team_attr]);
-
-		p_val = has_field
-		        ? &val_lst[attr_data->team_attr]
-		        : &attr_data->default_val;
-
-		p_field = _team_setting_get_field (self, attr_data);
-
-		if (!_team_attr_data_equal (attr_data,
-		                            self->d.is_port,
-		                            p_val,
-		                            p_field)) {
-			if (modify) {
-				_team_attr_data_copy (attr_data,
-				                      self->d.is_port,
-				                      (gpointer) p_field,
-				                      p_val);
-			}
-			changed_flags |= nm_team_attribute_to_flags (attr_data->team_attr);
-		}
-
-		if (modify) {
-			_team_setting_has_field_set (self,
-			                             attr_data,
-			                               has_field
-			                             ? SET_FIELD_MODE_SET
-			                             : SET_FIELD_MODE_UNSET);
-		}
-	}
-
-	return changed_flags;
+    guint32             changed_flags = 0;
+    const TeamAttrData *attr_data;
+
+    nm_assert((!has_lst) == (!val_lst));
+
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        const NMValueTypUnion *p_val;
+        gconstpointer          p_field;
+        gboolean               has_field;
+
+        if (!_team_attr_data_is_relevant(attr_data, self->d.is_port))
+            continue;
+
+        has_field = (has_lst && has_lst[attr_data->team_attr]);
+
+        p_val = has_field ? &val_lst[attr_data->team_attr] : &attr_data->default_val;
+
+        p_field = _team_setting_get_field(self, attr_data);
+
+        if (!_team_attr_data_equal(attr_data, self->d.is_port, p_val, p_field)) {
+            if (modify) {
+                _team_attr_data_copy(attr_data, self->d.is_port, (gpointer) p_field, p_val);
+            }
+            changed_flags |= nm_team_attribute_to_flags(attr_data->team_attr);
+        }
+
+        if (modify) {
+            _team_setting_has_field_set(self,
+                                        attr_data,
+                                        has_field ? SET_FIELD_MODE_SET : SET_FIELD_MODE_UNSET);
+        }
+    }
+
+    return changed_flags;
 }
 
 static guint32
-_team_setting_check_default (const NMTeamSetting *self)
+_team_setting_check_default(const NMTeamSetting *self)
 {
-	return _team_setting_set ((NMTeamSetting *) self, FALSE, NULL, NULL);
+    return _team_setting_set((NMTeamSetting *) self, FALSE, NULL, NULL);
 }
 
 static guint32
-_team_setting_set_default (NMTeamSetting *self)
+_team_setting_set_default(NMTeamSetting *self)
 {
-	return _team_setting_set (self, TRUE, NULL, NULL);
+    return _team_setting_set(self, TRUE, NULL, NULL);
 }
 
 /*****************************************************************************/
 
 gconstpointer
-_nm_team_setting_value_get (const NMTeamSetting *self,
-                            NMTeamAttribute team_attr,
-                            NMValueType value_type)
+_nm_team_setting_value_get(const NMTeamSetting *self,
+                           NMTeamAttribute      team_attr,
+                           NMValueType          value_type)
 {
-	const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+    const TeamAttrData *attr_data = _team_attr_data_get(self->d.is_port, team_attr);
 
-	nm_assert (value_type == attr_data->value_type);
+    nm_assert(value_type == attr_data->value_type);
 
-	nm_assert (   _team_setting_has_field (self, attr_data)
-	           || _team_attr_data_equal (attr_data,
-	                                     self->d.is_port,
-	                                     _team_setting_get_field (self, attr_data),
-	                                     &attr_data->default_val));
-	return _team_setting_get_field (self, attr_data);
+    nm_assert(_team_setting_has_field(self, attr_data)
+              || _team_attr_data_equal(attr_data,
+                                       self->d.is_port,
+                                       _team_setting_get_field(self, attr_data),
+                                       &attr_data->default_val));
+    return _team_setting_get_field(self, attr_data);
 }
 
 static guint32
-_team_setting_value_set (NMTeamSetting *self,
-                         const TeamAttrData *attr_data,
-                         gconstpointer val,
-                         SetFieldModeEnum set_field_mode,
-                         ResetJsonEnum reset_json)
+_team_setting_value_set(NMTeamSetting *     self,
+                        const TeamAttrData *attr_data,
+                        gconstpointer       val,
+                        SetFieldModeEnum    set_field_mode,
+                        ResetJsonEnum       reset_json)
 {
-	gpointer p_field;
-	gboolean changed;
+    gpointer p_field;
+    gboolean changed;
 
-	nm_assert (self);
-	_team_attr_data_ASSERT (attr_data);
-	nm_assert (val);
+    nm_assert(self);
+    _team_attr_data_ASSERT(attr_data);
+    nm_assert(val);
 
-	p_field = _team_setting_get_field (self, attr_data);
+    p_field = _team_setting_get_field(self, attr_data);
 
-	changed = !_team_attr_data_equal (attr_data, self->d.is_port, p_field, val);
-	if (changed)
-		nm_value_type_copy (attr_data->value_type, p_field, val);
-	return _team_setting_attribute_changed (self, attr_data, changed, set_field_mode, reset_json);
+    changed = !_team_attr_data_equal(attr_data, self->d.is_port, p_field, val);
+    if (changed)
+        nm_value_type_copy(attr_data->value_type, p_field, val);
+    return _team_setting_attribute_changed(self, attr_data, changed, set_field_mode, reset_json);
 }
 
 guint32
-nm_team_setting_value_reset (NMTeamSetting *self,
-                             NMTeamAttribute team_attr,
-                             gboolean to_default /* or else unset */)
+nm_team_setting_value_reset(NMTeamSetting * self,
+                            NMTeamAttribute team_attr,
+                            gboolean        to_default /* or else unset */)
 {
-	const TeamAttrData *attr_data;
+    const TeamAttrData *attr_data;
 
-	nm_assert (self);
+    nm_assert(self);
 
-	attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+    attr_data = _team_attr_data_get(self->d.is_port, team_attr);
 
-	return _team_setting_value_set (self,
-	                                attr_data,
-	                                &attr_data->default_val,
-	                                  to_default
-	                                ? SET_FIELD_MODE_SET
-	                                : SET_FIELD_MODE_UNSET,
-	                                RESET_JSON_YES);
+    return _team_setting_value_set(self,
+                                   attr_data,
+                                   &attr_data->default_val,
+                                   to_default ? SET_FIELD_MODE_SET : SET_FIELD_MODE_UNSET,
+                                   RESET_JSON_YES);
 }
 
 guint32
-_nm_team_setting_value_set (NMTeamSetting *self,
-                            NMTeamAttribute team_attr,
-                            NMValueType value_type,
-                            gconstpointer val)
+_nm_team_setting_value_set(NMTeamSetting * self,
+                           NMTeamAttribute team_attr,
+                           NMValueType     value_type,
+                           gconstpointer   val)
 {
-	const TeamAttrData *attr_data;
+    const TeamAttrData *attr_data;
 
-	nm_assert (self);
+    nm_assert(self);
 
-	attr_data = _team_attr_data_get (self->d.is_port, team_attr);
+    attr_data = _team_attr_data_get(self->d.is_port, team_attr);
 
-	nm_assert (value_type == attr_data->value_type);
+    nm_assert(value_type == attr_data->value_type);
 
-	return _team_setting_value_set (self,
-	                                attr_data,
-	                                val,
-	                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
-	                                RESET_JSON_YES);
+    return _team_setting_value_set(self,
+                                   attr_data,
+                                   val,
+                                   SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                   RESET_JSON_YES);
 }
 
 guint32
-nm_team_setting_value_link_watchers_add (NMTeamSetting *self,
-                                         const NMTeamLinkWatcher *link_watcher)
+nm_team_setting_value_link_watchers_add(NMTeamSetting *self, const NMTeamLinkWatcher *link_watcher)
 {
-	guint i;
-	gboolean changed;
-
-	for (i = 0; i < self->d.link_watchers->len; i++) {
-		if (nm_team_link_watcher_equal (self->d.link_watchers->pdata[i], link_watcher)) {
-			changed = FALSE;
-			goto out;
-		}
-	}
-	changed = TRUE;
-	g_ptr_array_add ((GPtrArray *) self->d.link_watchers,
-	                 _nm_team_link_watcher_ref ((NMTeamLinkWatcher *) link_watcher));
+    guint    i;
+    gboolean changed;
+
+    for (i = 0; i < self->d.link_watchers->len; i++) {
+        if (nm_team_link_watcher_equal(self->d.link_watchers->pdata[i], link_watcher)) {
+            changed = FALSE;
+            goto out;
+        }
+    }
+    changed = TRUE;
+    g_ptr_array_add((GPtrArray *) self->d.link_watchers,
+                    _nm_team_link_watcher_ref((NMTeamLinkWatcher *) link_watcher));
 out:
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, changed, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
+                                                changed,
+                                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                RESET_JSON_YES);
 }
 
 guint32
-nm_team_setting_value_link_watchers_remove_by_value (NMTeamSetting *self,
-                                                     const NMTeamLinkWatcher *link_watcher)
+nm_team_setting_value_link_watchers_remove_by_value(NMTeamSetting *          self,
+                                                    const NMTeamLinkWatcher *link_watcher)
 {
-	guint i;
-
-	for (i = 0; i < self->d.link_watchers->len; i++) {
-		if (nm_team_link_watcher_equal (self->d.link_watchers->pdata[i],
-		                                link_watcher))
-			return nm_team_setting_value_link_watchers_remove (self, i);
-	}
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, FALSE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
+    guint i;
+
+    for (i = 0; i < self->d.link_watchers->len; i++) {
+        if (nm_team_link_watcher_equal(self->d.link_watchers->pdata[i], link_watcher))
+            return nm_team_setting_value_link_watchers_remove(self, i);
+    }
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
+                                                FALSE,
+                                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                RESET_JSON_YES);
 }
 
 guint32
-nm_team_setting_value_link_watchers_remove (NMTeamSetting *self,
-                                            guint idx)
+nm_team_setting_value_link_watchers_remove(NMTeamSetting *self, guint idx)
 {
-	g_ptr_array_remove_index ((GPtrArray *) self->d.link_watchers, idx);
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, TRUE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
+    g_ptr_array_remove_index((GPtrArray *) self->d.link_watchers, idx);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
+                                                TRUE,
+                                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                RESET_JSON_YES);
 }
 
 static guint32
-_team_setting_value_link_watchers_set_list (NMTeamSetting *self,
-                                            const NMTeamLinkWatcher *const*arr,
-                                            guint len,
-                                            SetFieldModeEnum set_field_mode,
-                                            ResetJsonEnum reset_json)
+_team_setting_value_link_watchers_set_list(NMTeamSetting *                 self,
+                                           const NMTeamLinkWatcher *const *arr,
+                                           guint                           len,
+                                           SetFieldModeEnum                set_field_mode,
+                                           ResetJsonEnum                   reset_json)
 {
-	gboolean changed;
-
-	if (   self->d.link_watchers->len == len
-	    && nm_team_link_watchers_cmp ((const NMTeamLinkWatcher *const*) self->d.link_watchers->pdata,
-	                                  arr,
-	                                  len,
-	                                  FALSE) == 0) {
-		changed = FALSE;
-		goto out;
-	}
-
-	changed = TRUE;
-	if (len == 0)
-		g_ptr_array_set_size ((GPtrArray *) self->d.link_watchers, 0);
-	else {
-		_nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL;
-		guint i;
-
-		old_val_destroy = (GPtrArray *) g_steal_pointer (&self->_data_priv.link_watchers);
-
-		self->_data_priv.link_watchers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref);
-
-		for (i = 0; i < len; i++) {
-			if (arr[i]) {
-				g_ptr_array_add ((GPtrArray *) self->d.link_watchers,
-				                 _nm_team_link_watcher_ref ((NMTeamLinkWatcher *) arr[i]));
-			}
-		}
-	}
+    gboolean changed;
+
+    if (self->d.link_watchers->len == len
+        && nm_team_link_watchers_cmp(
+               (const NMTeamLinkWatcher *const *) self->d.link_watchers->pdata,
+               arr,
+               len,
+               FALSE)
+               == 0) {
+        changed = FALSE;
+        goto out;
+    }
+
+    changed = TRUE;
+    if (len == 0)
+        g_ptr_array_set_size((GPtrArray *) self->d.link_watchers, 0);
+    else {
+        _nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL;
+        guint                                   i;
+
+        old_val_destroy = (GPtrArray *) g_steal_pointer(&self->_data_priv.link_watchers);
+
+        self->_data_priv.link_watchers =
+            g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref);
+
+        for (i = 0; i < len; i++) {
+            if (arr[i]) {
+                g_ptr_array_add((GPtrArray *) self->d.link_watchers,
+                                _nm_team_link_watcher_ref((NMTeamLinkWatcher *) arr[i]));
+            }
+        }
+    }
 
 out:
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_LINK_WATCHERS, changed, set_field_mode, reset_json);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_LINK_WATCHERS,
+                                                changed,
+                                                set_field_mode,
+                                                reset_json);
 }
 
 guint32
-nm_team_setting_value_link_watchers_set_list (NMTeamSetting *self,
-                                              const NMTeamLinkWatcher *const*arr,
-                                              guint len)
+nm_team_setting_value_link_watchers_set_list(NMTeamSetting *                 self,
+                                             const NMTeamLinkWatcher *const *arr,
+                                             guint                           len)
 {
-	return _team_setting_value_link_watchers_set_list (self,
-	                                                   arr,
-	                                                   len,
-	                                                   SET_FIELD_MODE_SET_UNLESS_DEFAULT,
-	                                                   RESET_JSON_YES);
+    return _team_setting_value_link_watchers_set_list(self,
+                                                      arr,
+                                                      len,
+                                                      SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                      RESET_JSON_YES);
 }
 
 /*****************************************************************************/
 
 guint32
-nm_team_setting_value_master_runner_tx_hash_add (NMTeamSetting *self,
-                                                 const char *txhash)
+nm_team_setting_value_master_runner_tx_hash_add(NMTeamSetting *self, const char *txhash)
 {
-	gboolean changed;
-	guint i;
-
-	if (!self->d.master.runner_tx_hash)
-		self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func (g_free);
-	else {
-		for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
-			if (nm_streq (txhash, self->d.master.runner_tx_hash->pdata[i])) {
-				changed = FALSE;
-				goto out;
-			}
-		}
-	}
-	changed = TRUE;
-	g_ptr_array_add ((GPtrArray *) self->d.master.runner_tx_hash, g_strdup (txhash));
+    gboolean changed;
+    guint    i;
+
+    if (!self->d.master.runner_tx_hash)
+        self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func(g_free);
+    else {
+        for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
+            if (nm_streq(txhash, self->d.master.runner_tx_hash->pdata[i])) {
+                changed = FALSE;
+                goto out;
+            }
+        }
+    }
+    changed = TRUE;
+    g_ptr_array_add((GPtrArray *) self->d.master.runner_tx_hash, g_strdup(txhash));
 out:
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, changed, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+                                                changed,
+                                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                RESET_JSON_YES);
 }
 
 guint32
-nm_team_setting_value_master_runner_tx_hash_remove (NMTeamSetting *self,
-                                                    guint idx)
+nm_team_setting_value_master_runner_tx_hash_remove(NMTeamSetting *self, guint idx)
 {
-	g_ptr_array_remove_index ((GPtrArray *) self->d.master.runner_tx_hash, idx);
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, TRUE, SET_FIELD_MODE_SET_UNLESS_DEFAULT, RESET_JSON_YES);
+    g_ptr_array_remove_index((GPtrArray *) self->d.master.runner_tx_hash, idx);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+                                                TRUE,
+                                                SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                RESET_JSON_YES);
 }
 
 static guint32
-_team_setting_value_master_runner_tx_hash_set_list (NMTeamSetting *self,
-                                                    const char *const*arr,
-                                                    guint len,
-                                                    SetFieldModeEnum set_field_mode,
-                                                    ResetJsonEnum reset_json)
+_team_setting_value_master_runner_tx_hash_set_list(NMTeamSetting *    self,
+                                                   const char *const *arr,
+                                                   guint              len,
+                                                   SetFieldModeEnum   set_field_mode,
+                                                   ResetJsonEnum      reset_json)
 {
-	_nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL;
-	gboolean changed;
-	guint i;
-
-	if (_nm_utils_strv_cmp_n (self->d.master.runner_tx_hash ? (const char *const*) self->d.master.runner_tx_hash->pdata : NULL,
-	                          self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len : 0u,
-	                          arr,
-	                          len) == 0) {
-		changed = FALSE;
-		goto out;
-	}
-
-	changed = TRUE;
-
-	old_val_destroy = (GPtrArray *) g_steal_pointer (&self->_data_priv.master.runner_tx_hash);
-
-	for (i = 0; i < len; i++) {
-		if (!arr[i])
-			continue;
-		if (!self->d.master.runner_tx_hash)
-			self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func (g_free);
-		g_ptr_array_add ((GPtrArray *) self->d.master.runner_tx_hash, g_strdup (arr[i]));
-	}
+    _nm_unused gs_unref_ptrarray GPtrArray *old_val_destroy = NULL;
+    gboolean                                changed;
+    guint                                   i;
+
+    if (_nm_utils_strv_cmp_n(self->d.master.runner_tx_hash
+                                 ? (const char *const *) self->d.master.runner_tx_hash->pdata
+                                 : NULL,
+                             self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len
+                                                           : 0u,
+                             arr,
+                             len)
+        == 0) {
+        changed = FALSE;
+        goto out;
+    }
+
+    changed = TRUE;
+
+    old_val_destroy = (GPtrArray *) g_steal_pointer(&self->_data_priv.master.runner_tx_hash);
+
+    for (i = 0; i < len; i++) {
+        if (!arr[i])
+            continue;
+        if (!self->d.master.runner_tx_hash)
+            self->_data_priv.master.runner_tx_hash = g_ptr_array_new_with_free_func(g_free);
+        g_ptr_array_add((GPtrArray *) self->d.master.runner_tx_hash, g_strdup(arr[i]));
+    }
 
 out:
-	return _team_setting_attribute_changed_attr (self, NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH, changed, set_field_mode, reset_json);
+    return _team_setting_attribute_changed_attr(self,
+                                                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+                                                changed,
+                                                set_field_mode,
+                                                reset_json);
 }
 
 guint32
-nm_team_setting_value_master_runner_tx_hash_set_list (NMTeamSetting *self,
-                                                      const char *const*arr,
-                                                      guint len)
+nm_team_setting_value_master_runner_tx_hash_set_list(NMTeamSetting *    self,
+                                                     const char *const *arr,
+                                                     guint              len)
 {
-	return _team_setting_value_master_runner_tx_hash_set_list (self,
-	                                                           arr,
-	                                                           len,
-	                                                           SET_FIELD_MODE_SET_UNLESS_DEFAULT,
-	                                                           RESET_JSON_YES);
+    return _team_setting_value_master_runner_tx_hash_set_list(self,
+                                                              arr,
+                                                              len,
+                                                              SET_FIELD_MODE_SET_UNLESS_DEFAULT,
+                                                              RESET_JSON_YES);
 }
 
 /*****************************************************************************/
 
-#define _LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, _value_type) \
-	({ \
-		const NMValueTypUnioMaybe *const _args = (args); \
-		\
-		nm_assert (link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
-		\
-		  _args[(link_watcher_attribute)].has \
-		? &_args[(link_watcher_attribute)].val \
-		: &link_watcher_attr_datas[(link_watcher_attribute)].default_val; \
-	})
-#define _LINK_WATCHER_ATTR_GET_BOOL(args, link_watcher_attribute)   (_LINK_WATCHER_ATTR_GET (args, link_watcher_attribute, NM_VALUE_TYPE_BOOL   )->v_bool)
-#define _LINK_WATCHER_ATTR_GET_INT(args, link_watcher_attribute)    (_LINK_WATCHER_ATTR_GET (args, link_watcher_attribute, NM_VALUE_TYPE_INT    )->v_int)
-#define _LINK_WATCHER_ATTR_GET_STRING(args, link_watcher_attribute) (_LINK_WATCHER_ATTR_GET (args, link_watcher_attribute, NM_VALUE_TYPE_STRING )->v_string)
-
-#define _LINK_WATCHER_ATTR_SET(args, link_watcher_attribute, _value_type, c_type, val) \
-	({ \
-		nm_assert (link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
-		\
-		NM_VALUE_TYP_UNIO_MAYBE_SET (&(args)[(link_watcher_attribute)], c_type, (val)); \
-	})
-#define _LINK_WATCHER_ATTR_SET_BOOL(args, link_watcher_attribute, val)   _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_BOOL,   v_bool,   (val))
-#define _LINK_WATCHER_ATTR_SET_INT(args, link_watcher_attribute, val)    _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_INT,    v_int,    (val))
-#define _LINK_WATCHER_ATTR_SET_STRING(args, link_watcher_attribute, val) _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_STRING, v_string, (val))
+#define _LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, _value_type)                         \
+    ({                                                                                            \
+        const NMValueTypUnioMaybe *const _args = (args);                                          \
+                                                                                                  \
+        nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
+                                                                                                  \
+        _args[(link_watcher_attribute)].has                                                       \
+            ? &_args[(link_watcher_attribute)].val                                                \
+            : &link_watcher_attr_datas[(link_watcher_attribute)].default_val;                     \
+    })
+#define _LINK_WATCHER_ATTR_GET_BOOL(args, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_BOOL)->v_bool)
+#define _LINK_WATCHER_ATTR_GET_INT(args, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_INT)->v_int)
+#define _LINK_WATCHER_ATTR_GET_STRING(args, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_GET(args, link_watcher_attribute, NM_VALUE_TYPE_STRING)->v_string)
+
+#define _LINK_WATCHER_ATTR_SET(args, link_watcher_attribute, _value_type, c_type, val)            \
+    ({                                                                                            \
+        nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
+                                                                                                  \
+        NM_VALUE_TYP_UNIO_MAYBE_SET(&(args)[(link_watcher_attribute)], c_type, (val));            \
+    })
+#define _LINK_WATCHER_ATTR_SET_BOOL(args, link_watcher_attribute, val) \
+    _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_BOOL, v_bool, (val))
+#define _LINK_WATCHER_ATTR_SET_INT(args, link_watcher_attribute, val) \
+    _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_INT, v_int, (val))
+#define _LINK_WATCHER_ATTR_SET_STRING(args, link_watcher_attribute, val) \
+    _LINK_WATCHER_ATTR_SET((args), (link_watcher_attribute), NM_VALUE_TYPE_STRING, v_string, (val))
 
 static void
-_link_watcher_unpack (const NMTeamLinkWatcher *link_watcher,
-                      NMValueTypUnioMaybe args[static G_N_ELEMENTS (link_watcher_attr_datas)])
+_link_watcher_unpack(const NMTeamLinkWatcher *link_watcher,
+                     NMValueTypUnioMaybe      args[static G_N_ELEMENTS(link_watcher_attr_datas)])
 {
-	const char *v_name = nm_team_link_watcher_get_name (link_watcher);
-	NMTeamLinkWatcherArpPingFlags v_arp_ping_flags;
-
-	memset (args, 0, sizeof (args[0]) * G_N_ELEMENTS (link_watcher_attr_datas));
-
-	_LINK_WATCHER_ATTR_SET_STRING (args, LINK_WATCHER_ATTRIBUTE_NAME, v_name);
-
-	if (nm_streq (v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
-		_LINK_WATCHER_ATTR_SET_INT (args, LINK_WATCHER_ATTRIBUTE_DELAY_UP,   nm_team_link_watcher_get_delay_up (link_watcher));
-		_LINK_WATCHER_ATTR_SET_INT (args, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN, nm_team_link_watcher_get_delay_down (link_watcher));
-	} else if (NM_IN_STRSET (v_name, NM_TEAM_LINK_WATCHER_NSNA_PING,
-	                                 NM_TEAM_LINK_WATCHER_ARP_PING)) {
-		_LINK_WATCHER_ATTR_SET_INT    (args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT,   nm_team_link_watcher_get_init_wait (link_watcher));
-		_LINK_WATCHER_ATTR_SET_INT    (args, LINK_WATCHER_ATTRIBUTE_INTERVAL,    nm_team_link_watcher_get_interval (link_watcher));
-		_LINK_WATCHER_ATTR_SET_INT    (args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX,  nm_team_link_watcher_get_missed_max (link_watcher));
-		_LINK_WATCHER_ATTR_SET_STRING (args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST, nm_team_link_watcher_get_target_host (link_watcher));
-		if (nm_streq (v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
-			v_arp_ping_flags = nm_team_link_watcher_get_flags (link_watcher);
-			_LINK_WATCHER_ATTR_SET_INT    (args, LINK_WATCHER_ATTRIBUTE_VLANID,            nm_team_link_watcher_get_vlanid (link_watcher));
-			_LINK_WATCHER_ATTR_SET_STRING (args, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST,       nm_team_link_watcher_get_source_host (link_watcher));
-			_LINK_WATCHER_ATTR_SET_BOOL   (args, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,   NM_FLAGS_HAS (v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE));
-			_LINK_WATCHER_ATTR_SET_BOOL   (args, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE, NM_FLAGS_HAS (v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE));
-			_LINK_WATCHER_ATTR_SET_BOOL   (args, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS,       NM_FLAGS_HAS (v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS));
-		}
-	}
+    const char *                  v_name = nm_team_link_watcher_get_name(link_watcher);
+    NMTeamLinkWatcherArpPingFlags v_arp_ping_flags;
+
+    memset(args, 0, sizeof(args[0]) * G_N_ELEMENTS(link_watcher_attr_datas));
+
+    _LINK_WATCHER_ATTR_SET_STRING(args, LINK_WATCHER_ATTRIBUTE_NAME, v_name);
+
+    if (nm_streq(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
+        _LINK_WATCHER_ATTR_SET_INT(args,
+                                   LINK_WATCHER_ATTRIBUTE_DELAY_UP,
+                                   nm_team_link_watcher_get_delay_up(link_watcher));
+        _LINK_WATCHER_ATTR_SET_INT(args,
+                                   LINK_WATCHER_ATTRIBUTE_DELAY_DOWN,
+                                   nm_team_link_watcher_get_delay_down(link_watcher));
+    } else if (NM_IN_STRSET(v_name,
+                            NM_TEAM_LINK_WATCHER_NSNA_PING,
+                            NM_TEAM_LINK_WATCHER_ARP_PING)) {
+        _LINK_WATCHER_ATTR_SET_INT(args,
+                                   LINK_WATCHER_ATTRIBUTE_INIT_WAIT,
+                                   nm_team_link_watcher_get_init_wait(link_watcher));
+        _LINK_WATCHER_ATTR_SET_INT(args,
+                                   LINK_WATCHER_ATTRIBUTE_INTERVAL,
+                                   nm_team_link_watcher_get_interval(link_watcher));
+        _LINK_WATCHER_ATTR_SET_INT(args,
+                                   LINK_WATCHER_ATTRIBUTE_MISSED_MAX,
+                                   nm_team_link_watcher_get_missed_max(link_watcher));
+        _LINK_WATCHER_ATTR_SET_STRING(args,
+                                      LINK_WATCHER_ATTRIBUTE_TARGET_HOST,
+                                      nm_team_link_watcher_get_target_host(link_watcher));
+        if (nm_streq(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
+            v_arp_ping_flags = nm_team_link_watcher_get_flags(link_watcher);
+            _LINK_WATCHER_ATTR_SET_INT(args,
+                                       LINK_WATCHER_ATTRIBUTE_VLANID,
+                                       nm_team_link_watcher_get_vlanid(link_watcher));
+            _LINK_WATCHER_ATTR_SET_STRING(args,
+                                          LINK_WATCHER_ATTRIBUTE_SOURCE_HOST,
+                                          nm_team_link_watcher_get_source_host(link_watcher));
+            _LINK_WATCHER_ATTR_SET_BOOL(
+                args,
+                LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE,
+                NM_FLAGS_HAS(v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE));
+            _LINK_WATCHER_ATTR_SET_BOOL(
+                args,
+                LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE,
+                NM_FLAGS_HAS(v_arp_ping_flags,
+                             NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE));
+            _LINK_WATCHER_ATTR_SET_BOOL(
+                args,
+                LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS,
+                NM_FLAGS_HAS(v_arp_ping_flags, NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS));
+        }
+    }
 }
 
 static void
-_link_watcher_to_json (const NMTeamLinkWatcher *link_watcher,
-                       GString *gstr)
+_link_watcher_to_json(const NMTeamLinkWatcher *link_watcher, GString *gstr)
 {
-	NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)];
-	int i;
-	gboolean is_first = TRUE;
+    NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)];
+    int                 i;
+    gboolean            is_first = TRUE;
 
-	if (!link_watcher) {
-		g_string_append (gstr, "null");
-		return;
-	}
+    if (!link_watcher) {
+        g_string_append(gstr, "null");
+        return;
+    }
 
-	_link_watcher_unpack (link_watcher, args);
+    _link_watcher_unpack(link_watcher, args);
 
-	g_string_append (gstr, "{ ");
+    g_string_append(gstr, "{ ");
 
-	for (i = 0; i < (int) G_N_ELEMENTS (link_watcher_attr_datas); i++) {
-		const NMValueTypUnioMaybe *p_val = &args[i];
-		const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i];
+    for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) {
+        const NMValueTypUnioMaybe *p_val     = &args[i];
+        const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i];
 
-		if (!p_val->has)
-			continue;
-		if (nm_value_type_equal (attr_data->value_type, &attr_data->default_val, &p_val->val))
-			continue;
+        if (!p_val->has)
+            continue;
+        if (nm_value_type_equal(attr_data->value_type, &attr_data->default_val, &p_val->val))
+            continue;
 
-		if (is_first)
-			is_first = FALSE;
-		else
-			nm_json_aux_gstr_append_delimiter (gstr);
-		nm_json_aux_gstr_append_obj_name (gstr, attr_data->js_key, '\0');
-		nm_value_type_to_json (attr_data->value_type, gstr, &p_val->val);
-	}
+        if (is_first)
+            is_first = FALSE;
+        else
+            nm_json_gstr_append_delimiter(gstr);
+        nm_json_gstr_append_obj_name(gstr, attr_data->js_key, '\0');
+        nm_value_type_to_json(attr_data->value_type, gstr, &p_val->val);
+    }
 
-	g_string_append (gstr, " }");
+    g_string_append(gstr, " }");
 }
 
-#if WITH_JSON_VALIDATION
 static NMTeamLinkWatcher *
-_link_watcher_from_json (const json_t *root_js_obj,
-                         gboolean *out_unrecognized_content)
+_link_watcher_from_json(const NMJsonVt * vt,
+                        const nm_json_t *root_js_obj,
+                        gboolean *       out_unrecognized_content)
 {
-	NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)] = { };
-	const char *j_key;
-	json_t *j_val;
-	const char *v_name;
-	NMTeamLinkWatcher *result = NULL;
-
-	if (!json_is_object (root_js_obj))
-		goto fail;
-
-	json_object_foreach ((json_t *) root_js_obj, j_key, j_val) {
-		const LinkWatcherAttrData *attr_data = NULL;
-		NMValueTypUnioMaybe *parse_result;
-
-		if (j_key) {
-			int i;
-
-			for (i = 0; i < (int) G_N_ELEMENTS (link_watcher_attr_datas); i++) {
-				if (nm_streq (link_watcher_attr_datas[i].js_key, j_key)) {
-					attr_data = &link_watcher_attr_datas[i];
-					break;
-				}
-			}
-		}
-		if (!attr_data) {
-			*out_unrecognized_content = TRUE;
-			continue;
-		}
-
-		parse_result = &args[attr_data->link_watcher_attr];
-
-		if (parse_result->has)
-			*out_unrecognized_content = TRUE;
-
-		if (!nm_value_type_from_json (attr_data->value_type, j_val, &parse_result->val))
-			*out_unrecognized_content = TRUE;
-		else
-			parse_result->has = TRUE;
-	}
-
-#define _PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(_parse_results, ...) \
-	({ \
-		int _i; \
-		\
-		for (_i = 0; _i < (int) G_N_ELEMENTS ((_parse_results)); _i++) { \
-			if (   (_parse_results)[_i].has \
-			    && !NM_IN_SET ((LinkWatcherAttribute) _i, __VA_ARGS__)) \
-				break; \
-		} \
-		\
-		(_i == (int) G_N_ELEMENTS ((_parse_results))); \
-	})
-
-	v_name = _LINK_WATCHER_ATTR_GET_STRING (args, LINK_WATCHER_ATTRIBUTE_NAME);
-
-	if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
-		if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES (args, _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL))
-			*out_unrecognized_content = TRUE;
-		result = nm_team_link_watcher_new_ethtool (_LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_DELAY_UP),
-		                                           _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN),
-		                                           NULL);
-	} else if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) {
-		if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES (args, _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING))
-			*out_unrecognized_content = TRUE;
-		result = nm_team_link_watcher_new_nsna_ping (_LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
-		                                             _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_INTERVAL),
-		                                             _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
-		                                             _LINK_WATCHER_ATTR_GET_STRING (args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
-		                                             NULL);
-	} else if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
-		NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE;
-
-		if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES (args, _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING))
-			*out_unrecognized_content = TRUE;
-
-		if (_LINK_WATCHER_ATTR_GET_BOOL (args, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE;
-		if (_LINK_WATCHER_ATTR_GET_BOOL (args, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE;
-		if (_LINK_WATCHER_ATTR_GET_BOOL (args, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS;
-
-		result = nm_team_link_watcher_new_arp_ping2 (_LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
-		                                             _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_INTERVAL),
-		                                             _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
-		                                             _LINK_WATCHER_ATTR_GET_INT (args, LINK_WATCHER_ATTRIBUTE_VLANID),
-		                                             _LINK_WATCHER_ATTR_GET_STRING (args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
-		                                             _LINK_WATCHER_ATTR_GET_STRING (args, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST),
-		                                             v_flags,
-		                                             NULL);
-	}
-
-	if (result)
-		return result;
+    NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)] = {};
+    const char *        j_key;
+    nm_json_t *         j_val;
+    const char *        v_name;
+    NMTeamLinkWatcher * result = NULL;
+
+    if (!nm_json_is_object(root_js_obj))
+        goto fail;
+
+    nm_json_object_foreach (vt, (nm_json_t *) root_js_obj, j_key, j_val) {
+        const LinkWatcherAttrData *attr_data = NULL;
+        NMValueTypUnioMaybe *      parse_result;
+
+        if (j_key) {
+            int i;
+
+            for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) {
+                if (nm_streq(link_watcher_attr_datas[i].js_key, j_key)) {
+                    attr_data = &link_watcher_attr_datas[i];
+                    break;
+                }
+            }
+        }
+        if (!attr_data) {
+            *out_unrecognized_content = TRUE;
+            continue;
+        }
+
+        parse_result = &args[attr_data->link_watcher_attr];
+
+        if (parse_result->has)
+            *out_unrecognized_content = TRUE;
+
+        if (!nm_value_type_from_json(vt, attr_data->value_type, j_val, &parse_result->val))
+            *out_unrecognized_content = TRUE;
+        else
+            parse_result->has = TRUE;
+    }
+
+#define _PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(_parse_results, ...)                            \
+    ({                                                                                          \
+        int _i;                                                                                 \
+                                                                                                \
+        for (_i = 0; _i < (int) G_N_ELEMENTS((_parse_results)); _i++) {                         \
+            if ((_parse_results)[_i].has && !NM_IN_SET((LinkWatcherAttribute) _i, __VA_ARGS__)) \
+                break;                                                                          \
+        }                                                                                       \
+                                                                                                \
+        (_i == (int) G_N_ELEMENTS((_parse_results)));                                           \
+    })
+
+    v_name = _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_NAME);
+
+    if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
+        if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL))
+            *out_unrecognized_content = TRUE;
+        result = nm_team_link_watcher_new_ethtool(
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_DELAY_UP),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN),
+            NULL);
+    } else if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) {
+        if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING))
+            *out_unrecognized_content = TRUE;
+        result = nm_team_link_watcher_new_nsna_ping(
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INTERVAL),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
+            _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
+            NULL);
+    } else if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
+        NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE;
+
+        if (_PARSE_RESULT_HAS_UNEXPECTED_ATTRIBUTES(args,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING))
+            *out_unrecognized_content = TRUE;
+
+        if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE;
+        if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE;
+        if (_LINK_WATCHER_ATTR_GET_BOOL(args, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS;
+
+        result = nm_team_link_watcher_new_arp_ping2(
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_INTERVAL),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
+            _LINK_WATCHER_ATTR_GET_INT(args, LINK_WATCHER_ATTRIBUTE_VLANID),
+            _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
+            _LINK_WATCHER_ATTR_GET_STRING(args, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST),
+            v_flags,
+            NULL);
+    }
+
+    if (result)
+        return result;
 fail:
-	*out_unrecognized_content = TRUE;
-	return NULL;
+    *out_unrecognized_content = TRUE;
+    return NULL;
 }
-#endif
 
 /*****************************************************************************/
 
 static GVariant *
-_link_watcher_to_variant (const NMTeamLinkWatcher *link_watcher)
+_link_watcher_to_variant(const NMTeamLinkWatcher *link_watcher)
 {
-	NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)];
-	GVariantBuilder builder;
-	int i;
-
-	if (!link_watcher)
-		return NULL;
-
-	_link_watcher_unpack (link_watcher, args);
-
-	if (!args[LINK_WATCHER_ATTRIBUTE_NAME].has)
-		return NULL;
-
-	g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
-
-	for (i = 0; i < (int) G_N_ELEMENTS (link_watcher_attr_datas); i++) {
-		const NMValueTypUnioMaybe *p_val = &args[i];
-		const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i];
-		GVariant *v;
-
-		if (!p_val->has)
-			continue;
-		if (nm_value_type_equal (attr_data->value_type, &attr_data->default_val, &p_val->val))
-			continue;
-
-		if (attr_data->value_type == NM_VALUE_TYPE_INT)
-			v = g_variant_new_int32 (p_val->val.v_int);
-		else {
-			v = nm_value_type_to_variant (attr_data->value_type,
-			                              &p_val->val);
-		}
-		if (!v)
-			continue;
-
-		nm_assert (g_variant_is_floating (v));
-		g_variant_builder_add (&builder,
-		                       "{sv}",
-		                       attr_data->dbus_name,
-		                       v);
-	}
-
-	return g_variant_builder_end (&builder);
+    NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)];
+    GVariantBuilder     builder;
+    int                 i;
+
+    if (!link_watcher)
+        return NULL;
+
+    _link_watcher_unpack(link_watcher, args);
+
+    if (!args[LINK_WATCHER_ATTRIBUTE_NAME].has)
+        return NULL;
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
+
+    for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) {
+        const NMValueTypUnioMaybe *p_val     = &args[i];
+        const LinkWatcherAttrData *attr_data = &link_watcher_attr_datas[i];
+        GVariant *                 v;
+
+        if (!p_val->has)
+            continue;
+        if (nm_value_type_equal(attr_data->value_type, &attr_data->default_val, &p_val->val))
+            continue;
+
+        if (attr_data->value_type == NM_VALUE_TYPE_INT)
+            v = g_variant_new_int32(p_val->val.v_int);
+        else {
+            v = nm_value_type_to_variant(attr_data->value_type, &p_val->val);
+        }
+        if (!v)
+            continue;
+
+        nm_assert(g_variant_is_floating(v));
+        g_variant_builder_add(&builder, "{sv}", attr_data->dbus_name, v);
+    }
+
+    return g_variant_builder_end(&builder);
 }
 
-#define _LINK_WATCHER_ATTR_VARGET(variants, link_watcher_attribute, _value_type, c_type, _cmd) \
-	({ \
-		GVariant *const*_variants = (variants); \
-		GVariant *_cc; \
-		\
-		nm_assert (link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
-		\
-		  (_cc = _variants[(link_watcher_attribute)]) \
-		? (_cmd) \
-		: link_watcher_attr_datas[(link_watcher_attribute)].default_val.c_type; \
-	})
-#define _LINK_WATCHER_ATTR_VARGET_BOOL(variants, link_watcher_attribute)   (_LINK_WATCHER_ATTR_VARGET (variants, link_watcher_attribute, NM_VALUE_TYPE_BOOL,   v_bool,   g_variant_get_boolean (_cc)      ))
-#define _LINK_WATCHER_ATTR_VARGET_INT(variants, link_watcher_attribute)    (_LINK_WATCHER_ATTR_VARGET (variants, link_watcher_attribute, NM_VALUE_TYPE_INT,    v_int,    g_variant_get_int32 (_cc)        ))
-#define _LINK_WATCHER_ATTR_VARGET_STRING(variants, link_watcher_attribute) (_LINK_WATCHER_ATTR_VARGET (variants, link_watcher_attribute, NM_VALUE_TYPE_STRING, v_string, g_variant_get_string (_cc, NULL) ))
+#define _LINK_WATCHER_ATTR_VARGET(variants, link_watcher_attribute, _value_type, c_type, _cmd)    \
+    ({                                                                                            \
+        GVariant *const *_variants = (variants);                                                  \
+        GVariant *       _cc;                                                                     \
+                                                                                                  \
+        nm_assert(link_watcher_attr_datas[(link_watcher_attribute)].value_type == (_value_type)); \
+                                                                                                  \
+        (_cc = _variants[(link_watcher_attribute)])                                               \
+            ? (_cmd)                                                                              \
+            : link_watcher_attr_datas[(link_watcher_attribute)].default_val.c_type;               \
+    })
+#define _LINK_WATCHER_ATTR_VARGET_BOOL(variants, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_VARGET(variants,                                 \
+                               link_watcher_attribute,                   \
+                               NM_VALUE_TYPE_BOOL,                       \
+                               v_bool,                                   \
+                               g_variant_get_boolean(_cc)))
+#define _LINK_WATCHER_ATTR_VARGET_INT(variants, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_VARGET(variants,                                \
+                               link_watcher_attribute,                  \
+                               NM_VALUE_TYPE_INT,                       \
+                               v_int,                                   \
+                               g_variant_get_int32(_cc)))
+#define _LINK_WATCHER_ATTR_VARGET_STRING(variants, link_watcher_attribute) \
+    (_LINK_WATCHER_ATTR_VARGET(variants,                                   \
+                               link_watcher_attribute,                     \
+                               NM_VALUE_TYPE_STRING,                       \
+                               v_string,                                   \
+                               g_variant_get_string(_cc, NULL)))
 
 static void
-_variants_list_link_watcher_unref_auto (GVariant *(*p_variants)[])
+_variants_list_link_watcher_unref_auto(GVariant *(*p_variants)[])
 {
-	int i;
+    int i;
 
-	for (i = 0; i < (int) G_N_ELEMENTS (link_watcher_attr_datas); i++)
-		nm_g_variant_unref ((*p_variants)[i]);
+    for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++)
+        nm_g_variant_unref((*p_variants)[i]);
 }
 
 static NMTeamLinkWatcher *
-_link_watcher_from_variant (GVariant *watcher_var,
-                            gboolean strict_parsing,
-                            GError **error)
+_link_watcher_from_variant(GVariant *watcher_var, gboolean strict_parsing, GError **error)
 {
-	nm_auto (_variants_list_link_watcher_unref_auto) GVariant *variants[G_N_ELEMENTS (link_watcher_attr_datas)] = { NULL, };
-	const char *v_key;
-	GVariant *v_val;
-	const char *v_name;
-	GVariantIter iter;
-
-	g_return_val_if_fail (g_variant_is_of_type (watcher_var, G_VARIANT_TYPE ("a{sv}")), NULL);
-
-	g_variant_iter_init (&iter, watcher_var);
-	while (g_variant_iter_next (&iter, "{&sv}", &v_key, &v_val)) {
-		_nm_unused gs_unref_variant GVariant *v_val_free = v_val;
-		const LinkWatcherAttrData *attr_data = NULL;
-		const GVariantType *variant_type;
-		int i;
-
-		for (i = 0; i < (int) G_N_ELEMENTS (link_watcher_attr_datas); i++) {
-			if (nm_streq (link_watcher_attr_datas[i].dbus_name, v_key)) {
-				attr_data = &link_watcher_attr_datas[i];
-				break;
-			}
-		}
-		if (!attr_data) {
-			if (strict_parsing) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-				             _("invalid D-Bus property \"%s\""),
-				             v_key);
-				return NULL;
-			}
-			continue;
-		}
-
-		if (attr_data->value_type == NM_VALUE_TYPE_INT)
-			variant_type = G_VARIANT_TYPE_INT32;
-		else
-			variant_type = nm_value_type_get_variant_type (attr_data->value_type);
-
-		if (!g_variant_is_of_type (v_val, variant_type)) {
-			if (strict_parsing) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-				             _("invalid D-Bus property \"%s\""),
-				             v_key);
-				return NULL;
-			}
-			continue;
-		}
-
-		if (variants[attr_data->link_watcher_attr]) {
-			if (strict_parsing) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-				             _("duplicate D-Bus property \"%s\""),
-				             v_key);
-				return NULL;
-			}
-			g_variant_unref (variants[attr_data->link_watcher_attr]);
-		}
-		variants[attr_data->link_watcher_attr] = g_steal_pointer (&v_val_free);
-	}
-
-#define _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(_type, _variants, _error, ...) \
-	({ \
-		int _i; \
-		gboolean _has_error = FALSE; \
-		\
-		for (_i = 0; _i < (int) G_N_ELEMENTS ((_variants)); _i++) { \
-			if (   (_variants)[_i] \
-			    && !NM_IN_SET ((LinkWatcherAttribute) _i, __VA_ARGS__)) { \
-				_has_error = TRUE; \
-				g_set_error (_error, \
-				             NM_CONNECTION_ERROR, \
-				             NM_CONNECTION_ERROR_INVALID_PROPERTY, \
-				             _("invalid D-Bus property \"%s\" for \"%s\""), \
-				             link_watcher_attr_datas[_i].dbus_name, \
-				             _type); \
-				break; \
-			} \
-		} \
-		\
-		_has_error; \
-	})
-
-	v_name = _LINK_WATCHER_ATTR_VARGET_STRING (variants, LINK_WATCHER_ATTRIBUTE_NAME);
-
-	if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
-		if (   strict_parsing
-		    && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES (v_name, variants, error, _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL))
-			return NULL;
-		return nm_team_link_watcher_new_ethtool (_LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_DELAY_UP),
-		                                         _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN),
-		                                         strict_parsing ? error : NULL);
-	}
-
-	if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) {
-		if (   strict_parsing
-		    && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES (v_name, variants, error, _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING))
-			return NULL;
-		return nm_team_link_watcher_new_nsna_ping (_LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
-		                                           _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_INTERVAL),
-		                                           _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
-		                                           _LINK_WATCHER_ATTR_VARGET_STRING (variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
-		                                           strict_parsing ? error : NULL);
-	}
-
-	if (nm_streq0 (v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
-		NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE;
-
-		if (   strict_parsing
-		    && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES (v_name, variants, error, _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING))
-			return NULL;
-
-		if (_LINK_WATCHER_ATTR_VARGET_BOOL (variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE;
-		if (_LINK_WATCHER_ATTR_VARGET_BOOL (variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE;
-		if (_LINK_WATCHER_ATTR_VARGET_BOOL (variants, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS))
-			v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS;
-
-		return nm_team_link_watcher_new_arp_ping2 (_LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
-		                                           _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_INTERVAL),
-		                                           _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
-		                                           _LINK_WATCHER_ATTR_VARGET_INT (variants, LINK_WATCHER_ATTRIBUTE_VLANID),
-		                                           _LINK_WATCHER_ATTR_VARGET_STRING (variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
-		                                           _LINK_WATCHER_ATTR_VARGET_STRING (variants, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST),
-		                                           v_flags,
-		                                           strict_parsing ? error : NULL);
-	}
-
-	if (strict_parsing) {
-		g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("unknown link-watcher name \"%s\""),
-		             v_name);
-	}
-	return NULL;
+    nm_auto(_variants_list_link_watcher_unref_auto)
+        GVariant *variants[G_N_ELEMENTS(link_watcher_attr_datas)] = {
+            NULL,
+        };
+    const char * v_key;
+    GVariant *   v_val;
+    const char * v_name;
+    GVariantIter iter;
+
+    g_return_val_if_fail(g_variant_is_of_type(watcher_var, G_VARIANT_TYPE("a{sv}")), NULL);
+
+    g_variant_iter_init(&iter, watcher_var);
+    while (g_variant_iter_next(&iter, "{&sv}", &v_key, &v_val)) {
+        _nm_unused gs_unref_variant GVariant *v_val_free = v_val;
+        const LinkWatcherAttrData *           attr_data  = NULL;
+        const GVariantType *                  variant_type;
+        int                                   i;
+
+        for (i = 0; i < (int) G_N_ELEMENTS(link_watcher_attr_datas); i++) {
+            if (nm_streq(link_watcher_attr_datas[i].dbus_name, v_key)) {
+                attr_data = &link_watcher_attr_datas[i];
+                break;
+            }
+        }
+        if (!attr_data) {
+            if (strict_parsing) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("invalid D-Bus property \"%s\""),
+                            v_key);
+                return NULL;
+            }
+            continue;
+        }
+
+        if (attr_data->value_type == NM_VALUE_TYPE_INT)
+            variant_type = G_VARIANT_TYPE_INT32;
+        else
+            variant_type = nm_value_type_get_variant_type(attr_data->value_type);
+
+        if (!g_variant_is_of_type(v_val, variant_type)) {
+            if (strict_parsing) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("invalid D-Bus property \"%s\""),
+                            v_key);
+                return NULL;
+            }
+            continue;
+        }
+
+        if (variants[attr_data->link_watcher_attr]) {
+            if (strict_parsing) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("duplicate D-Bus property \"%s\""),
+                            v_key);
+                return NULL;
+            }
+            g_variant_unref(variants[attr_data->link_watcher_attr]);
+        }
+        variants[attr_data->link_watcher_attr] = g_steal_pointer(&v_val_free);
+    }
+
+#define _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(_type, _variants, _error, ...)              \
+    ({                                                                                   \
+        int      _i;                                                                     \
+        gboolean _has_error = FALSE;                                                     \
+                                                                                         \
+        for (_i = 0; _i < (int) G_N_ELEMENTS((_variants)); _i++) {                       \
+            if ((_variants)[_i] && !NM_IN_SET((LinkWatcherAttribute) _i, __VA_ARGS__)) { \
+                _has_error = TRUE;                                                       \
+                g_set_error(_error,                                                      \
+                            NM_CONNECTION_ERROR,                                         \
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,                        \
+                            _("invalid D-Bus property \"%s\" for \"%s\""),               \
+                            link_watcher_attr_datas[_i].dbus_name,                       \
+                            _type);                                                      \
+                break;                                                                   \
+            }                                                                            \
+        }                                                                                \
+                                                                                         \
+        _has_error;                                                                      \
+    })
+
+    v_name = _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_NAME);
+
+    if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ETHTOOL)) {
+        if (strict_parsing
+            && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name,
+                                                    variants,
+                                                    error,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_ETHTOOL))
+            return NULL;
+        return nm_team_link_watcher_new_ethtool(
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_DELAY_UP),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_DELAY_DOWN),
+            strict_parsing ? error : NULL);
+    }
+
+    if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_NSNA_PING)) {
+        if (strict_parsing
+            && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name,
+                                                    variants,
+                                                    error,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_NSNA_PING))
+            return NULL;
+        return nm_team_link_watcher_new_nsna_ping(
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INTERVAL),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
+            _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
+            strict_parsing ? error : NULL);
+    }
+
+    if (nm_streq0(v_name, NM_TEAM_LINK_WATCHER_ARP_PING)) {
+        NMTeamLinkWatcherArpPingFlags v_flags = NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE;
+
+        if (strict_parsing
+            && _VARIANTS_HAVE_UNEXPECTED_ATTRIBUTES(v_name,
+                                                    variants,
+                                                    error,
+                                                    _EXPECTED_LINK_WATCHER_ATTRIBUTES_ARP_PING))
+            return NULL;
+
+        if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_ACTIVE))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_ACTIVE;
+        if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_VALIDATE_INACTIVE))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_VALIDATE_INACTIVE;
+        if (_LINK_WATCHER_ATTR_VARGET_BOOL(variants, LINK_WATCHER_ATTRIBUTE_SEND_ALWAYS))
+            v_flags |= NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_SEND_ALWAYS;
+
+        return nm_team_link_watcher_new_arp_ping2(
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INIT_WAIT),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_INTERVAL),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_MISSED_MAX),
+            _LINK_WATCHER_ATTR_VARGET_INT(variants, LINK_WATCHER_ATTRIBUTE_VLANID),
+            _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_TARGET_HOST),
+            _LINK_WATCHER_ATTR_VARGET_STRING(variants, LINK_WATCHER_ATTRIBUTE_SOURCE_HOST),
+            v_flags,
+            strict_parsing ? error : NULL);
+    }
+
+    if (strict_parsing) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("unknown link-watcher name \"%s\""),
+                    v_name);
+    }
+    return NULL;
 }
 
 /*****************************************************************************/
@@ -1444,20 +1669,20 @@ _link_watcher_from_variant (GVariant *watcher_var,
  * Returns: (transfer full): a new floating #GVariant representing link watchers.
  **/
 GVariant *
-_nm_utils_team_link_watchers_to_variant (const GPtrArray *link_watchers)
+_nm_utils_team_link_watchers_to_variant(const GPtrArray *link_watchers)
 {
-	GVariantBuilder builder;
-	guint i;
-
-	g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
-	if (link_watchers) {
-		for (i = 0; i < link_watchers->len; i++) {
-			g_variant_builder_add (&builder,
-			                       "@a{sv}",
-			                       _link_watcher_to_variant (link_watchers->pdata[i]));
-		}
-	}
-	return g_variant_builder_end (&builder);
+    GVariantBuilder builder;
+    guint           i;
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
+    if (link_watchers) {
+        for (i = 0; i < link_watchers->len; i++) {
+            g_variant_builder_add(&builder,
+                                  "@a{sv}",
+                                  _link_watcher_to_variant(link_watchers->pdata[i]));
+        }
+    }
+    return g_variant_builder_end(&builder);
 }
 
 /**
@@ -1477,1078 +1702,1166 @@ _nm_utils_team_link_watchers_to_variant (const GPtrArray *link_watchers)
  * never returns %NULL.
  **/
 GPtrArray *
-_nm_utils_team_link_watchers_from_variant (GVariant *value,
-                                           gboolean strict_parsing,
-                                           GError **error)
+_nm_utils_team_link_watchers_from_variant(GVariant *value, gboolean strict_parsing, GError **error)
 {
-	gs_unref_ptrarray GPtrArray *link_watchers = NULL;
-	GVariantIter iter;
-	GVariant *watcher_var;
+    gs_unref_ptrarray GPtrArray *link_watchers = NULL;
+    GVariantIter                 iter;
+    GVariant *                   watcher_var;
 
-	g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), NULL);
+    g_return_val_if_fail(g_variant_is_of_type(value, G_VARIANT_TYPE("aa{sv}")), NULL);
 
-	link_watchers = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref);
+    link_watchers = g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref);
 
-	g_variant_iter_init (&iter, value);
-	while (g_variant_iter_next (&iter, "@a{sv}", &watcher_var)) {
-		_nm_unused gs_unref_variant GVariant *watcher_var_free = watcher_var;
-		NMTeamLinkWatcher *watcher;
+    g_variant_iter_init(&iter, value);
+    while (g_variant_iter_next(&iter, "@a{sv}", &watcher_var)) {
+        _nm_unused gs_unref_variant GVariant *watcher_var_free = watcher_var;
+        NMTeamLinkWatcher *                   watcher;
 
-		watcher = _link_watcher_from_variant (watcher_var, strict_parsing, error);
-		if (error && *error)
-			return NULL;
-		if (watcher)
-			g_ptr_array_add (link_watchers, watcher);
-	}
+        watcher = _link_watcher_from_variant(watcher_var, strict_parsing, error);
+        if (error && *error)
+            return NULL;
+        if (watcher)
+            g_ptr_array_add(link_watchers, watcher);
+    }
 
-	return g_steal_pointer (&link_watchers);
+    return g_steal_pointer(&link_watchers);
 }
 
 /*****************************************************************************/
 
 const char *
-nm_team_setting_config_get (const NMTeamSetting *self)
+nm_team_setting_config_get(const NMTeamSetting *self)
 {
-	char *js_str;
-
-	nm_assert (self);
-
-	if (G_LIKELY (!self->d._js_str_need_synthetize))
-		return self->d._js_str;
-
-	nm_assert (!self->d._js_str);
-	nm_assert (self->d.strict_validated);
-
-	if (_team_setting_check_default (self) == 0) {
-		/* the default is set. We signal this as a NULL JSON string.
-		 * Nothing to do. */
-		js_str = NULL;
-	} else {
-		gboolean list_is_empty = TRUE;
-		GString *gstr;
-
-		gstr = g_string_new (NULL);
-
-		g_string_append (gstr, "{ ");
-
-		if (self->d.is_port) {
-			static const NMTeamAttribute attr_lst_port[] = {
-				NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID,
-				NM_TEAM_ATTRIBUTE_PORT_PRIO,
-				NM_TEAM_ATTRIBUTE_PORT_STICKY,
-				NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
-				NM_TEAM_ATTRIBUTE_PORT_LACP_KEY,
-			};
-
-			if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty, attr_lst_port, G_N_ELEMENTS (attr_lst_port)))
-				list_is_empty = FALSE;
-		} else {
-			static const NMTeamAttribute attr_lst_runner_pt1[] = {
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
-			};
-			static const NMTeamAttribute attr_lst_runner_pt2[] = {
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
-			};
-			static const NMTeamAttribute attr_lst_runner_pt3[] = {
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
-				NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
-			};
-			static const NMTeamAttribute attr_lst_notify_peers[] = {
-				NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,
-				NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,
-			};
-			static const NMTeamAttribute attr_lst_mcast_rejoin[] = {
-				NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,
-				NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,
-			};
-
-			if (   _team_setting_has_fields_any_v (self, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1))
-			    || _team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))
-			    || _team_setting_has_fields_any_v (self, attr_lst_runner_pt3, G_N_ELEMENTS (attr_lst_runner_pt3))) {
-				gboolean list_is_empty2 = TRUE;
-
-				nm_assert (list_is_empty);
-
-				nm_json_aux_gstr_append_obj_name (gstr, "runner", '{');
-
-				if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1)))
-					list_is_empty2 = FALSE;
-
-				if (_team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))) {
-					if (!list_is_empty2)
-						nm_json_aux_gstr_append_delimiter (gstr);
-					nm_json_aux_gstr_append_obj_name (gstr, "tx_balancer", '{');
-					if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2)))
-						nm_assert_not_reached ();
-					g_string_append (gstr, " }");
-					list_is_empty2 = FALSE;
-				}
-
-				if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt3, G_N_ELEMENTS (attr_lst_runner_pt3)))
-					list_is_empty2 = FALSE;
-
-				nm_assert (!list_is_empty2);
-				g_string_append (gstr, " }");
-				list_is_empty = FALSE;
-			}
-
-			if (_team_setting_has_fields_any_v (self, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers))) {
-				if (!list_is_empty)
-					nm_json_aux_gstr_append_delimiter (gstr);
-				nm_json_aux_gstr_append_obj_name (gstr, "notify_peers", '{');
-				if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers)))
-					nm_assert_not_reached ();
-				g_string_append (gstr, " }");
-				list_is_empty = FALSE;
-			}
-
-			if (_team_setting_has_fields_any_v (self, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin))) {
-				if (!list_is_empty)
-					nm_json_aux_gstr_append_delimiter (gstr);
-				nm_json_aux_gstr_append_obj_name (gstr, "mcast_rejoin", '{');
-				if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin)))
-					nm_assert_not_reached ();
-				g_string_append (gstr, " }");
-				list_is_empty = FALSE;
-			}
-		}
-
-		if (_team_setting_field_to_json (self,
-		                                 gstr,
-		                                 !list_is_empty,
-		                                 _team_attr_data_get (self->d.is_port, NM_TEAM_ATTRIBUTE_LINK_WATCHERS)))
-			list_is_empty = FALSE;
-
-		if (!list_is_empty)
-			g_string_append (gstr, " }");
-
-		js_str = g_string_free (gstr, list_is_empty);;
-	}
-
-	/* mutate the constant object. In C++ speak, these fields are "mutable".
-	 * That is because we construct the JSON string lazily/on-demand. */
-	*((char **) &self->_data_priv._js_str) = js_str;
-	*((bool *) &self->_data_priv._js_str_need_synthetize) = FALSE;
-
-	return self->d._js_str;
+    char *js_str;
+
+    nm_assert(self);
+
+    if (G_LIKELY(!self->d._js_str_need_synthetize))
+        return self->d._js_str;
+
+    nm_assert(!self->d._js_str);
+    nm_assert(self->d.strict_validated);
+
+    if (_team_setting_check_default(self) == 0) {
+        /* the default is set. We signal this as a NULL JSON string.
+         * Nothing to do. */
+        js_str = NULL;
+    } else {
+        gboolean list_is_empty = TRUE;
+        GString *gstr;
+
+        gstr = g_string_new(NULL);
+
+        g_string_append(gstr, "{ ");
+
+        if (self->d.is_port) {
+            static const NMTeamAttribute attr_lst_port[] = {
+                NM_TEAM_ATTRIBUTE_PORT_QUEUE_ID,
+                NM_TEAM_ATTRIBUTE_PORT_PRIO,
+                NM_TEAM_ATTRIBUTE_PORT_STICKY,
+                NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
+                NM_TEAM_ATTRIBUTE_PORT_LACP_KEY,
+            };
+
+            if (_team_setting_fields_to_json_maybe(self,
+                                                   gstr,
+                                                   !list_is_empty,
+                                                   attr_lst_port,
+                                                   G_N_ELEMENTS(attr_lst_port)))
+                list_is_empty = FALSE;
+        } else {
+            static const NMTeamAttribute attr_lst_runner_pt1[] = {
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_HWADDR_POLICY,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH,
+            };
+            static const NMTeamAttribute attr_lst_runner_pt2[] = {
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_BALANCER_INTERVAL,
+            };
+            static const NMTeamAttribute attr_lst_runner_pt3[] = {
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_ACTIVE,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_FAST_RATE,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_SYS_PRIO,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_MIN_PORTS,
+                NM_TEAM_ATTRIBUTE_MASTER_RUNNER_AGG_SELECT_POLICY,
+            };
+            static const NMTeamAttribute attr_lst_notify_peers[] = {
+                NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_COUNT,
+                NM_TEAM_ATTRIBUTE_MASTER_NOTIFY_PEERS_INTERVAL,
+            };
+            static const NMTeamAttribute attr_lst_mcast_rejoin[] = {
+                NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_COUNT,
+                NM_TEAM_ATTRIBUTE_MASTER_MCAST_REJOIN_INTERVAL,
+            };
+
+            if (_team_setting_has_fields_any_v(self,
+                                               attr_lst_runner_pt1,
+                                               G_N_ELEMENTS(attr_lst_runner_pt1))
+                || _team_setting_has_fields_any_v(self,
+                                                  attr_lst_runner_pt2,
+                                                  G_N_ELEMENTS(attr_lst_runner_pt2))
+                || _team_setting_has_fields_any_v(self,
+                                                  attr_lst_runner_pt3,
+                                                  G_N_ELEMENTS(attr_lst_runner_pt3))) {
+                gboolean list_is_empty2 = TRUE;
+
+                nm_assert(list_is_empty);
+
+                nm_json_gstr_append_obj_name(gstr, "runner", '{');
+
+                if (_team_setting_fields_to_json_maybe(self,
+                                                       gstr,
+                                                       !list_is_empty2,
+                                                       attr_lst_runner_pt1,
+                                                       G_N_ELEMENTS(attr_lst_runner_pt1)))
+                    list_is_empty2 = FALSE;
+
+                if (_team_setting_has_fields_any_v(self,
+                                                   attr_lst_runner_pt2,
+                                                   G_N_ELEMENTS(attr_lst_runner_pt2))) {
+                    if (!list_is_empty2)
+                        nm_json_gstr_append_delimiter(gstr);
+                    nm_json_gstr_append_obj_name(gstr, "tx_balancer", '{');
+                    if (!_team_setting_fields_to_json_maybe(self,
+                                                            gstr,
+                                                            FALSE,
+                                                            attr_lst_runner_pt2,
+                                                            G_N_ELEMENTS(attr_lst_runner_pt2)))
+                        nm_assert_not_reached();
+                    g_string_append(gstr, " }");
+                    list_is_empty2 = FALSE;
+                }
+
+                if (_team_setting_fields_to_json_maybe(self,
+                                                       gstr,
+                                                       !list_is_empty2,
+                                                       attr_lst_runner_pt3,
+                                                       G_N_ELEMENTS(attr_lst_runner_pt3)))
+                    list_is_empty2 = FALSE;
+
+                nm_assert(!list_is_empty2);
+                g_string_append(gstr, " }");
+                list_is_empty = FALSE;
+            }
+
+            if (_team_setting_has_fields_any_v(self,
+                                               attr_lst_notify_peers,
+                                               G_N_ELEMENTS(attr_lst_notify_peers))) {
+                if (!list_is_empty)
+                    nm_json_gstr_append_delimiter(gstr);
+                nm_json_gstr_append_obj_name(gstr, "notify_peers", '{');
+                if (!_team_setting_fields_to_json_maybe(self,
+                                                        gstr,
+                                                        FALSE,
+                                                        attr_lst_notify_peers,
+                                                        G_N_ELEMENTS(attr_lst_notify_peers)))
+                    nm_assert_not_reached();
+                g_string_append(gstr, " }");
+                list_is_empty = FALSE;
+            }
+
+            if (_team_setting_has_fields_any_v(self,
+                                               attr_lst_mcast_rejoin,
+                                               G_N_ELEMENTS(attr_lst_mcast_rejoin))) {
+                if (!list_is_empty)
+                    nm_json_gstr_append_delimiter(gstr);
+                nm_json_gstr_append_obj_name(gstr, "mcast_rejoin", '{');
+                if (!_team_setting_fields_to_json_maybe(self,
+                                                        gstr,
+                                                        FALSE,
+                                                        attr_lst_mcast_rejoin,
+                                                        G_N_ELEMENTS(attr_lst_mcast_rejoin)))
+                    nm_assert_not_reached();
+                g_string_append(gstr, " }");
+                list_is_empty = FALSE;
+            }
+        }
+
+        if (_team_setting_field_to_json(
+                self,
+                gstr,
+                !list_is_empty,
+                _team_attr_data_get(self->d.is_port, NM_TEAM_ATTRIBUTE_LINK_WATCHERS)))
+            list_is_empty = FALSE;
+
+        if (!list_is_empty)
+            g_string_append(gstr, " }");
+
+        js_str = g_string_free(gstr, list_is_empty);
+    }
+
+    /* mutate the constant object. In C++ speak, these fields are "mutable".
+     * That is because we construct the JSON string lazily/on-demand. */
+    *((char **) &self->_data_priv._js_str)                = js_str;
+    *((bool *) &self->_data_priv._js_str_need_synthetize) = FALSE;
+
+    return self->d._js_str;
 }
 
 /*****************************************************************************/
 
-#if WITH_JSON_VALIDATION
 static gboolean
-_attr_data_match_keys (const TeamAttrData *attr_data,
-                       const char *const*keys,
-                       guint8 n_keys)
+_attr_data_match_keys(const TeamAttrData *attr_data, const char *const *keys, guint8 n_keys)
 {
-	guint8 i;
-
-	_team_attr_data_ASSERT (attr_data);
-	nm_assert (keys);
-	nm_assert (n_keys > 0);
-	nm_assert (({
-		gboolean all_non_null = TRUE;
-
-		for (i = 0; i < n_keys; i++)
-			all_non_null = all_non_null && keys[i] && keys[i][0] != '\0';
-		all_non_null;
-	}));
-
-	if (attr_data->js_keys_len < n_keys)
-		return FALSE;
-	for (i = 0; i < n_keys; i++) {
-		if (!nm_streq (keys[i], attr_data->js_keys[i]))
-			return FALSE;
-	}
-	return TRUE;
+    guint8 i;
+
+    _team_attr_data_ASSERT(attr_data);
+    nm_assert(keys);
+    nm_assert(n_keys > 0);
+    nm_assert(({
+        gboolean all_non_null = TRUE;
+
+        for (i = 0; i < n_keys; i++)
+            all_non_null = all_non_null && keys[i] && keys[i][0] != '\0';
+        all_non_null;
+    }));
+
+    if (attr_data->js_keys_len < n_keys)
+        return FALSE;
+    for (i = 0; i < n_keys; i++) {
+        if (!nm_streq(keys[i], attr_data->js_keys[i]))
+            return FALSE;
+    }
+    return TRUE;
 }
 
 static const TeamAttrData *
-_attr_data_find_by_json_key (gboolean is_port,
-                             const char *const*keys,
-                             guint8 n_keys)
+_attr_data_find_by_json_key(gboolean is_port, const char *const *keys, guint8 n_keys)
 {
-	const TeamAttrData *attr_data;
+    const TeamAttrData *attr_data;
 
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		if (    _team_attr_data_is_relevant (attr_data, is_port)
-		    && _attr_data_match_keys (attr_data, keys, n_keys))
-			return attr_data;
-	}
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        if (_team_attr_data_is_relevant(attr_data, is_port)
+            && _attr_data_match_keys(attr_data, keys, n_keys))
+            return attr_data;
+    }
 
-	return NULL;
+    return NULL;
 }
 
 static void
-_js_parse_locate_keys (NMTeamSetting *self,
-                       json_t *root_js_obj,
-                       json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
-                       gboolean *out_unrecognized_content)
+_js_parse_locate_keys(const NMJsonVt *vt,
+                      NMTeamSetting * self,
+                      nm_json_t *     root_js_obj,
+                      nm_json_t *     found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
+                      gboolean *      out_unrecognized_content)
 {
-	const char *keys[3];
-	const char *cur_key1;
-	const char *cur_key2;
-	const char *cur_key3;
-	json_t *cur_val1;
-	json_t *cur_val2;
-	json_t *cur_val3;
-
-#define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content) \
-	({ \
-		const TeamAttrData *_attr_data; \
-		gboolean _handled = FALSE; \
-		\
-		(_keys)[(_level) - 1] = (_cur_key); \
-		_attr_data = _attr_data_find_by_json_key ((_self)->d.is_port, (_keys), (_level)); \
-		if (   _attr_data \
-			&& _attr_data->js_keys_len == (_level)) { \
-			if ((_found_keys)[_attr_data->team_attr]) \
-				*(_out_unrecognized_content) = TRUE; \
-			(_found_keys)[_attr_data->team_attr] = (_cur_val); \
-			_handled = TRUE; \
-		} else if (   !_attr_data \
-		           || !json_is_object ((_cur_val))) { \
-			*(_out_unrecognized_content) = TRUE; \
-			_handled = TRUE; \
-		} \
-		_handled; \
-	})
-
-	json_object_foreach (root_js_obj, cur_key1, cur_val1) {
-		if (!_handle (self, cur_key1, cur_val1, keys, 1, found_keys, out_unrecognized_content)) {
-			json_object_foreach (cur_val1, cur_key2, cur_val2) {
-				if (!_handle (self, cur_key2, cur_val2, keys, 2, found_keys, out_unrecognized_content)) {
-					json_object_foreach (cur_val2, cur_key3, cur_val3) {
-						if (!_handle (self, cur_key3, cur_val3, keys, 3, found_keys, out_unrecognized_content))
-							*out_unrecognized_content = TRUE;
-					}
-				}
-			}
-		}
-	}
+    const char *keys[3];
+    const char *cur_key1;
+    const char *cur_key2;
+    const char *cur_key3;
+    nm_json_t * cur_val1;
+    nm_json_t * cur_val2;
+    nm_json_t * cur_val3;
+
+    nm_assert(vt);
+
+#define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content)  \
+    ({                                                                                             \
+        const TeamAttrData *_attr_data;                                                            \
+        gboolean            _handled = FALSE;                                                      \
+                                                                                                   \
+        (_keys)[(_level) -1] = (_cur_key);                                                         \
+        _attr_data           = _attr_data_find_by_json_key((_self)->d.is_port, (_keys), (_level)); \
+        if (_attr_data && _attr_data->js_keys_len == (_level)) {                                   \
+            if ((_found_keys)[_attr_data->team_attr])                                              \
+                *(_out_unrecognized_content) = TRUE;                                               \
+            (_found_keys)[_attr_data->team_attr] = (_cur_val);                                     \
+            _handled                             = TRUE;                                           \
+        } else if (!_attr_data || !nm_json_is_object((_cur_val))) {                                \
+            *(_out_unrecognized_content) = TRUE;                                                   \
+            _handled                     = TRUE;                                                   \
+        }                                                                                          \
+        _handled;                                                                                  \
+    })
+
+    nm_json_object_foreach (vt, root_js_obj, cur_key1, cur_val1) {
+        if (!_handle(self, cur_key1, cur_val1, keys, 1, found_keys, out_unrecognized_content)) {
+            nm_json_object_foreach (vt, cur_val1, cur_key2, cur_val2) {
+                if (!_handle(self,
+                             cur_key2,
+                             cur_val2,
+                             keys,
+                             2,
+                             found_keys,
+                             out_unrecognized_content)) {
+                    nm_json_object_foreach (vt, cur_val2, cur_key3, cur_val3) {
+                        if (!_handle(self,
+                                     cur_key3,
+                                     cur_val3,
+                                     keys,
+                                     3,
+                                     found_keys,
+                                     out_unrecognized_content))
+                            *out_unrecognized_content = TRUE;
+                    }
+                }
+            }
+        }
+    }
 
 #undef _handle
 }
 
 static void
-_js_parse_unpack (gboolean is_port,
-                  json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
-                  bool out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM],
-                  NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM],
-                  gboolean *out_unrecognized_content,
-                  GPtrArray **out_ptr_array_link_watchers_free,
-                  GPtrArray **out_ptr_array_master_runner_tx_hash_free)
+_js_parse_unpack(const NMJsonVt *vt,
+                 gboolean        is_port,
+                 nm_json_t *     found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
+                 bool            out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM],
+                 NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM],
+                 gboolean *      out_unrecognized_content,
+                 GPtrArray **    out_ptr_array_link_watchers_free,
+                 GPtrArray **    out_ptr_array_master_runner_tx_hash_free)
 {
-	const TeamAttrData *attr_data;
-
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		NMValueTypUnion *p_out_val;
-		gboolean valid = FALSE;
-		json_t *arg_js_obj;
-
-		if (!_team_attr_data_is_relevant (attr_data, is_port))
-			continue;
-
-		nm_assert (!out_has_lst[attr_data->team_attr]);
-
-		arg_js_obj = found_keys[attr_data->team_attr];
-		if (!arg_js_obj)
-			continue;
-
-		p_out_val = &out_val_lst[attr_data->team_attr];
-
-		if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
-			valid = nm_value_type_from_json (attr_data->value_type, arg_js_obj, p_out_val);
-		else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
-			GPtrArray *link_watchers = NULL;
-			NMTeamLinkWatcher *link_watcher;
-
-			nm_assert (out_ptr_array_link_watchers_free && !*out_ptr_array_link_watchers_free);
-			if (json_is_array (arg_js_obj)) {
-				gsize i, len;
-
-				len = json_array_size (arg_js_obj);
-				link_watchers = g_ptr_array_new_full (len, (GDestroyNotify) nm_team_link_watcher_unref);
-				for (i = 0; i < len; i++) {
-					link_watcher = _link_watcher_from_json (json_array_get (arg_js_obj, i),
-					                                        out_unrecognized_content);
-					if (link_watcher)
-						g_ptr_array_add (link_watchers, link_watcher);
-				}
-			} else {
-				link_watcher = _link_watcher_from_json (arg_js_obj,
-				                                        out_unrecognized_content);
-				if (link_watcher) {
-					link_watchers = g_ptr_array_new_full (1, (GDestroyNotify) nm_team_link_watcher_unref);
-					g_ptr_array_add (link_watchers, link_watcher);
-				}
-			}
-			if (link_watchers) {
-				valid = TRUE;
-				p_out_val->v_ptrarray = link_watchers;
-				*out_ptr_array_link_watchers_free = link_watchers;
-			}
-		} else if (   !is_port
-		           && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-			GPtrArray *strv = NULL;
-
-			nm_assert (out_ptr_array_master_runner_tx_hash_free && !*out_ptr_array_master_runner_tx_hash_free);
-			if (json_is_array (arg_js_obj)) {
-				gsize i, len;
-
-				len = json_array_size (arg_js_obj);
-				if (len > 0) {
-					strv = g_ptr_array_sized_new (len);
-					for (i = 0; i < len; i++) {
-						const char *v_string;
-
-						if (   nm_jansson_json_as_string (json_array_get (arg_js_obj, i),
-						                                  &v_string) <= 0
-						    || !v_string
-						    || v_string[0] == '\0') {
-							/* we remember that there was some invalid content, but parts of the
-							 * list could still be parsed. */
-							*out_unrecognized_content = TRUE;
-							continue;
-						}
-						g_ptr_array_add (strv, (char *) v_string);
-					}
-				}
-				valid = TRUE;
-				*out_ptr_array_master_runner_tx_hash_free = strv;
-			}
-			p_out_val->v_ptrarray = strv;
-		} else
-			nm_assert_not_reached ();
-
-		out_has_lst[attr_data->team_attr] = valid;
-		if (!valid)
-			*out_unrecognized_content = TRUE;
-	}
+    const TeamAttrData *attr_data;
+
+    nm_assert(vt);
+
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        NMValueTypUnion *p_out_val;
+        gboolean         valid = FALSE;
+        nm_json_t *      arg_js_obj;
+
+        if (!_team_attr_data_is_relevant(attr_data, is_port))
+            continue;
+
+        nm_assert(!out_has_lst[attr_data->team_attr]);
+
+        arg_js_obj = found_keys[attr_data->team_attr];
+        if (!arg_js_obj)
+            continue;
+
+        p_out_val = &out_val_lst[attr_data->team_attr];
+
+        if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
+            valid = nm_value_type_from_json(vt, attr_data->value_type, arg_js_obj, p_out_val);
+        else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
+            GPtrArray *        link_watchers = NULL;
+            NMTeamLinkWatcher *link_watcher;
+
+            nm_assert(out_ptr_array_link_watchers_free && !*out_ptr_array_link_watchers_free);
+            if (nm_json_is_array(arg_js_obj)) {
+                gsize i, len;
+
+                len = vt->nm_json_array_size(arg_js_obj);
+                link_watchers =
+                    g_ptr_array_new_full(len, (GDestroyNotify) nm_team_link_watcher_unref);
+                for (i = 0; i < len; i++) {
+                    link_watcher = _link_watcher_from_json(vt,
+                                                           vt->nm_json_array_get(arg_js_obj, i),
+                                                           out_unrecognized_content);
+                    if (link_watcher)
+                        g_ptr_array_add(link_watchers, link_watcher);
+                }
+            } else {
+                link_watcher = _link_watcher_from_json(vt, arg_js_obj, out_unrecognized_content);
+                if (link_watcher) {
+                    link_watchers =
+                        g_ptr_array_new_full(1, (GDestroyNotify) nm_team_link_watcher_unref);
+                    g_ptr_array_add(link_watchers, link_watcher);
+                }
+            }
+            if (link_watchers) {
+                valid                             = TRUE;
+                p_out_val->v_ptrarray             = link_watchers;
+                *out_ptr_array_link_watchers_free = link_watchers;
+            }
+        } else if (!is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+            GPtrArray *strv = NULL;
+
+            nm_assert(out_ptr_array_master_runner_tx_hash_free
+                      && !*out_ptr_array_master_runner_tx_hash_free);
+            if (nm_json_is_array(arg_js_obj)) {
+                gsize i, len;
+
+                len = vt->nm_json_array_size(arg_js_obj);
+                if (len > 0) {
+                    strv = g_ptr_array_sized_new(len);
+                    for (i = 0; i < len; i++) {
+                        const char *v_string;
+
+                        if (nm_jansson_json_as_string(vt,
+                                                      vt->nm_json_array_get(arg_js_obj, i),
+                                                      &v_string)
+                                <= 0
+                            || !v_string || v_string[0] == '\0') {
+                            /* we remember that there was some invalid content, but parts of the
+                             * list could still be parsed. */
+                            *out_unrecognized_content = TRUE;
+                            continue;
+                        }
+                        g_ptr_array_add(strv, (char *) v_string);
+                    }
+                }
+                valid                                     = TRUE;
+                *out_ptr_array_master_runner_tx_hash_free = strv;
+            }
+            p_out_val->v_ptrarray = strv;
+        } else
+            nm_assert_not_reached();
+
+        out_has_lst[attr_data->team_attr] = valid;
+        if (!valid)
+            *out_unrecognized_content = TRUE;
+    }
 }
-#endif
 
 guint32
-nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
+nm_team_setting_config_set(NMTeamSetting *self, const char *js_str)
 {
-	guint32 changed_flags = 0;
-	gboolean do_set_default = TRUE;
-	gboolean new_js_str_invalid = FALSE;
-
-	_team_setting_ASSERT (self);
-
-	if (   !js_str
-	    || js_str[0] == '\0') {
-		changed_flags = _team_setting_set_default (self);
-		if (   changed_flags != 0
-		    || !nm_streq0 (js_str, self->d._js_str))
-			changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-		nm_clear_g_free ((char **) &self->_data_priv._js_str);
-		self->_data_priv._js_str = g_strdup (js_str);
-		self->_data_priv._js_str_need_synthetize = FALSE;
-		self->_data_priv.strict_validated = TRUE;
-		self->_data_priv.js_str_invalid = FALSE;
-		return changed_flags;
-	}
-
-	if (   self->d._js_str
-	    && nm_streq (js_str, self->d._js_str)) {
-	    if (!self->d.strict_validated) {
-			/* setting the same JSON string twice in a row has no effect. */
-			return 0;
-		}
-	} else
-		changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-
-#if WITH_JSON_VALIDATION
-	{
-		nm_auto_decref_json json_t *root_js_obj = NULL;
-
-		if (nm_jansson_load ())
-			root_js_obj = json_loads (js_str, 0, NULL);
-
-		if (   !root_js_obj
-		    || !json_is_object (root_js_obj))
-			new_js_str_invalid = TRUE;
-		else {
-			gboolean unrecognized_content = FALSE;
-			bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { FALSE, };
-			NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM];
-			json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
-			gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL;
-			gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL;
-
-			_js_parse_locate_keys (self,
-			                       root_js_obj,
-			                       found_keys,
-			                       &unrecognized_content);
-
-			_js_parse_unpack (self->d.is_port,
-			                  found_keys,
-			                  has_lst,
-			                  val_lst,
-			                  &unrecognized_content,
-			                  &ptr_array_link_watchers_free,
-			                  &ptr_array_master_runner_tx_hash_free);
-
-			do_set_default = FALSE;
-
-			changed_flags |= _team_setting_set (self,
-			                                    TRUE,
-			                                    has_lst,
-			                                    val_lst);
-		}
-	}
-
-#endif
-
-	if (do_set_default)
-		changed_flags |= _team_setting_set_default (self);
-
-	self->_data_priv.strict_validated = FALSE;
-	self->_data_priv._js_str_need_synthetize = FALSE;
-	self->_data_priv.js_str_invalid = new_js_str_invalid;
-	g_free ((char *) self->_data_priv._js_str);
-	self->_data_priv._js_str = g_strdup (js_str);
-
-	return changed_flags;
+    const NMJsonVt *vt;
+    guint32         changed_flags      = 0;
+    gboolean        do_set_default     = TRUE;
+    gboolean        new_js_str_invalid = FALSE;
+
+    _team_setting_ASSERT(self);
+
+    if (!js_str || js_str[0] == '\0') {
+        changed_flags = _team_setting_set_default(self);
+        if (changed_flags != 0 || !nm_streq0(js_str, self->d._js_str))
+            changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+        nm_clear_g_free((char **) &self->_data_priv._js_str);
+        self->_data_priv._js_str                 = g_strdup(js_str);
+        self->_data_priv._js_str_need_synthetize = FALSE;
+        self->_data_priv.strict_validated        = TRUE;
+        self->_data_priv.js_str_invalid          = FALSE;
+        return changed_flags;
+    }
+
+    if (self->d._js_str && nm_streq(js_str, self->d._js_str)) {
+        if (!self->d.strict_validated) {
+            /* setting the same JSON string twice in a row has no effect. */
+            return 0;
+        }
+    } else
+        changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+
+    if ((vt = nm_json_vt())) {
+        nm_auto_decref_json nm_json_t *root_js_obj = NULL;
+
+        root_js_obj = vt->nm_json_loads(js_str, 0, NULL);
+        if (!root_js_obj || !nm_json_is_object(root_js_obj))
+            new_js_str_invalid = TRUE;
+        else {
+            gboolean unrecognized_content            = FALSE;
+            bool     has_lst[_NM_TEAM_ATTRIBUTE_NUM] = {
+                FALSE,
+            };
+            NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM];
+            nm_json_t *     found_keys[_NM_TEAM_ATTRIBUTE_NUM] = {
+                NULL,
+            };
+            gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL;
+            gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free         = NULL;
+
+            _js_parse_locate_keys(vt, self, root_js_obj, found_keys, &unrecognized_content);
+
+            _js_parse_unpack(vt,
+                             self->d.is_port,
+                             found_keys,
+                             has_lst,
+                             val_lst,
+                             &unrecognized_content,
+                             &ptr_array_link_watchers_free,
+                             &ptr_array_master_runner_tx_hash_free);
+
+            do_set_default = FALSE;
+
+            changed_flags |= _team_setting_set(self, TRUE, has_lst, val_lst);
+        }
+    }
+
+    if (do_set_default)
+        changed_flags |= _team_setting_set_default(self);
+
+    self->_data_priv.strict_validated        = FALSE;
+    self->_data_priv._js_str_need_synthetize = FALSE;
+    self->_data_priv.js_str_invalid          = new_js_str_invalid;
+    g_free((char *) self->_data_priv._js_str);
+    self->_data_priv._js_str = g_strdup(js_str);
+
+    return changed_flags;
 }
 
 /*****************************************************************************/
 
 static void
-_team_setting_prefix_error_plain (gboolean is_port,
-                                  const char *property_name,
-                                  GError **error)
+_team_setting_prefix_error_plain(gboolean is_port, const char *property_name, GError **error)
 {
-	g_prefix_error (error,
-	                "%s.%s: ",
-	                  is_port
-	                ? NM_SETTING_TEAM_PORT_SETTING_NAME
-	                : NM_SETTING_TEAM_SETTING_NAME,
-	                property_name);
+    g_prefix_error(error,
+                   "%s.%s: ",
+                   is_port ? NM_SETTING_TEAM_PORT_SETTING_NAME : NM_SETTING_TEAM_SETTING_NAME,
+                   property_name);
 }
 
 static void
-_team_setting_prefix_error (const NMTeamSetting *self,
-                            const char *prop_name_master,
-                            const char *prop_name_port,
-                            GError **error)
+_team_setting_prefix_error(const NMTeamSetting *self,
+                           const char *         prop_name_master,
+                           const char *         prop_name_port,
+                           GError **            error)
 {
-	_team_setting_ASSERT (self);
-	nm_assert (  self->d.is_port
-	           ? (!!prop_name_port)
-	           : (!!prop_name_master));
-	_team_setting_prefix_error_plain (self->d.is_port,
-	                                    self->d.is_port
-	                                  ? prop_name_port
-	                                  : prop_name_master,
-	                                  error);
+    _team_setting_ASSERT(self);
+    nm_assert(self->d.is_port ? (!!prop_name_port) : (!!prop_name_master));
+    _team_setting_prefix_error_plain(self->d.is_port,
+                                     self->d.is_port ? prop_name_port : prop_name_master,
+                                     error);
 }
 
 static gboolean
-_team_setting_verify_properties (const NMTeamSetting *self,
-                                 GError **error)
+_team_setting_verify_properties(const NMTeamSetting *self, GError **error)
 {
-	const TeamAttrData *attr_data;
-	guint i;
-
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-
-		if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
-			continue;
-		if (!_team_setting_has_field (self, attr_data))
-			continue;
-
-		if (attr_data->has_range) {
-			gconstpointer p_field;
-
-			p_field = _team_setting_get_field (self, attr_data);
-			if (attr_data->value_type == NM_VALUE_TYPE_INT32) {
-				gint32 v = *((const gint32 *) p_field);
-
-				if (   v < attr_data->range.r_int32.min
-				    || v > attr_data->range.r_int32.max) {
-					g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-					             _("value out or range"));
-					_team_setting_prefix_error_plain (self->d.is_port, attr_data->property_name, error);
-					return FALSE;
-				}
-			} else if (attr_data->value_type == NM_VALUE_TYPE_STRING) {
-				const char *v = *((const char *const*) p_field);
-
-				if (nm_utils_strv_find_first ((char **) attr_data->range.r_string.valid_names,
-				                              -1,
-				                              v) < 0) {
-					g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-					             _("invalid value"));
-					_team_setting_prefix_error_plain (self->d.is_port, attr_data->property_name, error);
-					return FALSE;
-				}
-			} else
-				nm_assert_not_reached ();
-		}
-
-		if (   !self->d.is_port
-		    && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-			if (self->d.master.runner_tx_hash) {
-				for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
-					const char *val = self->d.master.runner_tx_hash->pdata[i];
-
-					if (  !val
-					    || (nm_utils_strv_find_first ((char **) _valid_names_runner_tx_hash,
-					                                  -1,
-					                                  val) < 0)) {
-						g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-						             _("invalid runner-tx-hash"));
-						_team_setting_prefix_error_plain (self->d.is_port, NM_SETTING_TEAM_RUNNER_TX_HASH, error);
-						return FALSE;
-					}
-				}
-			}
-		}
-	}
-
-	if (!self->d.is_port) {
-
-		for (i = 0; i < G_N_ELEMENTS (_runner_compat_lst); i++) {
-			const RunnerCompatElem *e = &_runner_compat_lst[i];
-
-			nm_assert (NM_PTRARRAY_LEN (e->valid_runners) > 0);
-
-			attr_data = _team_attr_data_get (FALSE, e->team_attr);
-
-			if (!_team_setting_has_field (self, attr_data))
-				continue;
-			if (   self->d.master.runner
-			    && (nm_utils_strv_find_first ((char **) e->valid_runners,
-			                                  -1,
-			                                  self->d.master.runner) >= 0))
-				continue;
-			if (e->valid_runners[1] == NULL) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-				             _("%s is only allowed for runner %s"),
-				             attr_data->property_name,
-				             e->valid_runners[0]);
-			} else {
-				gs_free char *s = NULL;
-
-				s = g_strjoinv (",", (char **) e->valid_runners);
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-				             _("%s is only allowed for runners %s"),
-				             attr_data->property_name,
-				             s);
-			}
-			_team_setting_prefix_error_plain (self->d.is_port, NM_SETTING_TEAM_RUNNER, error);
-			return FALSE;
-		}
-	} else {
-		gboolean has_lacp_attrs;
-		gboolean has_activebackup_attrs;
-
-		has_lacp_attrs = _team_setting_has_fields_any (self, NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
-		                                                     NM_TEAM_ATTRIBUTE_PORT_LACP_KEY);
-		has_activebackup_attrs = _team_setting_has_fields_any (self, NM_TEAM_ATTRIBUTE_PORT_PRIO,
-		                                                             NM_TEAM_ATTRIBUTE_PORT_STICKY);
-		if (has_lacp_attrs && has_activebackup_attrs) {
-			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-			             _("cannot set parameters for lacp and activebackup runners together"));
-			_team_setting_prefix_error (self, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS, error);
-			return FALSE;
-		}
-	}
-
-	for (i = 0; i < self->d.link_watchers->len; i++) {
-		if (!self->d.link_watchers->pdata[i]) {
-			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING,
-			             _("missing link watcher"));
-			_team_setting_prefix_error (self, NM_SETTING_TEAM_LINK_WATCHERS, NM_SETTING_TEAM_PORT_LINK_WATCHERS, error);
-			return FALSE;
-		}
-	}
-
-	return TRUE;
+    const TeamAttrData *attr_data;
+    guint               i;
+
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        if (!_team_attr_data_is_relevant(attr_data, self->d.is_port))
+            continue;
+        if (!_team_setting_has_field(self, attr_data))
+            continue;
+
+        if (attr_data->has_range) {
+            gconstpointer p_field;
+
+            p_field = _team_setting_get_field(self, attr_data);
+            if (attr_data->value_type == NM_VALUE_TYPE_INT32) {
+                gint32 v = *((const gint32 *) p_field);
+
+                if (v < attr_data->range.r_int32.min || v > attr_data->range.r_int32.max) {
+                    g_set_error(error,
+                                NM_CONNECTION_ERROR,
+                                NM_CONNECTION_ERROR_INVALID_SETTING,
+                                _("value out or range"));
+                    _team_setting_prefix_error_plain(self->d.is_port,
+                                                     attr_data->property_name,
+                                                     error);
+                    return FALSE;
+                }
+            } else if (attr_data->value_type == NM_VALUE_TYPE_STRING) {
+                const char *v = *((const char *const *) p_field);
+
+                if (nm_utils_strv_find_first((char **) attr_data->range.r_string.valid_names, -1, v)
+                    < 0) {
+                    g_set_error(error,
+                                NM_CONNECTION_ERROR,
+                                NM_CONNECTION_ERROR_INVALID_SETTING,
+                                _("invalid value"));
+                    _team_setting_prefix_error_plain(self->d.is_port,
+                                                     attr_data->property_name,
+                                                     error);
+                    return FALSE;
+                }
+            } else
+                nm_assert_not_reached();
+        }
+
+        if (!self->d.is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+            if (self->d.master.runner_tx_hash) {
+                for (i = 0; i < self->d.master.runner_tx_hash->len; i++) {
+                    const char *val = self->d.master.runner_tx_hash->pdata[i];
+
+                    if (!val
+                        || (nm_utils_strv_find_first((char **) _valid_names_runner_tx_hash, -1, val)
+                            < 0)) {
+                        g_set_error(error,
+                                    NM_CONNECTION_ERROR,
+                                    NM_CONNECTION_ERROR_INVALID_SETTING,
+                                    _("invalid runner-tx-hash"));
+                        _team_setting_prefix_error_plain(self->d.is_port,
+                                                         NM_SETTING_TEAM_RUNNER_TX_HASH,
+                                                         error);
+                        return FALSE;
+                    }
+                }
+            }
+        }
+    }
+
+    if (!self->d.is_port) {
+        for (i = 0; i < G_N_ELEMENTS(_runner_compat_lst); i++) {
+            const RunnerCompatElem *e = &_runner_compat_lst[i];
+
+            nm_assert(NM_PTRARRAY_LEN(e->valid_runners) > 0);
+
+            attr_data = _team_attr_data_get(FALSE, e->team_attr);
+
+            if (!_team_setting_has_field(self, attr_data))
+                continue;
+            if (self->d.master.runner
+                && (nm_utils_strv_find_first((char **) e->valid_runners, -1, self->d.master.runner)
+                    >= 0))
+                continue;
+            if (e->valid_runners[1] == NULL) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_SETTING,
+                            _("%s is only allowed for runner %s"),
+                            attr_data->property_name,
+                            e->valid_runners[0]);
+            } else {
+                gs_free char *s = NULL;
+
+                s = g_strjoinv(",", (char **) e->valid_runners);
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_SETTING,
+                            _("%s is only allowed for runners %s"),
+                            attr_data->property_name,
+                            s);
+            }
+            _team_setting_prefix_error_plain(self->d.is_port, NM_SETTING_TEAM_RUNNER, error);
+            return FALSE;
+        }
+    } else {
+        gboolean has_lacp_attrs;
+        gboolean has_activebackup_attrs;
+
+        has_lacp_attrs         = _team_setting_has_fields_any(self,
+                                                      NM_TEAM_ATTRIBUTE_PORT_LACP_PRIO,
+                                                      NM_TEAM_ATTRIBUTE_PORT_LACP_KEY);
+        has_activebackup_attrs = _team_setting_has_fields_any(self,
+                                                              NM_TEAM_ATTRIBUTE_PORT_PRIO,
+                                                              NM_TEAM_ATTRIBUTE_PORT_STICKY);
+        if (has_lacp_attrs && has_activebackup_attrs) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_SETTING,
+                        _("cannot set parameters for lacp and activebackup runners together"));
+            _team_setting_prefix_error(self,
+                                       NM_SETTING_TEAM_LINK_WATCHERS,
+                                       NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+                                       error);
+            return FALSE;
+        }
+    }
+
+    for (i = 0; i < self->d.link_watchers->len; i++) {
+        if (!self->d.link_watchers->pdata[i]) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_SETTING,
+                        _("missing link watcher"));
+            _team_setting_prefix_error(self,
+                                       NM_SETTING_TEAM_LINK_WATCHERS,
+                                       NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+                                       error);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
 }
 
 static gboolean
-_team_setting_verify_config (const NMTeamSetting *self,
-                             GError **error)
+_team_setting_verify_config(const NMTeamSetting *self, GError **error)
 {
-	const char *js_str;
-
-	/* we always materialize the JSON string. That is because we want to validate the
-	 * string length of the resulting JSON. */
-	js_str = nm_team_setting_config_get (self);
-
-	if (js_str) {
-		if (strlen (js_str) > 1*1024*1024) {
-			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			             _("team config exceeds size limit"));
-			_team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
-			return FALSE;
-		}
-		if (!g_utf8_validate (js_str, -1, NULL)) {
-			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			             _("team config is not valid UTF-8"));
-			_team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
-			return FALSE;
-		}
-		if (self->d.js_str_invalid) {
-			g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			             _("invalid json"));
-			_team_setting_prefix_error (self, NM_SETTING_TEAM_CONFIG, NM_SETTING_TEAM_PORT_CONFIG, error);
-			return FALSE;
-		}
-	}
-
-	return TRUE;
+    const char *js_str;
+
+    /* we always materialize the JSON string. That is because we want to validate the
+     * string length of the resulting JSON. */
+    js_str = nm_team_setting_config_get(self);
+
+    if (js_str) {
+        if (strlen(js_str) > 1 * 1024 * 1024) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                        _("team config exceeds size limit"));
+            _team_setting_prefix_error(self,
+                                       NM_SETTING_TEAM_CONFIG,
+                                       NM_SETTING_TEAM_PORT_CONFIG,
+                                       error);
+            return FALSE;
+        }
+        if (!g_utf8_validate(js_str, -1, NULL)) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                        _("team config is not valid UTF-8"));
+            _team_setting_prefix_error(self,
+                                       NM_SETTING_TEAM_CONFIG,
+                                       NM_SETTING_TEAM_PORT_CONFIG,
+                                       error);
+            return FALSE;
+        }
+        if (self->d.js_str_invalid) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                        _("invalid json"));
+            _team_setting_prefix_error(self,
+                                       NM_SETTING_TEAM_CONFIG,
+                                       NM_SETTING_TEAM_PORT_CONFIG,
+                                       error);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
 }
 
 gboolean
-nm_team_setting_verify (const NMTeamSetting *self,
-                        GError **error)
+nm_team_setting_verify(const NMTeamSetting *self, GError **error)
 {
-	if (self->d.strict_validated) {
-		if (!_team_setting_verify_properties (self, error))
-			return FALSE;
-	}
-	return _team_setting_verify_config (self, error);
+    if (self->d.strict_validated) {
+        if (!_team_setting_verify_properties(self, error))
+            return FALSE;
+    }
+    return _team_setting_verify_config(self, error);
 }
 
 /*****************************************************************************/
 
 int
-nm_team_setting_cmp (const NMTeamSetting *self_a,
-                     const NMTeamSetting *self_b,
-                     gboolean ignore_js_str)
+nm_team_setting_cmp(const NMTeamSetting *self_a,
+                    const NMTeamSetting *self_b,
+                    gboolean             ignore_js_str)
 {
-	const TeamAttrData *attr_data;
+    const TeamAttrData *attr_data;
 
-	NM_CMP_SELF (self_a, self_b);
+    NM_CMP_SELF(self_a, self_b);
 
-	NM_CMP_FIELD_UNSAFE (self_a, self_b, d.is_port);
+    NM_CMP_FIELD_UNSAFE(self_a, self_b, d.is_port);
 
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		if (!_team_attr_data_is_relevant (attr_data, self_a->d.is_port))
-			continue;
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        if (!_team_attr_data_is_relevant(attr_data, self_a->d.is_port))
+            continue;
 
-		NM_CMP_RETURN (_team_attr_data_cmp (attr_data,
-		                                    self_a->d.is_port,
-		                                    _team_setting_get_field (self_a, attr_data),
-		                                    _team_setting_get_field (self_b, attr_data)));
-	}
+        NM_CMP_RETURN(_team_attr_data_cmp(attr_data,
+                                          self_a->d.is_port,
+                                          _team_setting_get_field(self_a, attr_data),
+                                          _team_setting_get_field(self_b, attr_data)));
+    }
 
-	if (!ignore_js_str) {
-		NM_CMP_DIRECT_STRCMP0 (nm_team_setting_config_get (self_a),
-		                       nm_team_setting_config_get (self_b));
-	}
+    if (!ignore_js_str) {
+        NM_CMP_DIRECT_STRCMP0(nm_team_setting_config_get(self_a),
+                              nm_team_setting_config_get(self_b));
+    }
 
-	return 0;
+    return 0;
 }
 
 guint32
-nm_team_setting_reset (NMTeamSetting *self,
-                       const NMTeamSetting *src)
+nm_team_setting_reset(NMTeamSetting *self, const NMTeamSetting *src)
 {
-	const TeamAttrData *attr_data;
-	guint32 changed_flags;
-
-	_team_setting_ASSERT (self);
-	_team_setting_ASSERT (src);
-	nm_assert (self->d.is_port == src->d.is_port);
-
-	if (self == src)
-		return 0;
-
-	changed_flags = 0;
-
-	for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-		if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
-			continue;
-		if (_team_attr_data_equal (attr_data,
-		                           self->d.is_port,
-		                           _team_setting_get_field (self, attr_data),
-		                           _team_setting_get_field (src, attr_data)))
-			continue;
-		_team_attr_data_copy (attr_data,
-		                      self->d.is_port,
-		                      _team_setting_get_field (self, attr_data),
-		                      _team_setting_get_field (src, attr_data));
-		changed_flags |= nm_team_attribute_to_flags (attr_data->team_attr);
-	}
-
-	self->_data_priv.has_fields_mask = src->d.has_fields_mask;
-
-	if (!nm_streq0 (self->d._js_str, src->d._js_str)) {
-		g_free ((char *) self->_data_priv._js_str);
-		self->_data_priv._js_str = g_strdup (src->d._js_str);
-		changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-	} else if (changed_flags != 0)
-		changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
-
-	self->_data_priv._js_str_need_synthetize = src->d._js_str_need_synthetize;
-	self->_data_priv.strict_validated = src->d.strict_validated;
-	self->_data_priv.js_str_invalid = src->d.js_str_invalid;
-
-	return changed_flags;
+    const TeamAttrData *attr_data;
+    guint32             changed_flags;
+
+    _team_setting_ASSERT(self);
+    _team_setting_ASSERT(src);
+    nm_assert(self->d.is_port == src->d.is_port);
+
+    if (self == src)
+        return 0;
+
+    changed_flags = 0;
+
+    for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+         attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+         attr_data++) {
+        if (!_team_attr_data_is_relevant(attr_data, self->d.is_port))
+            continue;
+        if (_team_attr_data_equal(attr_data,
+                                  self->d.is_port,
+                                  _team_setting_get_field(self, attr_data),
+                                  _team_setting_get_field(src, attr_data)))
+            continue;
+        _team_attr_data_copy(attr_data,
+                             self->d.is_port,
+                             _team_setting_get_field(self, attr_data),
+                             _team_setting_get_field(src, attr_data));
+        changed_flags |= nm_team_attribute_to_flags(attr_data->team_attr);
+    }
+
+    self->_data_priv.has_fields_mask = src->d.has_fields_mask;
+
+    if (!nm_streq0(self->d._js_str, src->d._js_str)) {
+        g_free((char *) self->_data_priv._js_str);
+        self->_data_priv._js_str = g_strdup(src->d._js_str);
+        changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+    } else if (changed_flags != 0)
+        changed_flags |= nm_team_attribute_to_flags(NM_TEAM_ATTRIBUTE_CONFIG);
+
+    self->_data_priv._js_str_need_synthetize = src->d._js_str_need_synthetize;
+    self->_data_priv.strict_validated        = src->d.strict_validated;
+    self->_data_priv.js_str_invalid          = src->d.js_str_invalid;
+
+    return changed_flags;
 }
 
 static void
-_variants_list_team_unref_auto (GVariant *(*p_variants)[])
+_variants_list_team_unref_auto(GVariant *(*p_variants)[])
 {
-	int i;
+    int i;
 
-	for (i = 0; i < _NM_TEAM_ATTRIBUTE_NUM; i++)
-		nm_g_variant_unref ((*p_variants)[i]);
+    for (i = 0; i < _NM_TEAM_ATTRIBUTE_NUM; i++)
+        nm_g_variant_unref((*p_variants)[i]);
 }
 
 gboolean
-nm_team_setting_reset_from_dbus (NMTeamSetting *self,
-                                 GVariant *setting_dict,
-                                 GHashTable *keys,
-                                 guint32 *out_changed,
-                                 guint /* NMSettingParseFlags */ parse_flags,
-                                 GError **error)
+nm_team_setting_reset_from_dbus(NMTeamSetting *                 self,
+                                GVariant *                      setting_dict,
+                                GHashTable *                    keys,
+                                guint32 *                       out_changed,
+                                guint /* NMSettingParseFlags */ parse_flags,
+                                GError **                       error)
 {
-	nm_auto (_variants_list_team_unref_auto) GVariant *variants[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
-	gs_unref_ptrarray GPtrArray *v_link_watchers = NULL;
-	const TeamAttrData *attr_data;
-	GVariantIter iter;
-	const char *v_key;
-	GVariant *v_val;
-
-	*out_changed = 0;
-
-	g_variant_iter_init (&iter, setting_dict);
-	while (g_variant_iter_next (&iter, "{&sv}", &v_key, &v_val)) {
-		_nm_unused gs_unref_variant GVariant *v_val_free = v_val;
-		const GVariantType *variant_type = NULL;
-
-		attr_data = _team_attr_data_find_for_property_name (self->d.is_port, v_key);
-		if (!attr_data) {
-			/* _nm_setting_new_from_dbus() already checks for unknown keys. Don't
-			 * do that here. */
-			continue;
-		}
-
-		if (keys)
-			g_hash_table_remove (keys, v_key);
-
-		if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
-			variant_type = nm_value_type_get_variant_type (attr_data->value_type);
-		else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG)
-			variant_type = G_VARIANT_TYPE_STRING;
-		else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS)
-			variant_type = G_VARIANT_TYPE ("aa{sv}");
-		else if (   !self->d.is_port
-		         && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH)
-			variant_type = G_VARIANT_TYPE_STRING_ARRAY;
-		else
-			nm_assert_not_reached ();
-
-		if (!g_variant_is_of_type (v_val, variant_type)) {
-			if (NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-				             _("invalid D-Bus type \"%s\""),
-				             g_variant_get_type_string (v_val));
-				_team_setting_prefix_error_plain (self->d.is_port,
-				                                  attr_data->property_name,
-				                                  error);
-				return FALSE;
-			}
-			continue;
-		}
-
-		/* _nm_setting_new_from_dbus() already checks for duplicate keys. Don't
-		 * do that here. */
-		nm_g_variant_unref (variants[attr_data->team_attr]);
-		variants[attr_data->team_attr] = g_steal_pointer (&v_val_free);
-	}
-
-	if (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) {
-
-		if (   variants[NM_TEAM_ATTRIBUTE_CONFIG]
-		    && WITH_JSON_VALIDATION
-		    && !NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
-			/* we don't require the content of the "link-watchers" and we also
-			 * don't perform strict validation. No need to parse it. */
-		} else {
-			gs_free_error GError *local = NULL;
-
-			/* We might need the parsed v_link_watchers array below (because there is no JSON
-			 * "config" present or because we don't build WITH_JSON_VALIDATION).
-			 *
-			 * Or we might run with NM_SETTING_PARSE_FLAGS_STRICT. In that mode, we may not necessarily
-			 * require that the entire setting as a whole validates (if a JSON config is present and
-			 * we are not "strict_validated") , but we require that we can at least parse the link watchers
-			 * on their own. */
-			v_link_watchers = _nm_utils_team_link_watchers_from_variant (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS],
-			                                                             NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT),
-			                                                             &local);
-			if (   local
-			    && NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
-				g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
-				             _("invalid link-watchers: %s"),
-				             local->message);
-				_team_setting_prefix_error (self,
-				                            NM_SETTING_TEAM_LINK_WATCHERS,
-				                            NM_SETTING_TEAM_PORT_LINK_WATCHERS,
-				                            error);
-				return FALSE;
-			}
-		}
-	}
-
-	*out_changed |= nm_team_setting_config_set (self,
-	                                              variants[NM_TEAM_ATTRIBUTE_CONFIG]
-	                                            ? g_variant_get_string (variants[NM_TEAM_ATTRIBUTE_CONFIG], NULL)
-	                                            : NULL);
-
-	if (   WITH_JSON_VALIDATION
-	    && variants[NM_TEAM_ATTRIBUTE_CONFIG]) {
-		/* for team settings, the JSON must be able to express all possible options. That means,
-		 * if the GVariant contains both the JSON "config" and other options, then the other options
-		 * are silently ignored. */
-	} else {
-		guint32 extra_changed = 0u;
-
-		for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
-			NMValueTypUnion val;
-			guint32 changed_flags = 0u;
-
-			if (!_team_attr_data_is_relevant (attr_data, self->d.is_port))
-				continue;
-			if (!variants[attr_data->team_attr])
-				continue;
-
-			if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
-				nm_value_type_get_from_variant (attr_data->value_type, &val, variants[attr_data->team_attr], FALSE);
-				changed_flags = _team_setting_value_set (self,
-				                                         attr_data,
-				                                         &val,
-				                                         SET_FIELD_MODE_SET,
-				                                         RESET_JSON_NO);
-			} else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
-				changed_flags = _team_setting_value_link_watchers_set_list (self,
-				                                                            v_link_watchers ? (const NMTeamLinkWatcher *const *) v_link_watchers->pdata : NULL,
-				                                                            v_link_watchers ? v_link_watchers->len : 0u,
-				                                                            SET_FIELD_MODE_SET,
-				                                                            RESET_JSON_NO);
-			} else if (   !self->d.is_port
-			           && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-				gs_free const char **strv = NULL;
-				gsize len;
-
-				strv = g_variant_get_strv (variants[attr_data->team_attr], &len);
-				changed_flags = _team_setting_value_master_runner_tx_hash_set_list (self,
-				                                                                    strv,
-				                                                                    NM_MIN (len, (gsize) G_MAXUINT),
-				                                                                    SET_FIELD_MODE_SET,
-				                                                                    RESET_JSON_NO);
-			} else
-				nm_assert_not_reached ();
-
-			extra_changed |= changed_flags;
-		}
-
-		if (!variants[NM_TEAM_ATTRIBUTE_CONFIG]) {
-			/* clear the JSON string so it can be regenerated. But only if we didn't set
-			 * it above. */
-			self->_data_priv.strict_validated = TRUE;
-			self->_data_priv._js_str_need_synthetize = TRUE;
-		}
-
-		*out_changed |= extra_changed;
-	}
-
-	return TRUE;
+    nm_auto(_variants_list_team_unref_auto) GVariant *variants[_NM_TEAM_ATTRIBUTE_NUM] = {
+        NULL,
+    };
+    gs_unref_ptrarray GPtrArray *v_link_watchers = NULL;
+    const TeamAttrData *         attr_data;
+    GVariantIter                 iter;
+    const char *                 v_key;
+    GVariant *                   v_val;
+    const NMJsonVt *             vt;
+
+    *out_changed = 0;
+
+    g_variant_iter_init(&iter, setting_dict);
+    while (g_variant_iter_next(&iter, "{&sv}", &v_key, &v_val)) {
+        _nm_unused gs_unref_variant GVariant *v_val_free   = v_val;
+        const GVariantType *                  variant_type = NULL;
+
+        attr_data = _team_attr_data_find_for_property_name(self->d.is_port, v_key);
+        if (!attr_data) {
+            /* _nm_setting_new_from_dbus() already checks for unknown keys. Don't
+             * do that here. */
+            continue;
+        }
+
+        if (keys)
+            g_hash_table_remove(keys, v_key);
+
+        if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
+            variant_type = nm_value_type_get_variant_type(attr_data->value_type);
+        else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG)
+            variant_type = G_VARIANT_TYPE_STRING;
+        else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS)
+            variant_type = G_VARIANT_TYPE("aa{sv}");
+        else if (!self->d.is_port
+                 && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH)
+            variant_type = G_VARIANT_TYPE_STRING_ARRAY;
+        else
+            nm_assert_not_reached();
+
+        if (!g_variant_is_of_type(v_val, variant_type)) {
+            if (NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("invalid D-Bus type \"%s\""),
+                            g_variant_get_type_string(v_val));
+                _team_setting_prefix_error_plain(self->d.is_port, attr_data->property_name, error);
+                return FALSE;
+            }
+            continue;
+        }
+
+        /* _nm_setting_new_from_dbus() already checks for duplicate keys. Don't
+         * do that here. */
+        nm_g_variant_unref(variants[attr_data->team_attr]);
+        variants[attr_data->team_attr] = g_steal_pointer(&v_val_free);
+    }
+
+    vt = nm_json_vt();
+
+    if (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) {
+        if (variants[NM_TEAM_ATTRIBUTE_CONFIG] && vt
+            && !NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
+            /* we don't require the content of the "link-watchers" and we also
+             * don't perform strict validation. No need to parse it. */
+        } else {
+            gs_free_error GError *local = NULL;
+
+            /* We might need the parsed v_link_watchers array below (because there is no JSON
+             * "config" present or because we don't have json support).
+             *
+             * Or we might run with NM_SETTING_PARSE_FLAGS_STRICT. In that mode, we may not necessarily
+             * require that the entire setting as a whole validates (if a JSON config is present and
+             * we are not "strict_validated") , but we require that we can at least parse the link watchers
+             * on their own. */
+            v_link_watchers = _nm_utils_team_link_watchers_from_variant(
+                variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS],
+                NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT),
+                &local);
+            if (local && NM_FLAGS_HAS(parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
+                g_set_error(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("invalid link-watchers: %s"),
+                            local->message);
+                _team_setting_prefix_error(self,
+                                           NM_SETTING_TEAM_LINK_WATCHERS,
+                                           NM_SETTING_TEAM_PORT_LINK_WATCHERS,
+                                           error);
+                return FALSE;
+            }
+        }
+    }
+
+    *out_changed |= nm_team_setting_config_set(
+        self,
+        variants[NM_TEAM_ATTRIBUTE_CONFIG]
+            ? g_variant_get_string(variants[NM_TEAM_ATTRIBUTE_CONFIG], NULL)
+            : NULL);
+
+    if (vt && variants[NM_TEAM_ATTRIBUTE_CONFIG]) {
+        /* for team settings, the JSON must be able to express all possible options. That means,
+         * if the GVariant contains both the JSON "config" and other options, then the other options
+         * are silently ignored. */
+    } else {
+        guint32 extra_changed = 0u;
+
+        for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1];
+             attr_data < &team_attr_datas[G_N_ELEMENTS(team_attr_datas)];
+             attr_data++) {
+            NMValueTypUnion val;
+            guint32         changed_flags = 0u;
+
+            if (!_team_attr_data_is_relevant(attr_data, self->d.is_port))
+                continue;
+            if (!variants[attr_data->team_attr])
+                continue;
+
+            if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
+                nm_value_type_get_from_variant(attr_data->value_type,
+                                               &val,
+                                               variants[attr_data->team_attr],
+                                               FALSE);
+                changed_flags = _team_setting_value_set(self,
+                                                        attr_data,
+                                                        &val,
+                                                        SET_FIELD_MODE_SET,
+                                                        RESET_JSON_NO);
+            } else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
+                changed_flags = _team_setting_value_link_watchers_set_list(
+                    self,
+                    v_link_watchers ? (const NMTeamLinkWatcher *const *) v_link_watchers->pdata
+                                    : NULL,
+                    v_link_watchers ? v_link_watchers->len : 0u,
+                    SET_FIELD_MODE_SET,
+                    RESET_JSON_NO);
+            } else if (!self->d.is_port
+                       && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+                gs_free const char **strv = NULL;
+                gsize                len;
+
+                strv          = g_variant_get_strv(variants[attr_data->team_attr], &len);
+                changed_flags = _team_setting_value_master_runner_tx_hash_set_list(
+                    self,
+                    strv,
+                    NM_MIN(len, (gsize) G_MAXUINT),
+                    SET_FIELD_MODE_SET,
+                    RESET_JSON_NO);
+            } else
+                nm_assert_not_reached();
+
+            extra_changed |= changed_flags;
+        }
+
+        if (!variants[NM_TEAM_ATTRIBUTE_CONFIG]) {
+            /* clear the JSON string so it can be regenerated. But only if we didn't set
+             * it above. */
+            self->_data_priv.strict_validated        = TRUE;
+            self->_data_priv._js_str_need_synthetize = TRUE;
+        }
+
+        *out_changed |= extra_changed;
+    }
+
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 gboolean
-nm_team_setting_maybe_changed (NMSetting *source,
-                               const GParamSpec *const*obj_properties,
-                               guint32 changed_flags)
+nm_team_setting_maybe_changed(NMSetting *              source,
+                              const GParamSpec *const *obj_properties,
+                              guint32                  changed_flags)
 {
-	NMTeamAttribute team_attr;
-	int count_flags;
-	guint32 ch;
-
-	if (changed_flags == 0u)
-		return FALSE;
-
-	count_flags = 0;
-	for (ch = changed_flags; ch != 0u; ch >>= 1) {
-		if (NM_FLAGS_HAS (ch, 0x1u))
-			count_flags++;
-	}
-
-	if (count_flags > 1)
-		g_object_freeze_notify (G_OBJECT (source));
-
-	ch = changed_flags;
-	for (team_attr = 0; team_attr < _NM_TEAM_ATTRIBUTE_NUM; team_attr++) {
-		if (!NM_FLAGS_ANY (ch, nm_team_attribute_to_flags (team_attr)))
-			continue;
-		g_object_notify_by_pspec (G_OBJECT (source),
-		                          (GParamSpec *) obj_properties[team_attr]);
-		ch &= ~nm_team_attribute_to_flags (team_attr);
-		if (ch == 0)
-			break;
-	}
-
-	if (count_flags > 1)
-		g_object_thaw_notify (G_OBJECT (source));
-
-	return TRUE;
+    NMTeamAttribute team_attr;
+    int             count_flags;
+    guint32         ch;
+
+    if (changed_flags == 0u)
+        return FALSE;
+
+    count_flags = 0;
+    for (ch = changed_flags; ch != 0u; ch >>= 1) {
+        if (NM_FLAGS_HAS(ch, 0x1u))
+            count_flags++;
+    }
+
+    if (count_flags > 1)
+        g_object_freeze_notify(G_OBJECT(source));
+
+    ch = changed_flags;
+    for (team_attr = 0; team_attr < _NM_TEAM_ATTRIBUTE_NUM; team_attr++) {
+        if (!NM_FLAGS_ANY(ch, nm_team_attribute_to_flags(team_attr)))
+            continue;
+        g_object_notify_by_pspec(G_OBJECT(source), (GParamSpec *) obj_properties[team_attr]);
+        ch &= ~nm_team_attribute_to_flags(team_attr);
+        if (ch == 0)
+            break;
+    }
+
+    if (count_flags > 1)
+        g_object_thaw_notify(G_OBJECT(source));
+
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 NMTeamSetting *
-_nm_setting_get_team_setting (struct _NMSetting *setting)
+_nm_setting_get_team_setting(struct _NMSetting *setting)
 {
-	if (NM_IS_SETTING_TEAM (setting))
-		return _nm_setting_team_get_team_setting (NM_SETTING_TEAM (setting));
-	return _nm_setting_team_port_get_team_setting (NM_SETTING_TEAM_PORT (setting));
+    if (NM_IS_SETTING_TEAM(setting))
+        return _nm_setting_team_get_team_setting(NM_SETTING_TEAM(setting));
+    return _nm_setting_team_port_get_team_setting(NM_SETTING_TEAM_PORT(setting));
 }
 
 static GVariant *
-_nm_team_settings_property_to_dbus (const NMSettInfoSetting *sett_info,
-                                    guint property_idx,
-                                    NMConnection *connection,
-                                    NMSetting *setting,
-                                    NMConnectionSerializationFlags flags,
-                                    const NMConnectionSerializationOptions *options)
+_nm_team_settings_property_to_dbus(const NMSettInfoSetting *               sett_info,
+                                   guint                                   property_idx,
+                                   NMConnection *                          connection,
+                                   NMSetting *                             setting,
+                                   NMConnectionSerializationFlags          flags,
+                                   const NMConnectionSerializationOptions *options)
 {
-	NMTeamSetting *self = _nm_setting_get_team_setting (setting);
-	const TeamAttrData *attr_data = _team_attr_data_get (self->d.is_port, sett_info->property_infos[property_idx].param_spec->param_id);
-
-	if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG) {
-		const char *config;
-
-		if (   self->d.strict_validated
-		    && !_nm_utils_is_manager_process) {
-			/* if we are in strict validating mode on the client side, the JSON is generated
-			 * artificially. In this case, don't send the config via D-Bus to the server.
-			 *
-			 * This also will cause NetworkManager to strictly validate the settings.
-			 * If a JSON "config" is present, strict validation won't be performed. */
-			return NULL;
-		}
-
-		config = nm_team_setting_config_get (self);
-		return config ? g_variant_new_string (config) : NULL;
-	}
-
-	if (!_team_setting_has_field (self, attr_data))
-		return NULL;
-
-	if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
-		return nm_value_type_to_variant (attr_data->value_type,
-	                                     _team_setting_get_field (self, attr_data));
-	}
-	if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS)
-		return _nm_utils_team_link_watchers_to_variant (self->d.link_watchers);
-	if (   !self->d.is_port
-	    && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
-		return g_variant_new_strv (self->d.master.runner_tx_hash ? (const char *const*) self->d.master.runner_tx_hash->pdata : NULL,
-		                           self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len : 0u);
-	}
-
-	nm_assert_not_reached ();
-	return NULL;
+    NMTeamSetting *     self = _nm_setting_get_team_setting(setting);
+    const TeamAttrData *attr_data =
+        _team_attr_data_get(self->d.is_port,
+                            sett_info->property_infos[property_idx].param_spec->param_id);
+
+    if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_CONFIG) {
+        const char *config;
+
+        if (self->d.strict_validated && !_nm_utils_is_manager_process) {
+            /* if we are in strict validating mode on the client side, the JSON is generated
+             * artificially. In this case, don't send the config via D-Bus to the server.
+             *
+             * This also will cause NetworkManager to strictly validate the settings.
+             * If a JSON "config" is present, strict validation won't be performed. */
+            return NULL;
+        }
+
+        config = nm_team_setting_config_get(self);
+        return config ? g_variant_new_string(config) : NULL;
+    }
+
+    if (!_team_setting_has_field(self, attr_data))
+        return NULL;
+
+    if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
+        return nm_value_type_to_variant(attr_data->value_type,
+                                        _team_setting_get_field(self, attr_data));
+    }
+    if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS)
+        return _nm_utils_team_link_watchers_to_variant(self->d.link_watchers);
+    if (!self->d.is_port && attr_data->team_attr == NM_TEAM_ATTRIBUTE_MASTER_RUNNER_TX_HASH) {
+        return g_variant_new_strv(self->d.master.runner_tx_hash
+                                      ? (const char *const *) self->d.master.runner_tx_hash->pdata
+                                      : NULL,
+                                  self->d.master.runner_tx_hash ? self->d.master.runner_tx_hash->len
+                                                                : 0u);
+    }
+
+    nm_assert_not_reached();
+    return NULL;
 }
 
 static void
-_nm_team_settings_property_from_dbus_link_watchers (GVariant *dbus_value,
-                                                    GValue *prop_value)
+_nm_team_settings_property_from_dbus_link_watchers(GVariant *dbus_value, GValue *prop_value)
 {
-	g_value_take_boxed (prop_value,
-	                    _nm_utils_team_link_watchers_from_variant (dbus_value, FALSE, NULL));
+    g_value_take_boxed(prop_value,
+                       _nm_utils_team_link_watchers_from_variant(dbus_value, FALSE, NULL));
 }
 
 const NMSettInfoPropertType nm_sett_info_propert_type_team_b = {
-	.dbus_type           = G_VARIANT_TYPE_BOOLEAN,
-	.to_dbus_fcn         = _nm_team_settings_property_to_dbus,
+    .dbus_type   = G_VARIANT_TYPE_BOOLEAN,
+    .to_dbus_fcn = _nm_team_settings_property_to_dbus,
 };
 
 const NMSettInfoPropertType nm_sett_info_propert_type_team_i = {
-	.dbus_type           = G_VARIANT_TYPE_INT32,
-	.to_dbus_fcn         = _nm_team_settings_property_to_dbus,
+    .dbus_type   = G_VARIANT_TYPE_INT32,
+    .to_dbus_fcn = _nm_team_settings_property_to_dbus,
 };
 
 const NMSettInfoPropertType nm_sett_info_propert_type_team_s = {
-	.dbus_type           = G_VARIANT_TYPE_STRING,
-	.to_dbus_fcn         = _nm_team_settings_property_to_dbus,
+    .dbus_type   = G_VARIANT_TYPE_STRING,
+    .to_dbus_fcn = _nm_team_settings_property_to_dbus,
 };
 
 const NMSettInfoPropertType nm_sett_info_propert_type_team_as = {
-	.dbus_type           = NM_G_VARIANT_TYPE ("as"),
-	.to_dbus_fcn         = _nm_team_settings_property_to_dbus,
+    .dbus_type   = NM_G_VARIANT_TYPE("as"),
+    .to_dbus_fcn = _nm_team_settings_property_to_dbus,
 };
 
 const NMSettInfoPropertType nm_sett_info_propert_type_team_link_watchers = {
-	.dbus_type           = NM_G_VARIANT_TYPE ("aa{sv}"),
-	.to_dbus_fcn         = _nm_team_settings_property_to_dbus,
-	.gprop_from_dbus_fcn = _nm_team_settings_property_from_dbus_link_watchers,
+    .dbus_type           = NM_G_VARIANT_TYPE("aa{sv}"),
+    .to_dbus_fcn         = _nm_team_settings_property_to_dbus,
+    .gprop_from_dbus_fcn = _nm_team_settings_property_from_dbus_link_watchers,
 };
 
 /*****************************************************************************/
 
 NMTeamSetting *
-nm_team_setting_new (gboolean is_port,
-                     const char *js_str)
+nm_team_setting_new(gboolean is_port, const char *js_str)
 {
-	NMTeamSetting *self;
-	gsize l;
+    NMTeamSetting *self;
+    gsize          l;
 
-	G_STATIC_ASSERT_EXPR (sizeof (*self) == sizeof (self->_data_priv));
-	G_STATIC_ASSERT_EXPR (sizeof (*self) == NM_CONST_MAX (nm_offsetofend (NMTeamSetting, d.master), nm_offsetofend (NMTeamSetting, d.port)));
+    G_STATIC_ASSERT_EXPR(sizeof(*self) == sizeof(self->_data_priv));
+    G_STATIC_ASSERT_EXPR(sizeof(*self)
+                         == NM_CONST_MAX(nm_offsetofend(NMTeamSetting, d.master),
+                                         nm_offsetofend(NMTeamSetting, d.port)));
 
-	l =   is_port
-	    ? nm_offsetofend (NMTeamSetting, d.port)
-	    : nm_offsetofend (NMTeamSetting, d.master);
+    l = is_port ? nm_offsetofend(NMTeamSetting, d.port) : nm_offsetofend(NMTeamSetting, d.master);
 
-	self = g_malloc0 (l);
+    self = g_malloc0(l);
 
-	self->_data_priv.is_port                 = is_port;
-	self->_data_priv.strict_validated        = TRUE;
-	self->_data_priv._js_str_need_synthetize = FALSE;
-	self->_data_priv.link_watchers           = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_team_link_watcher_unref);
+    self->_data_priv.is_port                 = is_port;
+    self->_data_priv.strict_validated        = TRUE;
+    self->_data_priv._js_str_need_synthetize = FALSE;
+    self->_data_priv.link_watchers =
+        g_ptr_array_new_with_free_func((GDestroyNotify) nm_team_link_watcher_unref);
 
-	_team_setting_ASSERT (self);
+    _team_setting_ASSERT(self);
 
-	nm_team_setting_config_set (self, js_str);
+    nm_team_setting_config_set(self, js_str);
 
-	_team_setting_ASSERT (self);
+    _team_setting_ASSERT(self);
 
-	return self;
+    return self;
 }
 
 void
-nm_team_setting_free (NMTeamSetting *self)
+nm_team_setting_free(NMTeamSetting *self)
 {
-	if (!self)
-		return;
-
-	_team_setting_ASSERT (self);
-
-	if (!self->d.is_port) {
-		nm_clear_pointer (((GPtrArray **) &self->_data_priv.master.runner_tx_hash), g_ptr_array_unref);
-		g_free ((char *) self->_data_priv.master.runner);
-		g_free ((char *) self->_data_priv.master.runner_hwaddr_policy);
-		g_free ((char *) self->_data_priv.master.runner_tx_balancer);
-		g_free ((char *) self->_data_priv.master.runner_agg_select_policy);
-	}
-	g_ptr_array_unref ((GPtrArray *) self->_data_priv.link_watchers);
-	g_free ((char *) self->_data_priv._js_str);
-	g_free (self);
+    if (!self)
+        return;
+
+    _team_setting_ASSERT(self);
+
+    if (!self->d.is_port) {
+        nm_clear_pointer(((GPtrArray **) &self->_data_priv.master.runner_tx_hash),
+                         g_ptr_array_unref);
+        g_free((char *) self->_data_priv.master.runner);
+        g_free((char *) self->_data_priv.master.runner_hwaddr_policy);
+        g_free((char *) self->_data_priv.master.runner_tx_balancer);
+        g_free((char *) self->_data_priv.master.runner_agg_select_policy);
+    }
+    g_ptr_array_unref((GPtrArray *) self->_data_priv.link_watchers);
+    g_free((char *) self->_data_priv._js_str);
+    g_free(self);
 }