コード例 #1
0
ファイル: ppp.c プロジェクト: mtomaschewski/wicked
static ni_netdev_t *
ni_objectmodel_ppp_device_create(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	int rv;

	ni_netdev_get_ppp(cfg);
	if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "ppp", 0))) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
				"Unable to create ppp interface - too many interfaces");
		return NULL;
	}
	ni_string_dup(&cfg->name, ifname);

	if ((rv = ni_system_ppp_create(nc, cfg, &dev)) < 0) {
		dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create ppp interface '%s'",
				cfg->name);
		return NULL;
	}

	if (dev && dev->link.type != NI_IFTYPE_PPP) {
		dbus_set_error(error, DBUS_ERROR_FAILED,
			"Unable to create ppp interface: new interface is of type %s",
			ni_linktype_type_to_name(dev->link.type));
		return NULL;
	}
	return dev;
}
コード例 #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
ファイル: 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;
}
コード例 #4
0
ファイル: team.c プロジェクト: mtomaschewski/wicked
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;
}
コード例 #5
0
ファイル: tun.c プロジェクト: pwieczorkiewicz/wicked
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;
}
コード例 #6
0
ファイル: bonding.c プロジェクト: pwieczorkiewicz/wicked
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;
}
コード例 #7
0
ファイル: ppp.c プロジェクト: mchf/wicked
static ni_netdev_t *
__ni_objectmodel_ppp_newlink(ni_netdev_t *cfg, const char *ifname, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *new_dev = NULL;
	int rv;

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

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

	if ((rv = ni_system_ppp_create(nc, ifname, cfg->ppp, &new_dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS
		 && (ifname != NULL && strcmp(ifname, new_dev->name))) {
			ni_dbus_set_error_from_code(error, rv,
					"unable to create PPP interface %s",
					ifname);
			return NULL;
		}
		ni_debug_dbus("PPP interface exists (and name matches)");
	}

	if (new_dev->link.type != NI_IFTYPE_PPP) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create PPP interface: new interface is of type %s",
				ni_linktype_type_to_name(new_dev->link.type));
		/* FIXME: delete device? */
		return NULL;
	}

	if (ni_ppp_write_config(new_dev->ppp) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to create PPP interface: failed to write coniguration files");
		/* FIXME: delete device */
		return NULL;
	}

	return new_dev;
}
コード例 #8
0
ファイル: ovs.c プロジェクト: mtomaschewski/wicked
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;
}
コード例 #9
0
ファイル: ifup.c プロジェクト: pwieczorkiewicz/wicked
static xml_node_t *
__ni_ifup_generate_match_type_dev(ni_netdev_t *dev)
{
	const char *type;
	xml_node_t *ret;

	if (!dev || dev->link.type == NI_IFTYPE_UNKNOWN)
		return NULL;

	if (!(type = ni_linktype_type_to_name(dev->link.type)))
		return NULL;

	if (!(ret = xml_node_new(NI_NANNY_IFPOLICY_MATCH_COND_AND, NULL)))
		return NULL;

	if (!xml_node_new_element(NI_NANNY_IFPOLICY_MATCH_DEV, ret, dev->name) ||
	    !xml_node_new_element(NI_NANNY_IFPOLICY_MATCH_LINK_TYPE, ret, type)) {
		xml_node_free(ret);
		return NULL;
	}
	return ret;
}
コード例 #10
0
ファイル: bridge.c プロジェクト: gsanso/wicked
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;
}
コード例 #11
0
ファイル: macvlan.c プロジェクト: gsanso/wicked
/*
 * Change a macvlan/macvtap interface
 */
