コード例 #1
0
ファイル: leasefile.c プロジェクト: gsanso/wicked
int
__ni_addrconf_lease_nis_domain_from_xml(ni_nis_info_t *nis, const xml_node_t *node)
{
	const xml_node_t *child;
	ni_nis_domain_t *dom = NULL;

	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "domain") && child->cdata) {
			if (!(dom = ni_nis_domain_find(nis, child->cdata)))
				dom = ni_nis_domain_new(nis, child->cdata);
			else
				return -1;
		}
	}
	if (dom) {
		for (child = node->children; child; child = child->next) {
			if (ni_string_eq(child->name, "binding") &&
				!ni_string_empty(child->cdata)) {
				int b = ni_nis_binding_name_to_type(child->cdata);
				if (b != -1) {
					dom->binding = (unsigned int)b;
				}
			}
			if (ni_string_eq(child->name, "server")) {
				if (!ni_string_empty(child->cdata)) {
					ni_string_array_append(&dom->servers,
								child->cdata);
				}
			}
		}
	}
	return dom ? 0 : 1;
}
コード例 #2
0
ファイル: dummy.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
__ni_objectmodel_dummy_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev_ifp = NULL;
	int rv;

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
		    (ifname = ni_netdev_make_name(nc, "dummy", 0))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create dummy interface: "
				"name argument missed");
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_ETHER;
		if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER ||
		    cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create dummy interface: "
				"invalid ethernet address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_dummy_create(nc, cfg_ifp, &dev_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL
		|| (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"Unable to create dummy interface: %s",
					ni_strerror(rv));
			dev_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("dummy interface exists (and name matches)");
	}

	if (dev_ifp->link.type != NI_IFTYPE_DUMMY) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create dummy interface: "
				"new interface is of type %s",
				ni_linktype_type_to_name(dev_ifp->link.type));
		dev_ifp = NULL;
	}

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev_ifp;
}
コード例 #3
0
ファイル: lldp.c プロジェクト: mchf/wicked
/*
 * Verify the LLDP configuration sent by the client
 */
static dbus_bool_t
__ni_objectmodel_lldp_verify(ni_dbus_object_t *object, const ni_dbus_method_t *method,
			const ni_netdev_t *dev, const ni_lldp_t *lldp, DBusError *error)
{
	switch (lldp->chassis_id.type) {
	case NI_LLDP_CHASSIS_ID_INTERFACE_NAME:
		if (lldp->chassis_id.string_value != NULL
		 && !ni_string_eq(lldp->chassis_id.string_value, dev->name)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
						"bad arguments in call to %s.%s(): requesting interface name %s, "
						"which does not match the device name. Consider using default-ifname",
						object->path, method->name, lldp->chassis_id.string_value);
			return FALSE;
		}
		break;

	case NI_LLDP_CHASSIS_ID_INTERFACE_ALIAS:
		if (lldp->chassis_id.string_value == NULL
		 && dev->link.alias == NULL) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
						"bad arguments in call to %s.%s(): requesting default interface alias, "
						"but no alias is set for this device",
						object->path, method->name);
			return FALSE;
		}
		break;

	default:
		break;
	}

	switch (lldp->port_id.type) {
	case NI_LLDP_PORT_ID_INTERFACE_NAME:
		if (lldp->port_id.string_value != NULL
		 && !ni_string_eq(lldp->port_id.string_value, dev->name)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
						"bad arguments in call to %s.%s(): requesting interface name %s, "
						"which does not match the device name. Consider using default-ifname",
						object->path, method->name, lldp->port_id.string_value);
			return FALSE;
		}
		break;

	case NI_LLDP_PORT_ID_INTERFACE_ALIAS:
		if (lldp->port_id.string_value == NULL
		 && dev->link.alias == NULL) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
						"bad arguments in call to %s.%s(): requesting default interface alias, "
						"but no alias is set for this device",
						object->path, method->name);
			return FALSE;
		}
		break;

	default:
		break;
	}

	return TRUE;
}
コード例 #4
0
ファイル: bonding.c プロジェクト: pwieczorkiewicz/wicked
/*
 * Get/set the list of slaves
 */
