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.c2866
1 files changed, 0 insertions, 2866 deletions
diff --git a/libnm-core/nm-team-utils.c b/libnm-core/nm-team-utils.c
deleted file mode 100644
index b7da35aa..00000000
--- a/libnm-core/nm-team-utils.c
+++ /dev/null
@@ -1,2866 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-/*
- * Copyright (C) 2019 Red Hat, Inc.
- */
-
-#define NM_VALUE_TYPE_DEFINE_FUNCTIONS
-
-#include "libnm-core/nm-default-libnm-core.h"
-
-#include "nm-team-utils.h"
-
-#include "nm-errors.h"
-#include "nm-utils-private.h"
-#include "nm-glib-aux/nm-json-aux.h"
-#include "nm-core-internal.h"
-#include "nm-setting-team.h"
-#include "nm-setting-team-port.h"
-
-/*****************************************************************************/
-
-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,
-} SetFieldModeEnum;
-
-typedef enum {
-    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);
-
-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,
-};
-
-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,
-};
-
-static const char *const _valid_names_runner_tx_balancer[] = {
-    "basic",
-    NULL,
-};
-
-static const char *const _valid_names_runner_tx_hash[] = {
-    "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,
-};
-
-typedef struct {
-    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),
-    },
-};
-
-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;
-} 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_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), ),
-
-#undef _INIT
-};
-
-/*****************************************************************************/
-
-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,
-} 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
-
-typedef struct {
-    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, ),
-#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 void
-_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);
-        }
-    }
-#endif
-}
-
-static gboolean
-_team_attr_data_is_relevant(const TeamAttrData *attr_data, gboolean is_port)
-{
-    return is_port ? attr_data->for_port : attr_data->for_master;
-}
-
-static const TeamAttrData *
-_team_attr_data_get(gboolean is_port, NMTeamAttribute 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));
-
-    return &team_attr_datas[idx];
-}
-
-static const TeamAttrData *
-_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;
-}
-
-static int
-_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;
-}
-
-static gboolean
-_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;
-}
-
-static void
-_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();
-}
-
-static void
-_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_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)
-{
-    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);
-#endif
-}
-
-static gboolean
-_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));
-}
-
-static gboolean
-_team_setting_has_fields_any_v(const NMTeamSetting *  self,
-                               const NMTeamAttribute *team_attrs,
-                               gsize                  n_team_attrs)
-{
-    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]);
-
-        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__))
-
-static void
-_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();
-
-do_unset:
-    self->_data_priv.has_fields_mask &= ~mask;
-    return;
-do_set:
-    self->_data_priv.has_fields_mask |= mask;
-}
-
-static gpointer
-_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));
-
-#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);
-#endif
-
-    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)
-{
-    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)
-{
-    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)
-{
-    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)
-{
-    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)
-{
-    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)
-{
-    return _team_setting_set((NMTeamSetting *) self, FALSE, NULL, NULL);
-}
-
-static guint32
-_team_setting_set_default(NMTeamSetting *self)
-{
-    return _team_setting_set(self, TRUE, NULL, NULL);
-}
-
-/*****************************************************************************/
-
-gconstpointer
-_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);
-
-    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);
-}
-
-static guint32
-_team_setting_value_set(NMTeamSetting *     self,
-                        const TeamAttrData *attr_data,
-                        gconstpointer       val,
-                        SetFieldModeEnum    set_field_mode,
-                        ResetJsonEnum       reset_json)
-{
-    gpointer p_field;
-    gboolean changed;
-
-    nm_assert(self);
-    _team_attr_data_ASSERT(attr_data);
-    nm_assert(val);
-
-    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);
-}
-
-guint32
-nm_team_setting_value_reset(NMTeamSetting * self,
-                            NMTeamAttribute team_attr,
-                            gboolean        to_default /* or else unset */)
-{
-    const TeamAttrData *attr_data;
-
-    nm_assert(self);
-
-    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);
-}
-
-guint32
-_nm_team_setting_value_set(NMTeamSetting * self,
-                           NMTeamAttribute team_attr,
-                           NMValueType     value_type,
-                           gconstpointer   val)
-{
-    const TeamAttrData *attr_data;
-
-    nm_assert(self);
-
-    attr_data = _team_attr_data_get(self->d.is_port, team_attr);
-
-    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);
-}
-
-guint32
-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));
-out:
-    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)
-{
-    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)
-{
-    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)
-{
-    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);
-}
-
-guint32
-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);
-}
-
-/*****************************************************************************/
-
-guint32
-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));
-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);
-}
-
-guint32
-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);
-}
-
-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)
-{
-    _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);
-}
-
-guint32
-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);
-}
-
-/*****************************************************************************/
-
-#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)])
-{
-    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)
-{
-    NMValueTypUnioMaybe args[G_N_ELEMENTS(link_watcher_attr_datas)];
-    int                 i;
-    gboolean            is_first = TRUE;
-
-    if (!link_watcher) {
-        g_string_append(gstr, "null");
-        return;
-    }
-
-    _link_watcher_unpack(link_watcher, args);
-
-    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];
-
-        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_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, " }");
-}
-
-static NMTeamLinkWatcher *
-_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;
-    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;
-}
-
-/*****************************************************************************/
-
-static GVariant *
-_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);
-}
-
-#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)[])
-{
-    int 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)
-{
-    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_utils_team_link_watchers_to_variant:
- * @link_watchers: (element-type NMTeamLinkWatcher): array of #NMTeamLinkWatcher
- *
- * Utility function to convert a #GPtrArray of #NMTeamLinkWatcher objects
- * representing link watcher configuration for team devices into a #GVariant
- * of type 'aa{sv}' representing an array of link watchers.
- *
- * Returns: (transfer full): a new floating #GVariant representing link watchers.
- **/
-GVariant *
-_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);
-}
-
-/**
- * _nm_utils_team_link_watchers_from_variant:
- * @value: a #GVariant of type 'aa{sv}'
- * @strict_parsing: whether to parse strictly or ignore everything invalid.
- * @error: error reason.
- *
- * Utility function to convert a #GVariant representing a list of team link
- * watchers int a #GPtrArray of #NMTeamLinkWatcher objects.
- *
- * Returns: (transfer full) (element-type NMTeamLinkWatcher): a newly allocated
- *   #GPtrArray of #NMTeamLinkWatcher objects.
- *
- * Note that if you provide an @error, then the function can only fail (and return %NULL)
- * or succeed (and not return %NULL). If you don't provide an @error, then the function
- * never returns %NULL.
- **/
-GPtrArray *
-_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;
-
-    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);
-
-    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);
-    }
-
-    return g_steal_pointer(&link_watchers);
-}
-
-/*****************************************************************************/
-
-const char *
-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_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;
-}
-
-/*****************************************************************************/
-
-static gboolean
-_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;
-}
-
-static const TeamAttrData *
-_attr_data_find_by_json_key(gboolean is_port, const char *const *keys, guint8 n_keys)
-{
-    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;
-    }
-
-    return NULL;
-}
-
-static void
-_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;
-    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(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;
-
-    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;
-    }
-}
-
-guint32
-nm_team_setting_config_set(NMTeamSetting *self, const char *js_str)
-{
-    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)
-{
-    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_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)
-{
-    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)
-{
-    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)
-{
-    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)
-{
-    const TeamAttrData *attr_data;
-
-    NM_CMP_SELF(self_a, self_b);
-
-    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;
-
-        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));
-    }
-
-    return 0;
-}
-
-guint32
-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;
-}
-
-static void
-_variants_list_team_unref_auto(GVariant *(*p_variants)[])
-{
-    int 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_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)
-{
-    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)
-{
-    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)
-{
-    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)
-{
-    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,
-};
-
-const NMSettInfoPropertType nm_sett_info_propert_type_team_i = {
-    .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,
-};
-
-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,
-};
-
-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,
-};
-
-/*****************************************************************************/
-
-NMTeamSetting *
-nm_team_setting_new(gboolean is_port, const char *js_str)
-{
-    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)));
-
-    l = is_port ? nm_offsetofend(NMTeamSetting, d.port) : nm_offsetofend(NMTeamSetting, d.master);
-
-    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);
-
-    _team_setting_ASSERT(self);
-
-    nm_team_setting_config_set(self, js_str);
-
-    _team_setting_ASSERT(self);
-
-    return self;
-}
-
-void
-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);
-}