static dbus_bool_t
__ni_objectmodel_macvlan_change(ni_netdev_t *cfg, ni_netdev_t *dev, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	const char *err;
	ni_macvlan_t *macvlan;
	const char *dev_iftype = NULL;

	macvlan = ni_netdev_get_macvlan(cfg);
	if ((err = ni_macvlan_validate(macvlan))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return FALSE;
	}

	if ((cfg->link.lowerdev.index &&
	     (cfg->link.lowerdev.index != dev->link.lowerdev.index)) ||
	    (cfg->link.lowerdev.name &&
	     !ni_string_eq(cfg->link.lowerdev.name, dev->link.lowerdev.name))) {
		const char *cfg_iftype = ni_linktype_type_to_name(cfg->link.type);

		if (cfg->link.lowerdev.name) {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s lower device to %s",
				cfg_iftype, cfg->link.lowerdev.name);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s lower device to %u",
				cfg_iftype, cfg->link.lowerdev.index);
		}
		return FALSE;
	}
	cfg->link.lowerdev.index = dev->link.lowerdev.index;
	ni_string_dup(&cfg->link.lowerdev.name, dev->link.lowerdev.name);

	cfg->link.ifindex = dev->link.ifindex;
	if (ni_string_empty(cfg->name))
		ni_string_dup(&cfg->name, dev->name);

	dev_iftype = ni_linktype_type_to_name(dev->link.type);

	if (!macvlan->mode) {
		macvlan->mode = dev->macvlan->mode;
	} else
	if ((macvlan->mode == NI_MACVLAN_MODE_PASSTHRU) !=
	    (dev->macvlan->mode == NI_MACVLAN_MODE_PASSTHRU)) {
		/* Passthrough mode can't be set or cleared dynamically */
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Cannot change %s mode to %s",
			dev_iftype,
			ni_macvlan_mode_to_name(macvlan->mode));
		return FALSE;
	}

	if (ni_netdev_device_is_up(dev)) {
		ni_debug_objectmodel("Skipping %s changeDevice call on %s: "
				"device is up", dev_iftype, dev->name);
		return TRUE;
	}

	if (ni_system_macvlan_change(nc, dev, cfg) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to change %s properties on interface %s",
			dev_iftype, dev->name);
		return FALSE;
	}

	if (cfg->link.hwaddr.type == ARPHRD_VOID)
		cfg->link.hwaddr.type = ARPHRD_ETHER;
	if (!ni_link_address_is_invalid(&cfg->link.hwaddr) &&
	    ni_system_hwaddr_change(nc, dev, &cfg->link.hwaddr) < 0) {
		ni_error("Unable to change hwaddr on %s interface %s",
			dev_iftype, dev->name);
		/* fail? */
	}

	return TRUE;
}
コード例 #12
0
ファイル: macvlan.c プロジェクト: gsanso/wicked
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;
}
コード例 #13
0
ファイル: ifup.c プロジェクト: pwieczorkiewicz/wicked
static ni_bool_t
ni_ifup_hire_nanny(ni_ifworker_t *w)
{
	xml_node_t *ifcfg = NULL, *policy = NULL;
	ni_netdev_t *dev;
	unsigned int i;
	ni_bool_t rv = FALSE;
	char *pname;

	if (!w)
		return rv;

	ni_debug_application("%s: hiring nanny", w->name);

	/* Create a config duplicate for a policy */
	ifcfg = xml_node_clone(w->config.node, NULL);
	if (!ifcfg)
		goto error;

	pname  = ni_ifpolicy_name_from_ifname(w->name);
	ni_debug_application("%s: converting config into policy '%s'",
			w->name, pname);

	policy = ni_convert_cfg_into_policy_node(ifcfg,
			__ni_ifup_generate_match(w),
			pname, w->config.origin);
	ni_string_free(&pname);
	if (!policy) {
		policy = ifcfg; /* Free cloned config*/
		goto error;
	}

#if 0
	/* Do we need this? */

	/* Add link type to match node*/
	if (dev) {
		ni_debug_application("%s: adding link type (%s) to match",
			w->name, ni_linktype_type_to_name(dev->link.type));
		ni_ifpolicy_match_add_link_type(policy, dev->link.type);
	}

	ni_debug_application("%s: adding minimum device state (%s) to match",
		w->name, ni_ifworker_state_name(w->fsm.state));

	/* Add minimum device state to match node */
	if (!ni_ifpolicy_match_add_min_state(policy, w->fsm.state))
		goto error;
#endif

	dev = w->device;
	if (dev) {
		ni_debug_application("%s: enabling device for nanny", w->name);
		if (!ni_nanny_call_device_enable(w->name))
			goto error;
	}

	ni_debug_application("%s: adding policy %s to nanny", w->name,
		xml_node_get_attr(policy, NI_NANNY_IFPOLICY_NAME));

	if (ni_nanny_addpolicy_node(policy, w->config.origin) <= 0) {
		ni_nanny_call_device_disable(w->name);
		goto error;
	}

	ni_debug_application("%s: nanny hired!", w->name);
	ni_ifworker_success(w);

	/* Append policies for all children in case they contain some special options */
	for (i = 0; i < w->children.count; i++) {
		ni_ifworker_t *child = w->children.data[i];

		if (!ni_ifup_hire_nanny(child))
			ni_error("%s: unable to apply configuration to nanny", child->name);
	}

	rv = TRUE;

error:
	if (!rv)
		ni_ifworker_fail(w, "%s: unable to apply configuration to nanny", w->name);
	xml_node_free(policy);
	return rv;
}
コード例 #14
0
ファイル: gre.c プロジェクト: mtomaschewski/wicked
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;
}
コード例 #15
0
ファイル: tuntap.c プロジェクト: mijos/wicked
/*
 * Create a new TUN/TAP interface
 */