static dbus_bool_t
__ni_objectmodel_bonding_get_slaves(const ni_dbus_object_t *object,
				const ni_dbus_property_t *property,
				ni_dbus_variant_t *result,
				DBusError *error)
{
	const ni_bonding_t *bond;
	unsigned int i;

	if (!(bond = __ni_objectmodel_bonding_read_handle(object, error)))
		return FALSE;

	ni_dbus_dict_array_init(result);
	for (i = 0; i < bond->slave_names.count; ++i) {
		const char *slave_name = bond->slave_names.data[i];
		ni_dbus_variant_t *slave;

		slave = ni_dbus_dict_array_add(result);

		ni_dbus_dict_add_string(slave, "device", slave_name);
		if (bond->primary_slave && ni_string_eq(bond->primary_slave, slave_name))
			ni_dbus_dict_add_bool(slave, "primary", TRUE);
		if (bond->active_slave && ni_string_eq(bond->active_slave, slave_name))
			ni_dbus_dict_add_bool(slave, "active", TRUE);
	}

	return TRUE;
}
コード例 #5
0
ファイル: naming.c プロジェクト: gsanso/wicked
/*
 * Identify a device by PCI attributes
 */
static ni_bool_t
ni_objectmodel_pci_match_attr(const ni_dbus_object_t *object, const char *name, const char *value)
{
	ni_netdev_t *dev;
	ni_pci_dev_t *pci_dev;

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

	if (!(pci_dev = dev->pci_dev))
		return FALSE;

	if (ni_string_eq(name, "path"))
		return ni_string_eq(pci_dev->path, value);

	/* Bridge means, we match if the query string is a prefix of the device's path */
	if (ni_string_eq(name, "bridge")) {
		unsigned int len;

		if (!value)
			return FALSE;
		len = strlen(value);
		return strncmp(pci_dev->path, value, len) == 0 && pci_dev->path[len] == '/';
	}

	if (ni_string_eq(name, "vendor"))
		return __match_uint(pci_dev->vendor, value);

	if (ni_string_eq(name, "device"))
		return __match_uint(pci_dev->device, value);

	ni_warn("%s: unsupported query attribute %s", __func__, name);
	return FALSE;
}
コード例 #6
0
ファイル: duid.c プロジェクト: mtomaschewski/wicked
static int
ni_do_duid_create(int argc, char **argv)
{
	enum {	OPT_HELP = 'h' };
	static struct option    options[] = {
		{ "help",	no_argument,		NULL,	OPT_HELP	},
		{ NULL,		no_argument,		NULL,	0		}
	};
	int opt = 0, status = NI_WICKED_RC_USAGE;
	const char *type = NULL;
	char *command = NULL;

	optind = 1;
	while ((opt = getopt_long(argc, argv, "+h", options, NULL)) != EOF) {
		switch (opt) {
		case OPT_HELP:
			status = NI_WICKED_RC_SUCCESS;
		default:
		usage:
			fprintf(stderr,
				"Usage: %s [options] <ll|llt|en|uuid> ...\n"
				"\n"
				"Options:\n"
				"  --help, -h           show this help text and exit.\n"
				"\n", argv[0]);
			goto cleanup;
		}
	}
	if (optind >= argc || ni_string_empty(argv[optind])) {
		fprintf(stderr, "%s: missing duid type argument\n\n", argv[0]);
		goto usage;
	}

	type = argv[optind];
	ni_string_printf(&command, "%s %s", argv[0], type);
	argv[optind] = command;

	if (ni_string_eq(type, "ll")) {
		status = ni_do_duid_create_ll(argc - optind, argv + optind);
	} else
	if (ni_string_eq(type, "llt")) {
		status = ni_do_duid_create_llt(argc - optind, argv + optind);
	} else
	if (ni_string_eq(type, "en")) {
		status = ni_do_duid_create_en(argc - optind, argv + optind);
	} else
	if (ni_string_eq(type, "uuid")) {
		status = ni_do_duid_create_uuid(argc - optind, argv + optind);
	} else {
		argv[optind] = (char *)type;
		fprintf(stderr, "%s: unsupported duid type '%s'\n", argv[0],
				ni_print_suspect(type, ni_string_len(type)));
		goto usage;
	}
	argv[optind] = (char *)type;

cleanup:
	ni_string_free(&command);
	return status;
}
コード例 #7
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
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;
}
コード例 #8
0
ファイル: leasefile.c プロジェクト: gsanso/wicked
static int
__ni_addrconf_lease_route_from_xml(ni_route_t *rp, const xml_node_t *node)
{
	const xml_node_t *child;
	ni_sockaddr_t addr;
	unsigned int plen;

	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "destination") && child->cdata) {
			if (!ni_sockaddr_prefix_parse(child->cdata, &addr, &plen))
				return -1;
			if (rp->family != addr.ss_family)
				return -1;
			if ((rp->family == AF_INET  && plen > 32) ||
			    (rp->family == AF_INET6 && plen > 128))
				return -1;
			rp->destination = addr;
			rp->prefixlen = plen;
		} else
		if (ni_string_eq(child->name, "nexthop")) {
			if (__ni_addrconf_lease_route_nh_from_xml(rp, child) != 0)
				return -1;
		}
	}
	return 0;
}
コード例 #9
0
ファイル: infiniband.c プロジェクト: pwieczorkiewicz/wicked
/*
 * InfinibandChild.Factory.newDevice:
 * Create a new infiniband child interface
 */
