Beispiel #1
0
/*
 * ethtool.changeDevice method
 */
static dbus_bool_t
ni_objectmodel_ethtool_setup(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, *cfg;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

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

	if (!(cfg = ni_objectmodel_ethtool_request_arg(&argv[0]))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		return FALSE;
	}

	if (ni_system_ethtool_setup(NULL, dev, cfg) < 0)  {
		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to apply ethtool settings");
		ni_netdev_put(cfg);
		return FALSE;
	}

	ni_netdev_put(cfg);
	return TRUE;
}
Beispiel #2
0
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;
}
Beispiel #3
0
/*
 * PPP.changeDevice method
 */
static dbus_bool_t
ni_objectmodel_ppp_device_change(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_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *ifp, *cfg;
	dbus_bool_t rv = FALSE;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

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

	if (!(cfg = ni_objectmodel_ppp_device_arg(&argv[0]))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		goto out;
	}

	if (ni_system_ppp_setup(nc, ifp, cfg) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to set up ppp device");
		goto out;
	}

	rv = TRUE;
out:
	if (cfg)
		ni_netdev_put(cfg);
	return rv;
}
Beispiel #4
0
/*
 * Create a new ppp interface
 */
static dbus_bool_t
ni_objectmodel_ppp_device_new(ni_dbus_object_t *factory_object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_dbus_server_t *server = ni_dbus_object_get_server(factory_object);
	ni_netdev_t *dev, *cfg;
	const char *ifname = NULL;

	if (argc != 2)
		goto error;

	if (!ni_dbus_variant_get_string(&argv[0], &ifname))
		goto error;

	if (!(cfg = ni_objectmodel_ppp_device_arg(&argv[1])))
		goto error;

	dev = ni_objectmodel_ppp_device_create(cfg, ifname, error);
	ni_netdev_put(cfg);

	if (dev)
		return ni_objectmodel_netif_factory_result(server, reply, dev, NULL, error);
	else
		return FALSE;

error:
	return ni_dbus_error_invalid_args(error, factory_object->path, method->name);
}
Beispiel #5
0
Datei: ppp.c Projekt: mchf/wicked
/*
 * Create a new PPP interface
 * We're given two arguments, the interface name and the <ppp> configuration data.
 * However, we ignore all the config data at this point and just create the
 * device. The configuration data is consumed by a subsequent call to changeDevice
 * (where we build a config file from it).
 */
dbus_bool_t
ni_objectmodel_ppp_newlink(ni_dbus_object_t *factory_object, const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error,
			__get_device_arg_fn_t get_device_arg_fn)
{
	ni_dbus_server_t *server = ni_dbus_object_get_server(factory_object);
	const char *ifname = NULL;
	ni_netdev_t *dev, *dev_cfg;

	NI_TRACE_ENTER();

	ni_assert(argc == 2);
	if (!ni_dbus_variant_get_string(&argv[0], &ifname))
		return ni_dbus_error_invalid_args(error, factory_object->path, method->name);
	if (!(dev_cfg = get_device_arg_fn(&argv[1], error)))
		return FALSE;

	dev = __ni_objectmodel_ppp_newlink(dev_cfg, ifname, error);
	ni_netdev_put(dev_cfg);

	if (dev == NULL)
		return FALSE;

	return ni_objectmodel_netif_factory_result(server, reply, dev, NULL, error);
}
Beispiel #6
0
static dbus_bool_t
__ni_objectmodel_tuntap_newlink(ni_iftype_t iftype, ni_dbus_object_t *factory_object,
			const ni_dbus_method_t *method,
			unsigned int argc, const ni_dbus_variant_t *argv,
			ni_dbus_message_t *reply, DBusError *error)
{
	ni_dbus_server_t *server = ni_dbus_object_get_server(factory_object);
	const char *ifname = NULL;
	ni_netdev_t *dev;
	ni_netdev_t *cfg;

	NI_TRACE_ENTER();
	ni_assert(argc == 2);

	if (!ni_dbus_variant_get_string(&argv[0], &ifname) ||
	    !(cfg = __ni_objectmodel_tuntap_device_arg(&argv[1], iftype))) {
		return ni_dbus_error_invalid_args(error,
						factory_object->path,
						method->name);
	}

	ni_string_dup(&cfg->name, ifname);
	dev = __ni_objectmodel_tuntap_create(cfg, error);

	ni_netdev_put(cfg);
	if (!dev)
		return FALSE;
	return ni_objectmodel_netif_factory_result(server, reply, dev, NULL, error);
}
Beispiel #7
0
static ni_netdev_t *
__ni_objectmodel_team_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	int rv;

	ni_netdev_get_team(cfg_ifp);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "team", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface - too many interfaces");
		goto out;
	}
	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 team interface: invalid ethernet address '%s'",
					ni_link_address_print(&cfg_ifp->link.hwaddr));
			goto out;
		}
	}

	if ((rv = ni_system_team_create(nc, cfg_ifp, &new_ifp)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create team interface '%s'", cfg_ifp->name);
		new_ifp = NULL;
		goto out;
#if 0
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create team interface: %s",
					ni_strerror(rv));
			goto out;
		}
		ni_debug_dbus("Bonding interface exists (and name matches)");
