예제 #1
0
파일: ppp.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_ppp_config_set_ipv4(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	const ni_dbus_variant_t *ipcp;
	ni_ppp_config_t *conf;
	dbus_bool_t b;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(conf = ni_objectmodel_get_ppp_config(object, TRUE, error)))
		return FALSE;

	__ni_objectmodel_dict_get_sockaddr(argument, "local-ip", &conf->ipv4.local_ip);
	if (conf->ipv4.local_ip.ss_family != AF_UNSPEC &&
	    conf->ipv4.local_ip.ss_family != AF_INET)
		return FALSE;
	__ni_objectmodel_dict_get_sockaddr(argument, "remote-ip", &conf->ipv4.remote_ip);
	if (conf->ipv4.remote_ip.ss_family != AF_UNSPEC &&
	    conf->ipv4.remote_ip.ss_family != AF_INET)
		return FALSE;

	if (!(ipcp = ni_dbus_dict_get(argument, "ipcp")))
		return TRUE;
	if (!ni_dbus_variant_is_dict(ipcp))
		return FALSE;

	if (ni_dbus_dict_get_bool(ipcp, "accept-local", &b))
		conf->ipv4.ipcp.accept_local = b;
	if (ni_dbus_dict_get_bool(ipcp, "accept-remote", &b))
		conf->ipv4.ipcp.accept_remote = b;

	return TRUE;
}
예제 #2
0
파일: team.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
__ni_objectmodel_team_set_link_watch(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	const ni_dbus_variant_t *entry;
	ni_team_t *team;
	unsigned int i;

	if (!(team = __ni_objectmodel_team_write_handle(object, error)))
		return FALSE;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	i = 0; entry = NULL;
	while ((entry = ni_dbus_dict_get_next(argument, "watch", entry))) {
		const ni_dbus_variant_t *dict;
		ni_team_link_watch_type_t type;
		ni_team_link_watch_t *lw;
		const char *name;

		if (!ni_dbus_struct_get_string(entry, 0, &name)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"bad array element %u value for property %s; missed subtype",
					i, property->name);
			return FALSE;
		}

		if (!ni_team_link_watch_name_to_type(name, &type)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"bad array element %u for property %s; unsupported subtype %s",
					i, property->name, name);
			return FALSE;
		}

		if (!(dict = ni_dbus_struct_get(entry, 1))) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"missed team link_watch member dict in array element %u", i);
			return FALSE;
		}

		if (!ni_dbus_variant_is_dict(dict)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
					"team link_watch array element %u is not a dict", i);
			return FALSE;
		}

		lw = ni_team_link_watch_new(type);
		if (!__ni_objectmodel_team_link_watch_from_dict(lw, dict, error, property)) {
			ni_team_link_watch_free(lw);
			return FALSE;
		}

		ni_team_link_watch_array_append(&team->link_watch, lw);
		i++;
	}
	return TRUE;
}
예제 #3
0
파일: ethtool.c 프로젝트: openSUSE/wicked
static dbus_bool_t
ni_objectmodel_ethtool_set_features(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	const ni_dbus_variant_t *dict;
	ni_ethtool_t *ethtool;
	unsigned int i;

	if (!argument || !ni_dbus_variant_is_dict_array(argument))
		return FALSE;

	if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error)))
		return FALSE;

	ni_ethtool_features_free(ethtool->features);
	if (!(ethtool->features = ni_ethtool_features_new()))
		return FALSE;

	for (i = 0; i < argument->array.len; ++i) {
		dict = &argument->variant_array_value[i];
		if (!ni_dbus_variant_is_dict(dict))
			continue;

		ni_objectmodel_ethtool_feature_from_dict(dict, ethtool->features);
	}
	return TRUE;
}
예제 #4
0
파일: ethtool.c 프로젝트: openSUSE/wicked
static dbus_bool_t
ni_objectmodel_ethtool_set_wake_on_lan(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	ni_ethtool_wake_on_lan_t *wol;
	ni_ethtool_t *ethtool;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error)))
		return FALSE;

	ni_ethtool_wake_on_lan_free(ethtool->wake_on_lan);
	if (!(ethtool->wake_on_lan = ni_ethtool_wake_on_lan_new()))
		return FALSE;
	wol = ethtool->wake_on_lan;

	ni_dbus_dict_get_uint32(argument, "support", &wol->support);
	ni_dbus_dict_get_uint32(argument, "options", &wol->options);
	__ni_objectmodel_dict_get_hwaddr(argument, "sopass", &wol->sopass);

	return TRUE;
}
예제 #5
0
파일: ppp.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_ppp_config_set_dns(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	ni_ppp_config_t *conf;
	dbus_bool_t b;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(conf = ni_objectmodel_get_ppp_config(object, TRUE, error)))
		return FALSE;

	if (ni_dbus_dict_get_bool(argument, "usepeerdns", &b))
		conf->dns.usepeerdns = b;

	__ni_objectmodel_dict_get_sockaddr(argument, "dns1", &conf->dns.dns1);
	__ni_objectmodel_dict_get_sockaddr(argument, "dns2", &conf->dns.dns2);

