Пример #1
0
static int
set_ethtool_eee(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_eee_t *eee;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(eee = ni_ethtool_eee_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "eee")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&eee->status.enabled, enabled);
		} else
		if (ni_string_eq(key, "tx-lpi")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&eee->tx_lpi.enabled, enabled);
		} else
		if (ni_string_eq(key, "tx-timer")) {
			ni_parse_uint(val, &eee->tx_lpi.timer, 10);
		} else
		if (ni_string_eq(key, "advertise")) {
			if (!set_ethtool_link_advertise(val, &eee->speed.advertising))
				break;
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse eee '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing eee '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown eee setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_eee(ref, ethtool, eee);
	}
	ni_ethtool_eee_free(eee);
	return ret;
}
Пример #2
0
static int
set_ethtool_pause(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_pause_t *pause;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(pause = ni_ethtool_pause_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "tx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->tx, enabled);
		} else
		if (ni_string_eq(key, "rx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->rx, enabled);
		} else
		if (ni_string_eq(key, "autoneg")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&pause->autoneg, enabled);
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse pause '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing pause '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown pause setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_pause(ref, ethtool, pause);
	}
	ni_ethtool_pause_free(pause);
	return ret;
}
Пример #3
0
/*
 * Discover current IPv6 device settings
 */