static ni_netdev_t *
__ni_objectmodel_ib_newchild(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	const ni_infiniband_t *ib;
	const char *err;
	int rv;

	ib = ni_netdev_get_infiniband(cfg);
	if ((err = ni_infiniband_validate(NI_IFTYPE_INFINIBAND_CHILD,
					ib, &cfg->link.lowerdev)) != NULL) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return NULL;
	}

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg->name) &&
		    !ni_string_printf(&cfg->name, "%s.%04x",
					cfg->link.lowerdev.name, ib->pkey)) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create infiniband child: "
				"name argument missed, failed to construct");
			return NULL;
		}
		ifname = NULL;
	} else if (!ni_string_eq(cfg->name, ifname)) {
		ni_string_dup(&cfg->name, ifname);
	}

	if (ni_string_eq(cfg->name, cfg->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Cannot to create infiniband child: "
			"child name %s equal with parent device name",
			cfg->name);
		return NULL;
	}

	if ((rv = ni_system_infiniband_child_create(nc, cfg, &dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || !dev
		|| (ifname && dev && !ni_string_eq(ifname, dev->name))) {
			dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create infiniband child interface: %s",
				ni_strerror(rv));
			return NULL;
		}
	}

	if (dev && dev->link.type != NI_IFTYPE_INFINIBAND_CHILD) {
		dbus_set_error(error,
			DBUS_ERROR_FAILED,
			"Unable to create infiniband child interface %s: it exists with type %s",
			cfg->name, ni_linktype_type_to_name(dev->link.type));
		return NULL;
        }

	return dev;
}
コード例 #10
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
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;
}
コード例 #11
0
ファイル: ethtool.c プロジェクト: mtomaschewski/wicked
int
ni_ethtool_get_driver_info(const char *ifname, ni_ethtool_t *ethtool)
{
	static const ni_ethtool_cmd_info_t NI_ETHTOOL_CMD_GDRVINFO = {
		ETHTOOL_GDRVINFO,      "get driver-info"
	};
	struct ethtool_drvinfo drv_info;
	ni_ethtool_driver_info_t *info;
	int ret;

	if (!ni_ethtool_supported(ethtool, NI_ETHTOOL_SUPP_GET_DRIVER_INFO))
		return -EOPNOTSUPP;

	ni_ethtool_driver_info_free(ethtool->driver_info);
	ethtool->driver_info = NULL;

	memset(&drv_info, 0, sizeof(drv_info));
	ret = ni_ethtool_call(ifname, &NI_ETHTOOL_CMD_GDRVINFO, &drv_info, NULL);
	ni_ethtool_set_supported(ethtool, NI_ETHTOOL_SUPP_GET_DRIVER_INFO,
				ret != -EOPNOTSUPP);
	if (ret < 0)
		return ret;

	if (!(info = ni_ethtool_driver_info_new()))
		return -ENOMEM;

	drv_info.driver[sizeof(drv_info.driver)-1] = '\0';
	if (!ni_string_empty(drv_info.driver) && !ni_string_eq(drv_info.driver, "N/A"))
		ni_string_dup(&info->driver, drv_info.driver);
	drv_info.version[sizeof(drv_info.version)-1] = '\0';
	if (!ni_string_empty(drv_info.version) && !ni_string_eq(drv_info.version, "N/A"))
		ni_string_dup(&info->version, drv_info.version);
	drv_info.fw_version[sizeof(drv_info.fw_version)-1] = '\0';
	if (!ni_string_empty(drv_info.fw_version) && !ni_string_eq(drv_info.fw_version, "N/A"))
		ni_string_dup(&info->fw_version, drv_info.fw_version);
	 drv_info.bus_info[sizeof(drv_info.bus_info)-1] = '\0';
	 if (!ni_string_empty(drv_info.bus_info) && !ni_string_eq(drv_info.bus_info, "N/A"))
		 ni_string_dup(&info->bus_info, drv_info.bus_info);
	 drv_info.erom_version[sizeof(drv_info.erom_version)-1] = '\0';
	 if (!ni_string_empty(drv_info.erom_version) && !ni_string_eq(drv_info.erom_version, "N/A"))
		 ni_string_dup(&info->erom_version, drv_info.erom_version);

	if ((info->supports.n_priv_flags = drv_info.n_priv_flags))
		info->supports.bitmap |= NI_BIT(NI_ETHTOOL_DRIVER_SUPP_PRIV_FLAGS);
	if ((info->supports.n_stats = drv_info.n_stats))
		info->supports.bitmap |= NI_BIT(NI_ETHTOOL_DRIVER_SUPP_STATS);
	if ((info->supports.testinfo_len = drv_info.testinfo_len))
		info->supports.bitmap |= NI_BIT(NI_ETHTOOL_DRIVER_SUPP_TEST);
	if ((info->supports.eedump_len = drv_info.eedump_len))
		info->supports.bitmap |= NI_BIT(NI_ETHTOOL_DRIVER_SUPP_EEPROM);
	if ((info->supports.regdump_len = drv_info.regdump_len))
		info->supports.bitmap |= NI_BIT(NI_ETHTOOL_DRIVER_SUPP_REGDUMP);

	ethtool->driver_info = info;

	return 0;
}
コード例 #12
0
ファイル: fsm.c プロジェクト: pwieczorkiewicz/wicked
int
ni_dhcp4_fsm_recover_lease(ni_dhcp4_device_t *dev, const ni_dhcp4_request_t *req)
{
	ni_addrconf_lease_t *lease;
	time_t now = time(NULL), then;

	/* Don't recover anything if we already have a lease attached. */
	if (dev->lease != NULL)
		return -1;

	lease = ni_addrconf_lease_file_read(dev->ifname, NI_ADDRCONF_DHCP, AF_INET);
	if (!lease)
		return -1;

	if (lease->state != NI_ADDRCONF_STATE_GRANTED)
		goto discard;

	ni_debug_dhcp("trying to recover dhcp4 lease, now inspecting");
	then = lease->time_acquired;
	if (now < then) {
		ni_debug_dhcp("%s: found time-warped lease (hi, grand-grand-pa)", __FUNCTION__);
		goto discard;
	}

	if (now >= then + lease->dhcp4.lease_time) {
		ni_debug_dhcp("%s: found expired lease", __FUNCTION__);
		goto discard;
	}

	if ((req->hostname && !ni_string_eq(req->hostname, dev->lease->hostname))
	 || (req->clientid && !ni_string_eq(req->clientid, dev->lease->dhcp4.client_id))) {
		ni_debug_dhcp("%s: lease doesn't match request", __FUNCTION__);
		goto discard;
	}

	ni_dhcp4_device_set_lease(dev, lease);

	if (now >= then + lease->dhcp4.rebind_time) {
		ni_dhcp4_fsm_rebind(dev);
	} else
	if (now >= then + lease->dhcp4.renewal_time) {
		ni_dhcp4_fsm_renewal(dev);
	} else {
		ni_dhcp4_fsm_set_deadline(dev, then + lease->dhcp4.renewal_time);
		dev->fsm.state = NI_DHCP4_STATE_BOUND;
	}

	ni_debug_dhcp("%s: recovered old lease; now in state=%s",
			dev->ifname, ni_dhcp4_fsm_state_name(dev->fsm.state));
	dev->notify = 1;
	return 0;

discard:
	ni_addrconf_lease_free(lease);
	return -1;
}
コード例 #13
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
static int
set_ethtool_wake_on_lan(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_wake_on_lan_t *wol;
	char *key = NULL, *val = NULL;
	int ret = -1, n;

	if (!(wol = ni_ethtool_wake_on_lan_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, "options")) {
			if (!set_ethtool_wake_on_lan_options(wol, val))
				break;
		} else
		if (ni_string_eq(key, "sopass")) {
			if (ni_link_address_parse(&wol->sopass, ARPHRD_ETHER, val) < 0)
				break;
		} else {
			val = key;
			key = NULL;
		}

		key = NULL;
		val = NULL;
	}

	if (wol->sopass.len && !(wol->options & NI_BIT(NI_ETHTOOL_WOL_SECUREON)))
		wol->options |= NI_BIT(NI_ETHTOOL_WOL_SECUREON);

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse wake-on-lan %s' value argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing wake-on-lan '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown wake-on-lan setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_wake_on_lan(ref, ethtool, wol);
	}

	ni_ethtool_wake_on_lan_free(wol);
	return ret;
}
コード例 #14
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
static int
set_ethtool_channels(const ni_netdev_ref_t *ref, ni_ethtool_t *ethtool, struct ethtool_args *args)
{
	ni_ethtool_channels_t *channels;
	char *key = NULL, *val = NULL;
	int ret = -1, n;

	if (!(channels = ni_ethtool_channels_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")) {
			ni_parse_uint(val, &channels->tx, 10);
		} else
		if (ni_string_eq(key, "rx")) {
			ni_parse_uint(val, &channels->rx, 10);
		} else
		if (ni_string_eq(key, "other")) {
			ni_parse_uint(val, &channels->other, 10);
		} else
		if (ni_string_eq(key, "combined")) {
			ni_parse_uint(val, &channels->combined, 10);
		} else {
			val = key;
			key = NULL;
			break;
		}

		key = NULL;
		val = NULL;
	}

	if (key) {
		if (val)
			fprintf(stderr, "%s: cannot parse channels '%s' argument '%s'\n",
					ref->name, key, val);
		else
			fprintf(stderr, "%s: missing channels '%s' value argument\n",
					ref->name, key);
	} else {
		if (val)
			fprintf(stderr, "%s: unknown channels setting name '%s'\n",
					ref->name, val);
		else
			ret = ni_ethtool_set_channels(ref, ethtool, channels);
	}
	ni_ethtool_channels_free(channels);
	return ret;
}
コード例 #15
0
ファイル: teamd-test.c プロジェクト: gsanso/wicked
int main(int argc, char **argv)
{
	ni_teamd_client_t *tdc;
	const char *command, *param1, *param2;
	char *val = NULL;
	ni_json_t *json;
	int rv = 0;

	if (argc < 3) {
		printf("Usage: teamd-test ifname command [param1] [param2]\n");
		return -2;
	}
	command = argv[2];
	param1 = argv[3];
	param2 = argv[4];

	if (ni_init("teamd-test") < 0)
		return -1;
	ni_config_teamd_enable(NI_CONFIG_TEAMD_CTL_DETECT_ONCE);

	tdc = ni_teamd_client_open(argv[1]);

	if (ni_string_eq(command, "state-item-get"))
		rv = ni_teamd_ctl_state_get_item(tdc, param1, &val);
	else if (ni_string_eq(command, "state-item-set"))
		rv = ni_teamd_ctl_state_set_item(tdc, param1, param2);
	else if (ni_string_eq(command, "state-dump"))
		rv = ni_teamd_ctl_state_dump(tdc, &val);
	else if (ni_string_eq(command, "config-dump"))
		rv = ni_teamd_ctl_config_dump(tdc, FALSE, &val);
	else if (ni_string_eq(command, "config-dump-actual"))
		rv = ni_teamd_ctl_config_dump(tdc, TRUE, &val);

	printf("%s\n", val ? val : ni_format_boolean(!!rv));

	if (val && (json = ni_json_parse_string(val))) {
		ni_stringbuf_t buf = NI_STRINGBUF_INIT_DYNAMIC;

		ni_json_format_string(&buf, json, NULL);
		printf("type<%s>: %s\n",
			ni_json_type_name(ni_json_type(json)), buf.string);
		ni_stringbuf_destroy(&buf);
		ni_json_free(json);
	} else if (val) {
		printf("json parsing error\n");
	}

	ni_string_free(&val);
	return rv;
}
コード例 #16
0
ファイル: lease.c プロジェクト: nirmoy/wicked
static int
__ni_dhcp6_lease_ia_addr_from_xml(ni_dhcp6_ia_addr_t *iadr, unsigned int type,
					const xml_node_t *node)
{
	const xml_node_t *child;
	const char *name;
	ni_sockaddr_t addr;
	unsigned int value;

	name = (type == NI_DHCP6_OPTION_IA_PD) ? "prefix" : "address";
	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, name) && child->cdata) {
			if (type == NI_DHCP6_OPTION_IA_PD) {
				if (!ni_sockaddr_prefix_parse(child->cdata,
							&addr, &value)
					|| value == 0 || value > 128
					|| addr.ss_family != AF_INET6)
					return -1;
				iadr->addr = addr.six.sin6_addr;
				iadr->plen = value;
			} else {
				if (ni_sockaddr_parse(&addr, child->cdata,
							AF_INET6) != 0)
					return -1;
				iadr->addr = addr.six.sin6_addr;
				iadr->plen = 0;
			}
		} else
		if (ni_string_eq(child->name, "preferred-lft") && child->cdata) {
			if (ni_parse_uint(child->cdata, &value, 10) != 0)
				return -1;
			iadr->preferred_lft = value;
		} else
		if (ni_string_eq(child->name, "valid-lft") && child->cdata) {
			if (ni_parse_uint(child->cdata, &value, 10) != 0)
				return -1;
			iadr->valid_lft = value;
		} else
		if (ni_string_eq(child->name, "status")) {
			if (__ni_dhcp6_lease_status_from_xml(&iadr->status, child) < 0)
				return -1;
		}
	}

	ni_sockaddr_set_ipv6(&addr, iadr->addr, 0);
	if (ni_sockaddr_is_ipv6_specified(&addr))
		return 0;
	else
		return 1;
}
コード例 #17
0
ファイル: json.c プロジェクト: gsanso/wicked
ni_json_t *
ni_json_new_literal(const char *string)
{
	if (ni_string_eq("null", string))
		return ni_json_new_null();

	if (ni_string_eq("true", string))
		return ni_json_new_bool(TRUE);

	if (ni_string_eq("false", string))
		return ni_json_new_bool(FALSE);

	return NULL;
}
コード例 #18
0
ファイル: lease.c プロジェクト: nirmoy/wicked
int
__ni_dhcp6_lease_boot_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node)
{
	xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "url") && child->cdata) {
			ni_string_dup(&lease->dhcp6.boot_url, child->cdata);
		} else
		if (ni_string_eq(child->name, "param") && child->cdata) {
			ni_string_array_append(&lease->dhcp6.boot_params, child->cdata);
		}
	}
	return 0;
}
コード例 #19
0
static ni_bool_t
ni_set_global_config_dir(const char *pathname)
{
	if (pathname == NULL) {
		ni_string_free(&ni_global.config_dir);
		ni_string_free(&ni_global.config_path);
		return TRUE;
	}

	if (ni_isdir(pathname)) {
		char *real = NULL;

		if (*pathname != '/') {
			/* resolve to absolute path */
			if (ni_realpath(pathname, &real) == NULL)
				return FALSE;
			pathname = real;
		}

		if (ni_string_eq(WICKED_CONFIGDIR, pathname))
			pathname = NULL;

		ni_string_dup(&ni_global.config_dir, pathname);
		ni_string_free(&real);

		return TRUE;
	}
	errno = ENOTDIR;
	return FALSE;
}
コード例 #20
0
ファイル: iaid.c プロジェクト: mtomaschewski/wicked
ni_bool_t
ni_iaid_map_set(ni_iaid_map_t *map, const char *name, unsigned int iaid)
{
	xml_node_t *root, *node = NULL;
	const char *attr;

	if (!(root = ni_iaid_map_root_node(map)) || ni_string_empty(name))
		return FALSE;

	while ((node = ni_iaid_map_next_node(root, node))) {
		attr = xml_node_get_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE);
		if (!ni_string_eq(name, attr))
			continue;

		xml_node_set_uint(node, iaid);
		return TRUE;
	}

	if ((node = xml_node_new(NI_CONFIG_DEFAULT_IAID_NODE, root))) {
		xml_node_add_attr(node, NI_CONFIG_DEFAULT_IAID_DEVICE, name);
		xml_node_set_uint(node, iaid);
		return TRUE;
	}
	return FALSE;
}
コード例 #21
0
ファイル: state.c プロジェクト: gsanso/wicked
static ni_bool_t
ni_objectmodel_recover_state_xml(xml_node_t *list, const char **prefix_list)
{
	ni_dbus_object_t *root_object;
	xml_node_t *object_node;

	root_object = ni_dbus_server_get_root_object(__ni_objectmodel_server);
	for (object_node = list->children; object_node; object_node = object_node->next) {
		ni_dbus_object_t *object;
		const char *name;

		if (!ni_string_eq(object_node->name, "object")) {
			ni_error("%s: not an <object> element", xml_node_location(object_node));
			return FALSE;
		}

		if (!(name = xml_node_get_attr(object_node, "path"))) {
			ni_error("%s: <object> lacks path attribute", xml_node_location(object_node));
			return FALSE;
		}
		if (!(name = ni_dbus_object_get_relative_path(root_object, name))) {
			ni_error("%s: <object> has invalid path attribute", xml_node_location(object_node));
			return FALSE;
		}

		if (!(object = ni_dbus_object_lookup(root_object, name)))
			continue;

		if (!ni_objectmodel_recover_object_state_xml(object_node, object, prefix_list))
			return FALSE;

	}

	return TRUE;
}
コード例 #22
0
ファイル: leasefile.c プロジェクト: gsanso/wicked
int
ni_addrconf_lease_ptz_data_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node)
{
	const xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "posix-string") &&
		    !ni_string_empty(child->cdata)) {
			ni_string_dup(&lease->posix_tz_string, child->cdata);
		} else
		if (ni_string_eq(child->name, "posix-dbname") &&
		    !ni_string_empty(child->cdata)) {
			ni_string_dup(&lease->posix_tz_dbname, child->cdata);
		}
	}
	return 0;
}
コード例 #23
0
ファイル: leasefile.c プロジェクト: gsanso/wicked
int
ni_addrconf_lease_nds_data_from_xml(ni_addrconf_lease_t *lease, const xml_node_t *node)
{
	const xml_node_t *child;

	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "tree") && !ni_string_empty(child->cdata)) {
			ni_string_dup(&lease->nds_tree, child->cdata);
		} else
		if (ni_string_eq(child->name, "server") && !ni_string_empty(child->cdata)) {
			ni_string_array_append(&lease->nds_servers, child->cdata);
		} else
		if (ni_string_eq(child->name, "context") && !ni_string_empty(child->cdata)) {
			ni_string_array_append(&lease->nds_context, child->cdata);
		}
	}
	return 0;
}
コード例 #24
0
ファイル: duid.c プロジェクト: mtomaschewski/wicked
static int
ni_do_duid_del(int argc, char **argv)
{
	enum {	OPT_HELP = 'h', OPT_SCOPE = 's' };
	static struct option    options[] = {
		{ "help",	no_argument,		NULL,	OPT_HELP	},
		{ "scope",	required_argument,	NULL,	OPT_SCOPE	},
		{ NULL,		no_argument,		NULL,	0		}
	};
	int opt = 0, status = NI_WICKED_RC_USAGE;
	ni_duid_map_t *map = NULL;
	const char *scope = NULL;

	optind = 1;
	while ((opt = getopt_long(argc, argv, "+hs:", options, NULL)) != EOF) {
		switch (opt) {
		case OPT_SCOPE:
			if (optarg && !ni_string_eq(optarg, "default"))
				scope = optarg;
			break;
		case OPT_HELP:
			status = NI_WICKED_RC_SUCCESS;
		default:
		usage:
			fprintf(stderr,
				"Usage: %s [options]\n"
				"\n"
				"Options:\n"
				"  --help, -h           show this help text and exit.\n"
				"  --scope <ifname>     delete device specific duid instead of default\n"
				"\n", argv[0]);
			goto cleanup;
		}
	}
	if (argc - optind)
		goto usage;

	if (scope && !ni_netdev_name_is_valid(scope)) {
		fprintf(stderr, "%s: invalid scope interface name '%s'\n", argv[0],
				ni_print_suspect(scope, ni_string_len(scope)));
		status = NI_WICKED_RC_ERROR;
		goto cleanup;
	}

	status = NI_WICKED_RC_ERROR;
	if (!(map = ni_duid_map_load(NULL)))
		goto cleanup;

	if (ni_duid_map_del(map, scope)) {
		if (ni_duid_map_save(map))
			status = NI_WICKED_RC_SUCCESS;
	}

cleanup:
	ni_duid_map_free(map);
	return status;
}
コード例 #25
0
ファイル: logging.c プロジェクト: hwoarang/wicked
void
ni_log_init(void)
{
	const char *var = getenv("WICKED_DEBUG");

	if (ni_string_empty(var) && (var = getenv("DEBUG"))) {
		if (ni_string_eq(var, "no"))
			var = "";
		else
		if (ni_string_eq(var, "yes"))
			var = "most";
	}
	if (!ni_string_empty(var))
		ni_enable_debug(var);

	if ((var = getenv("WICKED_LOG_LEVEL"))) {
		ni_log_level_set(var);
	}
}
コード例 #26
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
static ni_bool_t
set_ethtool_wake_on_lan_options(ni_ethtool_wake_on_lan_t *wol, const char *value)
{
	ni_string_array_t tmp = NI_STRING_ARRAY_INIT;
	unsigned int i, flag;
	unsigned int options;
	ni_bool_t ret = TRUE;

	if (!ni_string_split(&tmp, value, ",|", 0))
		return FALSE;

	if (tmp.count == 1) {
		value = tmp.data[0];

		if (set_ethtool_wake_on_lan_letterjam(wol, value))
			goto cleanup;
	}

	options = NI_ETHTOOL_WOL_DISABLE;
	for (i = 0; i < tmp.count; ++i) {
		value = tmp.data[i];

		if (ni_string_eq(value, "d") ||
		    ni_string_eq(value, "disable") ||
		    ni_string_eq(value, "disabled")) {
			wol->options = NI_ETHTOOL_WOL_DISABLE;
			break;
		}

		if (ni_ethtool_wol_flag_type(value, &flag))
			options |= NI_BIT(flag);
		else
			ret = FALSE;
	}

	if (ret && wol->options == NI_ETHTOOL_WOL_DEFAULT)
		wol->options = options;

cleanup:
	ni_string_array_destroy(&tmp);
	return ret;
}
コード例 #27
0
ファイル: lease.c プロジェクト: nirmoy/wicked
/*
 * dhcp6 lease data from xml
 */