#if 0	/* limitted to IPv4? */
	if (conf->dns.dns1.ss_family != AF_UNSPEC && conf->dns.dns1.ss_family != AF_INET)
		return FALSE;
	if (conf->dns.dns2.ss_family != AF_UNSPEC && conf->dns.dns2.ss_family != AF_INET)
		return FALSE;
#endif
	return TRUE;
}
예제 #6
0
파일: ovs.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
__ni_objectmodel_ovs_bridge_set_vlan(ni_dbus_object_t *object, const ni_dbus_property_t *property,
					const ni_dbus_variant_t *argument, DBusError *error)
{
	ni_ovs_bridge_t *ovsbr;
	const char *parent = NULL;
	uint16_t tag = 0;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(ovsbr = __ni_objectmodel_ovs_bridge_write_handle(object, error)))
		return FALSE;

	ni_dbus_dict_get_string(argument, "parent", &parent);
	ni_dbus_dict_get_uint16(argument, "tag", &tag);

	if (!ni_string_empty(parent) && tag < 0x0fff) {
		ovsbr->config.vlan.tag = tag;
		ni_netdev_ref_set_ifname(&ovsbr->config.vlan.parent, parent);
	} else {
		ovsbr->config.vlan.tag = 0;
		ni_netdev_ref_destroy(&ovsbr->config.vlan.parent);
	}
	return TRUE;
}
예제 #7
0
파일: ethtool.c 프로젝트: openSUSE/wicked
/*
 * Extract ethtool properties from a dbug dict argument.
 * We're re-using device properties from ni_objectmodel_ethtool_service,
 * which are derived from changeDevice method configuration propeties.
 */
static ni_netdev_t *
ni_objectmodel_ethtool_request_arg(const ni_dbus_variant_t *argument)
{
	if (!ni_dbus_variant_is_dict(argument))
		return NULL;

	return ni_objectmodel_get_netif_argument(argument, NI_IFTYPE_UNKNOWN,
						&ni_objectmodel_ethtool_service);
}
예제 #8
0
/*
 * Generic functions for static address configuration
 */
static dbus_bool_t
ni_objectmodel_addrconf_static_request(ni_dbus_object_t *object, unsigned int addrfamily,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_addrconf_lease_t *lease = NULL;
	const ni_dbus_variant_t *dict;
	const char *string_value;
	ni_netdev_t *dev;
	ni_address_t *ap;
	int rv;

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	if (argc != 1 || !ni_dbus_variant_is_dict(&argv[0])) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"requestLease: expected one dict argument");
		return FALSE;
	}
	dict = &argv[0];

	lease = ni_addrconf_lease_new(NI_ADDRCONF_STATIC, addrfamily);
	lease->state = NI_ADDRCONF_STATE_GRANTED;
	ni_uuid_generate(&lease->uuid);

	if (!__ni_objectmodel_set_address_dict(&lease->addrs, dict, error)
	 || !__ni_objectmodel_set_route_dict(&lease->routes, dict, error)
	 || !__ni_objectmodel_set_resolver_dict(&lease->resolver, dict, error)) {
		ni_addrconf_lease_free(lease);
		return FALSE;
	}
	if (__ni_objectmodel_get_domain_string(dict, "hostname", &string_value))
		ni_string_dup(&lease->hostname, string_value);

	/* mark all addresses tentative, causing to verify them */
	for (ap = lease->addrs; ap; ap = ap->next)
		ni_address_set_tentative(ap, TRUE);

	rv = __ni_system_interface_update_lease(dev, &lease);
	if (lease)
		ni_addrconf_lease_free(lease);

	if (rv < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Error configuring static %s addresses: %s",
				ni_addrfamily_type_to_name(addrfamily),
				ni_strerror(rv));
		return FALSE;
	}

	/* Don't return anything. */
	return TRUE;
}
예제 #9
0
/*
 * Wickedd is sending us a signal indicating internal device state change.
 * We want to wait for this signal and when it is >= device-up return TRUE.
 * After timeout we fail...
 */