int
ni_system_ipv6_devinfo_get(ni_netdev_t *dev, ni_ipv6_devinfo_t *ipv6)
{
	if (ipv6 == NULL)
		ipv6 = ni_netdev_get_ipv6(dev);

	if (!ni_ipv6_supported()) {
		__ni_ipv6_devconf_reset(&ipv6->conf);
		__ni_ipv6_ra_info_reset(&ipv6->radv);
		ipv6->conf.enabled = NI_TRISTATE_DISABLE;
		return 0;
	}

	/*
	 * dhcpcd does something very odd when shutting down an interface;
	 * in addition to removing all IPv4 addresses, it also removes any
	 * IPv6 addresses. The kernel seems to take this as "disable IPv6
	 * on this interface", and subsequently, /proc/sys/ipv6/conf/<ifname>
	 * is gone.
	 * When we bring the interface back up, everything is fine; but until
	 * then we need to ignore this glitch.
	 */
	if (ni_sysctl_ipv6_ifconfig_is_present(dev->name)) {
		int val;

		if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "disable_ipv6", &val) >= 0)
			ni_tristate_set(&ipv6->conf.enabled, !val);

		if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "forwarding", &val) >= 0)
			ni_tristate_set(&ipv6->conf.forwarding, !!val);

		if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "autoconf", &val) >= 0)
			ni_tristate_set(&ipv6->conf.autoconf, !!val);

		if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "accept_redirects", &val) >= 0)
			ni_tristate_set(&ipv6->conf.accept_redirects, !!val);

		if (ni_sysctl_ipv6_ifconfig_get_int(dev->name, "use_tempaddr", &val) >= 0)
			ipv6->conf.privacy = val < -1 ? -1 : (val > 2 ? 2 : val);
	} else {
		ni_warn("%s: cannot get ipv6 device attributes", dev->name);

		/* Reset to defaults */
		__ni_ipv6_devconf_reset(&ipv6->conf);
		__ni_ipv6_ra_info_reset(&ipv6->radv);
	}

	return 0;
}
Пример #4
0
int
ni_system_ipv6_devinfo_set(ni_netdev_t *dev, const ni_ipv6_devconf_t *conf)
{
	ni_ipv6_devinfo_t *ipv6;

	if (!conf || !(ipv6 = ni_netdev_get_ipv6(dev)))
		return -1;

	if (!ni_ipv6_supported()) {
		ipv6->conf.enabled = NI_TRISTATE_DISABLE;
		if (ni_tristate_is_enabled(conf->enabled)) {
			errno = EAFNOSUPPORT;
			return -1;
		}
		return 0;
	}

	if (ni_tristate_is_set(conf->enabled)) {
		if (__ni_system_ipv6_devinfo_change_int(dev->name, "disable_ipv6",
				ni_tristate_is_enabled(conf->enabled) ? 0 : 1) < 0)
			return -1;

		ni_tristate_set(&ipv6->conf.enabled, conf->enabled);
	}

	/* If we're disabling IPv6 on this interface, we're done! */
	if (ni_tristate_is_disabled(conf->enabled)) {
		__ni_ipv6_ra_info_reset(&dev->ipv6->radv);
		return 0;
	}

	if (__ni_system_ipv6_devinfo_change_int(dev->name, "autoconf",
						conf->autoconf) == 0)
		ipv6->conf.autoconf = conf->autoconf;

	if (__ni_system_ipv6_devinfo_change_int(dev->name, "forwarding",
						conf->forwarding) == 0)
		ipv6->conf.forwarding = conf->forwarding;

	if (__ni_system_ipv6_devinfo_change_int(dev->name, "accept_redirects",
						conf->accept_redirects) == 0)
		ipv6->conf.accept_redirects = conf->accept_redirects;

	if (ipv6->conf.privacy != NI_TRISTATE_DEFAULT) {
		/* kernel is using -1 for loopback, ptp, ... */
		if (__ni_system_ipv6_devinfo_change_int(dev->name,
			"use_tempaddr",	conf->privacy) == 0) {
			ipv6->conf.privacy = conf->privacy;
		}
	}

	return 0;
}
Пример #5
0
ni_tristate_t
ni_netdev_guess_link_required(const ni_netdev_t *dev)
{
	ni_tristate_t link_required = NI_TRISTATE_DEFAULT;

	switch (dev->link.type) {
	case NI_IFTYPE_OVS_SYSTEM:
	case NI_IFTYPE_TUN:
	case NI_IFTYPE_TAP:
		ni_tristate_set(&link_required, FALSE);
		break;

	case NI_IFTYPE_BRIDGE:
		if (dev->bridge && dev->bridge->stp && !dev->bridge->ports.count)
			ni_tristate_set(&link_required, FALSE);
		break;

	default:
		break;
	}
	return link_required;
}
Пример #6
0
static dbus_bool_t
ni_objectmodel_ethtool_set_link_settings(ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		const ni_dbus_variant_t *argument,
		DBusError *error)
{
	ni_ethtool_link_settings_t *link;
	const ni_dbus_variant_t *adv;
	uint32_t uv32;
	int32_t sv32;

	if (!(link = ni_objectmodel_ethtool_link_settings_write_handle(object, error)))
		return FALSE;

	if (ni_dbus_dict_get_int32(argument, "autoneg", &sv32) && ni_tristate_is_set(sv32))
		ni_tristate_set(&link->autoneg, sv32);
	if (ni_dbus_dict_get_uint32(argument, "speed",  &uv32) && uv32 <= INT_MAX)
		link->speed  = uv32;
	if (ni_dbus_dict_get_uint32(argument, "duplex", &uv32) && uv32 < NI_ETHTOOL_DUPLEX_UNKNOWN)
		link->duplex = uv32;
	if (ni_dbus_dict_get_uint32(argument, "port",   &uv32) && uv32 <= NI_ETHTOOL_PORT_OTHER)
		link->port   = uv32;

	if (ni_dbus_dict_get_uint32(argument, "mdix", &uv32))
		link->tp_mdix  = uv32;
	if (ni_dbus_dict_get_uint32(argument, "mdio", &uv32))
		link->mdio_support = uv32;
	if (ni_dbus_dict_get_uint32(argument, "phy-address", &uv32))
		link->phy_address  = uv32;
	if (ni_dbus_dict_get_uint32(argument, "transceiver", &uv32))
		link->transceiver  = uv32;

	if ((adv = ni_dbus_dict_get(argument, "advertise"))) {
		/* config */
		ni_objectmodel_ethtool_link_adv_bitfield_from_array(adv,
				&link->advertising, ni_ethtool_link_adv_type);
	} else {
		/* states */
		ni_objectmodel_ethtool_link_adv_from_dict(argument, "supported", &link->supported);
		ni_objectmodel_ethtool_link_adv_from_dict(argument, "advertising", &link->advertising);
		ni_objectmodel_ethtool_link_adv_from_dict(argument, "lp-advertising", &link->lp_advertising);
	}

	return TRUE;
}
Пример #7
0
static int
set_ethtool_coalesce(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_coalesce_t *coalesce;
	char *key = NULL, *val = NULL;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(coalesce = ni_ethtool_coalesce_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;
		if (ni_string_eq(key, "adaptive-rx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&coalesce->adaptive_rx, enabled);
		} else
		if (ni_string_eq(key, "adaptive-tx")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&coalesce->adaptive_tx, enabled);
		} else
		if (ni_string_eq(key, "rx-usecs")) {
			ni_parse_uint(val, &coalesce->rx_usecs, 10);
		} else
		if (ni_string_eq(key, "rx-frames")) {
			ni_parse_uint(val, &coalesce->rx_frames, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-irq")) {
			ni_parse_uint(val, &coalesce->rx_usecs_irq, 10);
		} else
		if (ni_string_eq(key, "rx-frames-irq")) {
			ni_parse_uint(val, &coalesce->rx_frames_irq, 10);
		} else
		if (ni_string_eq(key, "tx-usecs")) {
			ni_parse_uint(val, &coalesce->tx_usecs, 10);
		} else
		if (ni_string_eq(key, "tx-frames")) {
			ni_parse_uint(val, &coalesce->tx_frames, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-irq")) {
			ni_parse_uint(val, &coalesce->tx_usecs_irq, 10);
		} else
		if (ni_string_eq(key, "tx-frames-irq")) {
			ni_parse_uint(val, &coalesce->rx_frames_irq, 10);
		} else
		if (ni_string_eq(key, "stats-block-usecs")) {
			ni_parse_uint(val, &coalesce->stats_block_usecs, 10);
		} else
		if (ni_string_eq(key, "pkt-rate-low")) {
			ni_parse_uint(val, &coalesce->pkt_rate_low, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-low")) {
			ni_parse_uint(val, &coalesce->rx_usecs_low, 10);
		} else
		if (ni_string_eq(key, "rx-frames-low")) {
			ni_parse_uint(val, &coalesce->rx_frames_low, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-low")) {
			ni_parse_uint(val, &coalesce->tx_usecs_low, 10);
		} else
		if (ni_string_eq(key, "tx-frames-low")) {
			ni_parse_uint(val, &coalesce->tx_frames_low, 10);
		} else
		if (ni_string_eq(key, "pkt-rate-high")) {
			ni_parse_uint(val, &coalesce->pkt_rate_high, 10);
		} else
		if (ni_string_eq(key, "rx-usecs-high")) {
			ni_parse_uint(val, &coalesce->rx_usecs_high, 10);
		} else
		if (ni_string_eq(key, "rx-frames-high")) {
			ni_parse_uint(val, &coalesce->rx_frames_high, 10);
		} else
		if (ni_string_eq(key, "tx-usecs-high")) {
			ni_parse_uint(val, &coalesce->tx_usecs_high, 10);
		} else
		if (ni_string_eq(key, "tx-frames-high")) {
			ni_parse_uint(val, &coalesce->tx_frames_high, 10);
		} else
		if (ni_string_eq(key, "sample_interval")) {
			ni_parse_uint(val, &coalesce->sample_interval, 10);
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse coalesce '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing coalesce '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown coalesce setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_coalesce(ref, ethtool, coalesce);
	}
	ni_ethtool_coalesce_free(coalesce);
	return ret;
}
Пример #8
0
static int
set_ethtool_link_settings(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_link_settings_t *link;
	char *key = NULL, *val = NULL;
	unsigned int value;
	ni_bool_t enabled;
	int ret = -1, n;

	if (!(link = ni_ethtool_link_settings_new()))
		return ret;

	for (n = 0; n < args->argc && args->argv[n]; ++n) {
		key = args->argv[n++];
		if (n < args->argc)
			val = args->argv[n];
		else
			break;

		if (ni_string_eq(key, "autoneg")) {
			if (ni_parse_boolean(val, &enabled) != 0)
				break;
			ni_tristate_set(&link->autoneg, enabled);
		} else
		if (ni_string_eq(key, "speed")) {
			if (ni_parse_uint(val, &value, 10) != 0)
				break;
			link->speed = value;
		} else
		if (ni_string_eq(key, "duplex")) {
			if (!ni_ethtool_link_duplex_type(val, &value))
				break;
			link->duplex = value;
		} else
		if (ni_string_eq(key, "port")) {
			if (!ni_ethtool_link_port_type(val, &value))
				break;
			link->port = value;
		} else
		if (ni_string_eq(key, "mdix")) {
			if (!ni_ethtool_link_mdix_type(val, &value))
				break;
			link->tp_mdix = value;
		} else
		if (ni_string_eq(key, "phy-address")) {
			if (ni_parse_uint(val, &value, 10) != 0)
				break;
			link->phy_address = value;
		} else
		if (ni_string_eq(key, "transceiver")) {
			if (!ni_ethtool_link_xcvr_type(val, &value))
				break;
			link->transceiver = value;
		} else
		if (ni_string_eq(key, "advertise")) {
			if (!set_ethtool_link_advertise(val, &link->advertising))
				break;
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse link '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing link '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown link setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_link_settings(ref, ethtool, link);
	}
	ni_ethtool_link_settings_free(link);
	return ret;
}
Пример #9
0
static ni_bool_t
ni_dhcp4_tester_req_xml_init(ni_dhcp4_request_t *req, xml_document_t *doc)
{
	xml_node_t *xml, *child;
	const char *type;

	xml = xml_document_root(doc);
	if (xml && !xml->name && xml->children)
		xml = xml->children;

	if (!xml || !ni_string_eq(xml->name, "request")) {
		ni_error("Invalid dhcp4 request xml '%s'",
				xml ? xml_node_location(xml) : NULL);
		return FALSE;
	}

	type = xml_node_get_attr(xml, "type");
	if (ni_string_eq(type, "offer")) {
		req->dry_run = NI_DHCP4_RUN_OFFER;
	} else
	if (ni_string_eq(type, "lease")) {
		req->dry_run = NI_DHCP4_RUN_LEASE;
	}

	for (child = xml->children; child; child = child->next) {
		if (ni_string_eq(child->name, "uuid")) {
			if (ni_uuid_parse(&req->uuid, child->cdata) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "acquire-timeout")) {
			if (ni_parse_uint(child->cdata, &req->acquire_timeout, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "hostname")) {
			if (!ni_check_domain_name(child->cdata, ni_string_len(child->cdata), 0))
				goto failure;
			ni_string_dup(&req->hostname, child->cdata);
		} else
		if (ni_string_eq(child->name, "fqdn")) {
			const xml_node_t *ptr;

			for (ptr = child->children; ptr; ptr = ptr->next) {
				if (ni_string_eq(ptr->name, "enabled")) {
					ni_bool_t b;
					if (ni_parse_boolean(ptr->cdata, &b) == 0)
						ni_tristate_set(&req->fqdn.enabled, b);
					else
					if (ni_string_eq(ptr->cdata, "default"))
						req->fqdn.enabled = NI_TRISTATE_DEFAULT;
					else
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "update")) {
					if (!ni_dhcp_fqdn_update_name_to_mode(ptr->cdata, &req->fqdn.update))
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "encode")) {
					if (ni_parse_boolean(ptr->cdata, &req->fqdn.encode) != 0)
						goto failure;
				} else
				if (ni_string_eq(ptr->name, "qualify")) {
					if (ni_parse_boolean(ptr->cdata, &req->fqdn.qualify) != 0)
						goto failure;
				}
			}
		} else
		if (ni_string_eq(child->name, "clientid")) {
			ni_opaque_t duid;

			if (ni_parse_hex(child->cdata, duid.data, sizeof(duid.data)) <= 0)
				goto failure;
			ni_string_dup(&req->clientid, child->cdata);
		} else
		if(ni_string_eq(child->name, "start-delay")) {
			if (ni_parse_uint(child->cdata, &req->start_delay, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "lease-time")) {
			if (ni_parse_uint(child->cdata, &req->lease_time, 10) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "recover-lease")) {
			if (ni_parse_boolean(child->cdata, &req->recover_lease) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "release-lease")) {
			if (ni_parse_boolean(child->cdata, &req->release_lease) != 0)
				goto failure;
		} else
		if (ni_string_eq(child->name, "request-options")) {
			xml_node_t *opt;
			for (opt = child->children; opt; opt = opt->next) {
				if (ni_string_empty(opt->cdata))
					continue;
				ni_string_array_append(&req->request_options, opt->cdata);
			}
		}
	}

	return TRUE;
failure:
	if (child) {
		ni_error("Cannot parse dhcp4 request '%s': %s",
				child->name, xml_node_location(child));
	}
	return FALSE;
}