static int
__ni_dhcp6_lease_status_from_xml(ni_dhcp6_status_t *status, const xml_node_t *node)
{
	const xml_node_t *child;
	unsigned int value;

	ni_dhcp6_status_clear(status);
	for (child = node->children; child; child = child->next) {
		if (ni_string_eq(child->name, "code")) {
			if (ni_parse_uint(child->cdata, &value, 10) != 0
					|| value > 0xffff)
				return -1;
			status->code = value;
		} else
		if (ni_string_eq(child->name, "message") && child->cdata) {
			ni_string_dup(&status->message, child->cdata);
		}
	}
	return 0;
}
コード例 #28
0
ファイル: ethtool.c プロジェクト: openSUSE/wicked
const struct ethtool_opt *
ethtool_opt_find(const struct ethtool_opt *opts, const char *name)
{
	const struct ethtool_opt *opt;

	for (opt = opts; opt && opt->name; opt++) {
		if (opt->func && ni_string_eq(opt->name, name))
			return opt;
	}
	return NULL;
}
コード例 #29
0
ファイル: bridge.c プロジェクト: mijos/wicked
unsigned int
ni_bridge_waittime_from_xml(const xml_node_t *brnode)
{
	unsigned int waittime = 0;
	ni_bridge_t bridge;
	xml_node_t *child;

	if (xml_node_is_empty(brnode))
		return waittime;

	__ni_bridge_init(&bridge);
	for (child = brnode->children; child; child = child->next) {
		if (ni_string_eq(child->name, "stp")) {
			if (ni_parse_boolean(child->cdata, &bridge.stp))
				continue;
		} else
		if (ni_string_eq(child->name, "forward-delay")) {
			if (ni_parse_double(child->cdata, &bridge.forward_delay))
				continue;

			if (bridge.forward_delay > NI_BRIDGE_FORWARD_DELAY_MAX)
				bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MAX;
			else
			if (bridge.forward_delay < NI_BRIDGE_FORWARD_DELAY_MIN)
				bridge.forward_delay = NI_BRIDGE_FORWARD_DELAY_MIN;
		} else
		if (ni_string_eq(child->name, "max-age")) {
			if (ni_parse_double(child->cdata, &bridge.max_age))
				continue;

			if (bridge.max_age > NI_BRIDGE_MAX_AGE_MAX)
				bridge.max_age = NI_BRIDGE_MAX_AGE_MAX;
			else
			if (bridge.max_age < NI_BRIDGE_MAX_AGE_MIN)
				bridge.max_age = NI_BRIDGE_MAX_AGE_MIN;
		}
	}

	waittime = ni_bridge_waittime(&bridge);
	return waittime;
}
コード例 #30
0
ファイル: netdev.c プロジェクト: mtomaschewski/wicked
ni_addrconf_lease_t *
ni_netdev_get_lease_by_owner(ni_netdev_t *dev, const char *owner)
{
	ni_addrconf_lease_t *lease;

	for (lease = dev->leases; lease; lease = lease->next) {
		if (ni_string_eq(lease->owner, owner))
			return lease;
	}

	return NULL;
}