static ni_netdev_t *
__ni_objectmodel_tuntap_create(ni_netdev_t *cfg, DBusError *error)
{
	ni_netconfig_t *nc = ni_global_state_handle(0);
	ni_netdev_t *dev = NULL;
	const char *iftype;
	const ni_tuntap_t *tuntap;
	const char *err;
	int rv;

	iftype = ni_linktype_type_to_name(cfg->link.type);
	if (cfg->link.type != NI_IFTYPE_TUN && cfg->link.type != NI_IFTYPE_TAP) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
			"BUG: Cannot handle %s type in tun/tap factory", iftype);
		return NULL;
	}

	ni_debug_dbus("%s.newDevice(name=%s)", iftype, cfg->name);
	tuntap = ni_netdev_get_tuntap(cfg);
	if ((err = ni_tuntap_validate(tuntap))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return NULL;
	}

	if (ni_string_empty(cfg->name)) {
		if (ni_string_empty(cfg->name) &&
		    (cfg->name = (char *) ni_netdev_make_name(nc, iftype, 0))) {
			ni_string_dup(&cfg->name, cfg->name);
		} else {
			dbus_set_error(error, DBUS_ERROR_INVALID_ARGS,
				"Unable to create %s interface: "
				"name argument missed", iftype);
			return NULL;
		}
		cfg->name = NULL;
	} else if(!ni_string_eq(cfg->name, cfg->name)) {
		ni_string_dup(&cfg->name, cfg->name);
	}

	if (cfg->link.type == NI_IFTYPE_TAP && cfg->link.hwaddr.len) {
		if (cfg->link.hwaddr.type == ARPHRD_VOID)
			cfg->link.hwaddr.type = ARPHRD_ETHER;

		if (cfg->link.hwaddr.type != ARPHRD_ETHER
		||  cfg->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'", iftype,
					ni_link_address_print(&cfg->link.hwaddr));
			return NULL;
		}
	}

	if ((rv = ni_system_tuntap_create(nc, cfg, &dev)) < 0) {
		if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL
		|| (cfg->name && dev && !ni_string_eq(dev->name, cfg->name))) {
			ni_dbus_set_error_from_code(error, rv,
				"Unable to create %s interface %s",
				iftype, cfg->name);
			return NULL;
		}
		ni_debug_dbus("%s interface exists (and name matches)", iftype);
	}

	if (dev->link.type != cfg->link.type) {
		dbus_set_error(error,
			DBUS_ERROR_FAILED,
			"Unable to create %s: existing interface %s is of type %s",
			iftype, dev->name, ni_linktype_type_to_name(dev->link.type));
		return NULL;
	}

	return dev;
}
コード例 #16
0
ファイル: tuntap.c プロジェクト: mijos/wicked
static dbus_bool_t
ni_objectmodel_tuntap_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 *dev, *cfg;
	ni_tuntap_t *tuntap;
	const char *err;
	const char *iftype_name;

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

	if (!(dev = ni_objectmodel_unwrap_netif(object, error)) ||
	    !(cfg = __ni_objectmodel_tuntap_device_arg(&argv[0], dev->link.type)) ||
	    !(ni_netdev_get_tuntap(dev))) {
		ni_dbus_error_invalid_args(error, object->path, method->name);
		return FALSE;
	}

	/* changeDevice method is only needed in case of TAP devices */
	if (dev->link.type != NI_IFTYPE_TAP)
		return TRUE;

	iftype_name = ni_linktype_type_to_name(dev->link.type);

	tuntap = ni_netdev_get_tuntap(cfg);
	if ((err = ni_tuntap_validate(tuntap))) {
		dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err);
		return FALSE;
	}

	cfg->link.ifindex = dev->link.ifindex;
	if (ni_string_empty(cfg->name))
		ni_string_dup(&cfg->name, dev->name);

	if (ni_netdev_device_is_up(dev)) {
		ni_debug_objectmodel("Skipping %s changeDevice call on %s: "
				"device is up", iftype_name, dev->name);
		return TRUE;
	}

	if (ni_system_tap_change(nc, dev, cfg) < 0) {
		dbus_set_error(error,
				DBUS_ERROR_FAILED,
				"Unable to change %s properties on interface %s",
				iftype_name, dev->name);
		return FALSE;
	}

	if (cfg->link.hwaddr.type == ARPHRD_VOID)
		cfg->link.hwaddr.type = ARPHRD_ETHER;
	if (ni_system_hwaddr_change(nc, dev, &cfg->link.hwaddr) < 0) {
		ni_error("Unable to change hwaddr on %s interface %s",
				iftype_name, dev->name);
		/* fail? */
	}

	return TRUE;
}