#endif
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Beispiel #8
0
void
ni_compat_netdev_free(ni_compat_netdev_t *compat)
{
	ni_netdev_put(compat->dev);

	/* FIXME: clean up the rest */

	free(compat);
}
Beispiel #9
0
/*
 * Functions for handling lists of interfaces
 */
void
__ni_netdev_list_destroy(ni_netdev_t **list)
{
	ni_netdev_t *dev;

	while ((dev = *list) != NULL) {
		*list = dev->next;
		ni_netdev_put(dev);
	}
}
Beispiel #10
0
void
ni_netconfig_device_remove(ni_netconfig_t *nc, ni_netdev_t *dev)
{
	ni_netdev_t **pos, *cur;

	for (pos = &nc->interfaces; (cur = *pos) != NULL; pos = &cur->next) {
		if (cur == dev) {
			*pos = cur->next;
			ni_netdev_put(cur);
			return;
		}
	}
}
Beispiel #11
0
/*
 * Infiniband(Child).changeDevice method
 */
static dbus_bool_t
ni_objectmodel_ib_setup(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_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *ifp, *cfg;
	dbus_bool_t rv = FALSE;

	/* we've already checked that argv matches our signature */
	if (argc != 1 || !(ifp = ni_objectmodel_unwrap_netif(object, error)))
		return FALSE;

	if (ifp->link.type == NI_IFTYPE_INFINIBAND) {
		cfg = __ni_objectmodel_ibparent_device_arg(&argv[0]);
	} else
	if (ifp->link.type == NI_IFTYPE_INFINIBAND_CHILD) {
		cfg = __ni_objectmodel_ibchild_device_arg(&argv[0]);
	} else {
		cfg = NULL;
	}
	if (!cfg) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		goto out;
	}

	/* when <infiniband/> node is empty (defaults only), skip setup */
	if (cfg->infiniband) {
		const char *err;

		if ((err = ni_infiniband_validate(ifp->link.type, cfg->infiniband,
							&cfg->link.lowerdev))) {
			dbus_set_error(error, DBUS_ERROR_FAILED, "%s", err);
			goto out;
		}

		if (ni_system_infiniband_setup(nc, ifp, cfg) < 0) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
					"failed to configure infiniband device %s",
					ifp->name);
			goto out;
		}
	}

	rv = TRUE;