void
ni_state_change_signal_handler(ni_dbus_connection_t *conn, ni_dbus_message_t *msg, void *user_data)
{
	const char *signal_name = dbus_message_get_member(msg);
	const char *object_path = dbus_message_get_path(msg);
	ni_dbus_variant_t argv = NI_DBUS_VARIANT_INIT;
	ni_ifworker_array_t *ifworkers = user_data;
	ni_fsm_state_t cur_state, target_state;
	const char *ifname;
	unsigned int i;

	if (ni_string_empty(object_path))
		return;

	/* Deserialize dbus message */
	if (ni_dbus_message_get_args_variants(msg, &argv, 1) < 0 ||
	    !ni_dbus_variant_is_dict(&argv)) {
		ni_error("Unable to retrieve dict from signal %s,  object_path=%s",
			signal_name, object_path);
		return;
	}

	if (!ni_dbus_dict_get_uint32(&argv, "current-state", &cur_state) ||
	    !ni_dbus_dict_get_uint32(&argv, "target-state", &target_state) ||
	    !ni_dbus_dict_get_string(&argv, "ifname", &ifname)) {
		ni_error("Unable to retrieve dict's values from signal %s,  object_path=%s",
			signal_name, object_path);
		return;
	}

	ni_debug_application("received signal %s; object_path=%s; target_state=%s, state_name=%s",
		signal_name, object_path,  ni_ifworker_state_name(target_state),
		ni_ifworker_state_name(cur_state));

	for (i = 0; i < ifworkers->count; ++i) {
		ni_ifworker_t *w = ifworkers->data[i];

		if (cur_state != NI_FSM_STATE_NONE && cur_state != target_state)
			continue;

		if (!ni_string_eq(w->name, ifname))
			continue;

		ni_warn("%s: Device %s", ifname, cur_state == target_state ? "succeeded" : "failed");
		ni_ifworker_array_remove_with_children(ifworkers, w);

	}

	ni_dbus_variant_destroy(&argv);
}
예제 #10
0
파일: ethtool.c 프로젝트: openSUSE/wicked
static dbus_bool_t
ni_objectmodel_ethtool_set_priv_flags(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	const ni_dbus_variant_t *dict;
	ni_ethtool_t *ethtool;
	unsigned int i, len;
	dbus_bool_t enabled;
	ni_stringbuf_t buf;
	const char *name;

	if (!ni_dbus_variant_is_dict_array(argument))
		return FALSE;
	if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error)))
		return FALSE;

	ni_ethtool_priv_flags_free(ethtool->priv_flags);
	if (!(ethtool->priv_flags = ni_ethtool_priv_flags_new()))
		return FALSE;

	if ((len = argument->array.len) > 32)
		len = 32;

	ni_stringbuf_init(&buf);
	for (i = 0; i < argument->array.len; ++i) {
		dict = &argument->variant_array_value[i];
		if (!ni_dbus_variant_is_dict(dict))
			continue;

		if (!ni_dbus_dict_get_string(dict, "name", &name) ||
		    !ni_dbus_dict_get_bool(dict, "enabled", &enabled))
			continue;

		ni_stringbuf_put(&buf, name, ni_string_len(name));
		ni_stringbuf_trim_head(&buf, " \t\n");
		ni_stringbuf_trim_tail(&buf, " \t\n");
		if (ni_string_empty(buf.string))
			continue;

		if (ni_string_array_append(&ethtool->priv_flags->names, buf.string) == 0) {
			if (enabled)
				ethtool->priv_flags->bitmap |= NI_BIT(i);
		}
		ni_stringbuf_destroy(&buf);
	}
	return TRUE;
}
예제 #11
0
파일: ppp.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_ppp_set_mode(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	ni_dbus_variant_t *dict;
	const char *mode;
	ni_ppp_t *ppp;

	if (!(ppp = ni_objectmodel_ppp_handle(object, TRUE, error)))
		return FALSE;

	if (!ni_dbus_struct_get_string(argument, 0, &mode)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"bad value for property %s; missed subtype", property->name);
		return FALSE;
	}

	if (!ni_ppp_mode_name_to_type(mode, &ppp->mode.type)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"bad value for property %s; unsupported subtype %s", property->name, mode);
		return FALSE;
	}

	if (!(dict = ni_dbus_struct_get(argument, 1))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "missed ppp mode member dict");
		return FALSE;
	}
	if (!ni_dbus_variant_is_dict(dict)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "ppp mode member is not a dict");
		return FALSE;
	}

	ni_ppp_mode_init(&ppp->mode, ppp->mode.type);
	switch (ppp->mode.type) {
	case NI_PPP_MODE_PPPOE: {
			ni_ppp_mode_pppoe_t *pppoe = &ppp->mode.pppoe;
			const char *string;

			if (ni_dbus_dict_get_string(dict, "device", &string))
				ni_netdev_ref_set_ifname(&pppoe->device, string);
		}
		break;

	default:
		return FALSE;
	}

	return TRUE;
}
예제 #12
0
파일: ovs.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
__ni_objectmodel_ovs_bridge_port_from_dict(ni_ovs_bridge_port_t *port, const ni_dbus_variant_t *dict, DBusError *error)
{
	const char *string;

	(void)error;

	if (!port || !dict)
		return FALSE;

	if (!ni_dbus_variant_is_dict(dict))
		return FALSE;

	if (!ni_dbus_dict_get_string(dict, "device", &string) || ni_string_empty(string))
		return FALSE;

	ni_netdev_ref_set_ifname(&port->device, string);
	return TRUE;
}
예제 #13
0
static dbus_bool_t
ni_objectmodel_addrconf_ipv4ll_request(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_netdev_t *dev;

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	if (argc != 1 || !ni_dbus_variant_is_dict(&argv[0])) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"%s.%s: expected one dict argument",
				NI_OBJECTMODEL_ADDRCONF_IPV4AUTO_INTERFACE, method->name);
		return FALSE;
	}

	return ni_objectmodel_addrconf_forward_request(&ipv4ll_forwarder, dev, &argv[0], reply, error);
}
예제 #14
0
파일: ethtool.c 프로젝트: openSUSE/wicked
static dbus_bool_t
ni_objectmodel_ethtool_set_driver_info(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	ni_ethtool_driver_info_t *info;
	ni_ethtool_t *ethtool;
	const char *str;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(ethtool = ni_objectmodel_ethtool_write_handle(object, error)))
		return FALSE;

	ni_ethtool_driver_info_free(ethtool->driver_info);
	if (!(ethtool->driver_info = ni_ethtool_driver_info_new()))
		return FALSE;

	info = ethtool->driver_info;
	if (ni_dbus_dict_get_string(argument, "driver", &str))
		ni_string_dup(&info->driver, str);
	if (ni_dbus_dict_get_string(argument, "version", &str))
		ni_string_dup(&info->version, str);
	if (ni_dbus_dict_get_string(argument, "bus-info", &str))
		ni_string_dup(&info->bus_info, str);
	if (ni_dbus_dict_get_string(argument, "firmware-version", &str))
		ni_string_dup(&info->fw_version, str);
	if (ni_dbus_dict_get_string(argument, "expansion-rom-version", &str))
		ni_string_dup(&info->erom_version, str);

	ni_dbus_dict_get_uint32(argument, "supports", &info->supports.bitmap);

	return TRUE;
}
예제 #15
0
파일: ppp.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
ni_objectmodel_ppp_config_set_auth(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	ni_ppp_config_t *conf;
	const char *string;

	if (!ni_dbus_variant_is_dict(argument))
		return FALSE;

	if (!(conf = ni_objectmodel_get_ppp_config(object, TRUE, error)))
		return FALSE;

	if (ni_dbus_dict_get_string(argument, "hostname", &string))
		ni_string_dup(&conf->auth.hostname, string);

	if (ni_dbus_dict_get_string(argument, "username", &string))
		ni_string_dup(&conf->auth.username, string);

	if (ni_dbus_dict_get_string(argument, "password", &string))
		ni_string_dup(&conf->auth.password, string);

	return TRUE;
}
예제 #16
0
파일: team.c 프로젝트: mtomaschewski/wicked
static dbus_bool_t
__ni_objectmodel_team_set_runner(ni_dbus_object_t *object, const ni_dbus_property_t *property,
				const ni_dbus_variant_t *argument, DBusError *error)
{
	ni_dbus_variant_t *dict;
	const char *name;
	ni_team_t *team;

	if (!(team = __ni_objectmodel_team_write_handle(object, error)))
		return FALSE;

	if (!ni_dbus_struct_get_string(argument, 0, &name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"bad value for property %s; missed subtype", property->name);
		return FALSE;
	}

	if (!ni_team_runner_name_to_type(name, &team->runner.type)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"bad value for property %s; unsupported subtype %s", property->name, name);
		return FALSE;
	}

	if (!(dict = ni_dbus_struct_get(argument, 1))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "missed team runner member dict");
		return FALSE;
	}
	if (!ni_dbus_variant_is_dict(dict)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "team runner member is not a dict");
		return FALSE;
	}

	ni_team_runner_init(&team->runner, team->runner.type);
	switch (team->runner.type) {
	case NI_TEAM_RUNNER_ACTIVE_BACKUP: {
			ni_team_runner_active_backup_t *ab = &team->runner.ab;
			uint32_t u32;

			if (ni_dbus_dict_get_uint32(dict, "hwaddr_policy", &u32))
				ab->config.hwaddr_policy = u32;
			else
				ab->config.hwaddr_policy = NI_TEAM_AB_HWADDR_POLICY_SAME_ALL;
		}
		break;

	case NI_TEAM_RUNNER_LOAD_BALANCE: {
			ni_team_runner_load_balance_t *lb = &team->runner.lb;
			ni_dbus_variant_t *txb;
			uint32_t u32;

			if (ni_dbus_dict_get_uint32(dict, "tx_hash", &u32))
				lb->config.tx_hash = u32;
			else	lb->config.tx_hash = NI_TEAM_TX_HASH_NONE;

			txb = ni_dbus_dict_get(dict, "tx_balancer");
			if (txb) {
				if (ni_dbus_dict_get_uint32(txb, "name", &u32) &&
				    ni_team_tx_balancer_type_to_name(u32))
					lb->config.tx_balancer.type = u32;
				else	lb->config.tx_balancer.type = NI_TEAM_TX_BALANCER_BASIC;
				if (ni_dbus_dict_get_uint32(txb, "balancing_interval", &u32))
					lb->config.tx_balancer.interval = u32;
				else	lb->config.tx_balancer.interval = 50;
			}
		}
		break;

	case NI_TEAM_RUNNER_ROUND_ROBIN:
		break;

	case NI_TEAM_RUNNER_BROADCAST:
		break;

	case NI_TEAM_RUNNER_RANDOM:
		break;

	case NI_TEAM_RUNNER_LACP: {
			ni_team_runner_lacp_t *lacp = &team->runner.lacp;
			ni_dbus_variant_t *txb;
			dbus_bool_t b;
			uint16_t u16;
			uint32_t u32;

			if (ni_dbus_dict_get_bool(dict, "active", &b))
				lacp->config.active = b;
			else	lacp->config.active = TRUE;

			if (ni_dbus_dict_get_uint16(dict, "sys_prio", &u16))
				lacp->config.sys_prio = u16;
			else	lacp->config.sys_prio = 255;

			if (ni_dbus_dict_get_bool(dict, "fast_rate", &b))
				lacp->config.fast_rate = b;
			else	lacp->config.fast_rate = FALSE;

			if (ni_dbus_dict_get_uint16(dict, "min_ports", &u16) && u16 < 256)
				lacp->config.sys_prio = u16;
			else	lacp->config.sys_prio = 0;

			if (ni_dbus_dict_get_uint32(dict, "select_policy", &u32))
				lacp->config.select_policy = u32;
			else	lacp->config.select_policy = NI_TEAM_LACP_SELECT_POLICY_PRIO;

			if (ni_dbus_dict_get_uint32(dict, "tx_hash", &u32))
				lacp->config.tx_hash = u32;
			else	lacp->config.tx_hash = NI_TEAM_TX_HASH_NONE;

			txb = ni_dbus_dict_get(dict, "tx_balancer");
			if (txb) {
				if (ni_dbus_dict_get_uint32(txb, "name", &u32) &&
				    ni_team_tx_balancer_type_to_name(u32))
					lacp->config.tx_balancer.type = u32;
				else	lacp->config.tx_balancer.type = NI_TEAM_TX_BALANCER_BASIC;
				if (ni_dbus_dict_get_uint32(txb, "balancing_interval", &u32))
					lacp->config.tx_balancer.interval = u32;
				else	lacp->config.tx_balancer.interval = 50;
			}
		}
		break;

	default:
		return FALSE;
	}
	return TRUE;
}