out:
	if (cfg)
		ni_netdev_put(cfg);
	return rv;
}
Beispiel #12
0
static ni_netdev_t *
__ni_objectmodel_tun_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_tun_t *tun;
	const char *err;
	int rv;

	/* There's nothing in the device argument that we could use. */

	ni_debug_dbus("TUN.newDevice(name=%s)", ifname);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "tun", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create tun - too many interfaces");
		goto out;
	}

	tun = ni_netdev_get_tun(cfg_ifp);
	if ((err = ni_tun_validate(tun))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

	if ((rv = ni_system_tun_create(nc, ifname, tun, &new_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || new_ifp == NULL
		|| (ifname && new_ifp && !ni_string_eq(new_ifp->name, ifname))) {
			ni_dbus_set_error_from_code(error, rv,
					"unable to create TUN interface %s",
					ifname);
			new_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("TUN interface exists (and name matches)");
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Beispiel #13
0
static dbus_bool_t
ni_objectmodel_ib_newchild(ni_dbus_object_t *factory_object, const ni_dbus_method_t *method,
				unsigned int argc, const ni_dbus_variant_t *argv,
				ni_dbus_message_t *reply, DBusError *error)
{
	ni_dbus_server_t *server = ni_dbus_object_get_server(factory_object);
	ni_netdev_t *cfg, *dev;
	const char *ifname = NULL;

	NI_TRACE_ENTER();

	if (argc != 2 || !ni_dbus_variant_get_string(&argv[0], &ifname) || !ifname ||
	    !(cfg = __ni_objectmodel_ibchild_device_arg(&argv[1]))) {
		return ni_dbus_error_invalid_args(error, factory_object->path, method->name);
	}

	if (!(dev = __ni_objectmodel_ib_newchild(cfg, ifname, error))) {
		ni_netdev_put(cfg);
		return FALSE;
	}
	ni_netdev_put(cfg);

	return ni_objectmodel_netif_factory_result(server, reply, dev, NULL, error);
}
Beispiel #14
0
static ni_netdev_t *
__ni_objectmodel_bond_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_bonding_t *bond;
	int rv;

	bond = ni_netdev_get_bonding(cfg_ifp);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "bond", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bonding interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_bond_create(nc, cfg_ifp->name, bond, &new_ifp)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create bonding interface '%s'", cfg_ifp->name);
		new_ifp = NULL;
		goto out;
#if 0
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create bonding interface: %s",
					ni_strerror(rv));
			goto out;
		}
		ni_debug_dbus("Bonding interface exists (and name matches)");
#endif
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Beispiel #15
0
/*
 * LLDP.lldpUp
 */
static dbus_bool_t
ni_objectmodel_lldp_up(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, *cfg;
	dbus_bool_t rv = FALSE;

	/* we've already checked that argv matches our signature */
	ni_assert(argc == 1);

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

	ni_debug_lldp("ni_objectmodel_lldp_up(%s -> %s)", object->path, dev->name);

	if (!ni_system_lldp_available(dev)) {
		ni_error("Cannot enable LLDP for device %s: incompatible layer 2 protocol", dev->name);
		return TRUE;
	}

	if (!(cfg = __ni_objectmodel_protocol_arg(&argv[0], &ni_objectmodel_lldp_service))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		goto out;
	}

	if (cfg->lldp
	 && !__ni_objectmodel_lldp_verify(object, method, dev, cfg->lldp, error))
		goto out;

	if (ni_system_lldp_up(dev, cfg->lldp) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to set up LLDP on device %s", dev->name);
		goto out;
	}

	rv = TRUE;

out:
	if (cfg)
		ni_netdev_put(cfg);
	return rv;
}
Beispiel #16
0
/*
 * Common helper function to extract some specific properties of device info from a dbus dict
 */
static ni_netdev_t *
__ni_objectmodel_protocol_arg(const ni_dbus_variant_t *dict, const ni_dbus_service_t *service)
{
	ni_dbus_object_t *dev_object;
	ni_netdev_t *dev;
	dbus_bool_t rv;

	dev = ni_netdev_new(NULL, 0);
	dev->link.type = NI_IFTYPE_ETHERNET;

	dev_object = ni_objectmodel_wrap_netif(dev);
	rv = ni_dbus_object_set_properties_from_dict(dev_object, service, dict, NULL);
	ni_dbus_object_free(dev_object);

	if (!rv) {
		ni_netdev_put(dev);
		dev = NULL;
	}
	return dev;
}
Beispiel #17
0
static ni_netdev_t *
__ni_objectmodel_ovs_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	int rv;

	ni_netdev_get_ovs_bridge(cfg_ifp);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ovsbr", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ovs bridge interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_ovs_bridge_create(nc, cfg_ifp, &new_ifp)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || new_ifp == NULL
		|| (ifname && new_ifp && !ni_string_eq(ifname, new_ifp->name))) {
			dbus_set_error(error,
					DBUS_ERROR_FAILED,
					"Unable to create OVS bridge device: %s",
					ni_strerror(rv));
			new_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("OVS bridge device %s exists (and with correct type)", ifname);
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Beispiel #18
0
static ni_netdev_t *
__ni_objectmodel_bridge_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_ifp = NULL;
	const ni_bridge_t *bridge;
	int rv;

	bridge = ni_netdev_get_bridge(cfg_ifp);

	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "br", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create bridging interface - too many interfaces");
		goto out;
	}
	ni_string_dup(&cfg_ifp->name, ifname);

	if ((rv = ni_system_bridge_create(nc, cfg_ifp->name, bridge, &new_ifp)) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create bridging interface: %s",
				ni_strerror(rv));
		new_ifp = NULL;
		goto out;
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return new_ifp;
}
Beispiel #19
0
static ni_netdev_t *
__ni_objectmodel_macvlan_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;
	const ni_macvlan_t *macvlan;
	const char *err;
	const char *cfg_ifp_iftype = NULL;
	int rv;

	cfg_ifp_iftype = ni_linktype_type_to_name(cfg_ifp->link.type);

	if (ni_string_empty(cfg_ifp->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Incomplete arguments: need a lower device name");
		return NULL;
	} else
	if (!ni_netdev_ref_bind_ifindex(&cfg_ifp->link.lowerdev, nc)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Unable to find %s lower device %s by name",
			cfg_ifp_iftype,
			cfg_ifp->link.lowerdev.name);
		return NULL;
	}

	macvlan = ni_netdev_get_macvlan(cfg_ifp);
	if ((err = ni_macvlan_validate(macvlan))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

	if (ni_string_empty(ifname)) {
		if (ni_string_empty(cfg_ifp->name) &&
			(ifname = ni_netdev_make_name(
				nc,
				cfg_ifp_iftype,
				0))) {
			ni_string_dup(&cfg_ifp->name, ifname);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create %s interface: "
				"name argument missed",
				cfg_ifp_iftype);
			goto out;
		}
		ifname = NULL;
	} else if(!ni_string_eq(cfg_ifp->name, ifname)) {
		ni_string_dup(&cfg_ifp->name, ifname);
	}
	if (ni_string_eq(cfg_ifp->name, cfg_ifp->link.lowerdev.name)) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"Cannot create %s interface: "
			"macvlan name %s equal with lower device name",
			cfg_ifp_iftype,
			cfg_ifp->name);
		return NULL;
	}

	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 %s interface: "
				"invalid ethernet address '%s'",
				cfg_ifp_iftype,
				ni_link_address_print(&cfg_ifp->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_macvlan_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 %s interface: %s",
				cfg_ifp_iftype,
				ni_strerror(rv));
			dev_ifp = NULL;
			goto out;
		}
		ni_debug_dbus("%s interface exists (and name matches)",
			cfg_ifp_iftype);
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev_ifp;
}
Beispiel #20
0
static ni_netdev_t *
__ni_objectmodel_gre_create(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_gre_t *gre = NULL;
	ni_netdev_t *dev = NULL;
	const char *err = NULL;
	int rv;

	gre = ni_netdev_get_gre(cfg_ifp);
	if ((err = ni_gre_validate(gre))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		goto out;
	}

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

	if (!ni_string_empty(cfg_ifp->link.lowerdev.name) &&
	    !ni_objectmodel_bind_netdev_ref_index(cfg_ifp->name, "gre tunnel",
					&cfg_ifp->link.lowerdev, nc, error))
		goto out;

	if (cfg_ifp->link.hwaddr.len) {
		if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID)
			cfg_ifp->link.hwaddr.type = ARPHRD_IPGRE;

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

	if (cfg_ifp->link.hwpeer.len) {
		if (cfg_ifp->link.hwpeer.type == ARPHRD_VOID)
			cfg_ifp->link.hwpeer.type = ARPHRD_IPGRE;

		if (cfg_ifp->link.hwpeer.type != ARPHRD_IPGRE ||
		    cfg_ifp->link.hwpeer.len != ni_link_address_length(ARPHRD_IPGRE)) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot create gre tunnel interface: "
				"invalid remote address '%s'",
				ni_link_address_print(&cfg_ifp->link.hwpeer));
			return NULL;
		}
	}

	if ((rv = ni_system_tunnel_create(nc, cfg_ifp, &dev, NI_IFTYPE_GRE) < 0)) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL
			|| (ifname && dev && !ni_string_eq(dev->name, ifname))) {
			dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create gre tunnel: %s", cfg_ifp->name);
			dev = NULL;
			goto out;
		}
		ni_debug_dbus("gre tunnel exists (and name matches)");
	}

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

out:
	if (cfg_ifp)
		ni_netdev_put(cfg_ifp);
	return dev;
}