Esempio n. 1
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;
}
Esempio n. 2
0
/*
 * get/set ethtool.wake-on-lan
 */
static dbus_bool_t
ni_objectmodel_ethtool_get_wake_on_lan(const ni_dbus_object_t *object,
		const ni_dbus_property_t *property,
		ni_dbus_variant_t *result,
		DBusError *error)
{
	const ni_ethtool_wake_on_lan_t *wol;
	const ni_ethtool_t *ethtool;

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

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

	if (wol->support == NI_ETHTOOL_WOL_DEFAULT ||
	    wol->support == NI_ETHTOOL_WOL_DISABLE)
		return FALSE;

	ni_dbus_variant_init_dict(result);
	ni_dbus_dict_add_uint32(result, "support", wol->support);
	if (wol->options != NI_ETHTOOL_WOL_DEFAULT)
		ni_dbus_dict_add_uint32(result, "options", wol->options);

	/* from config it is VOID, hide sopass from kernel with type ETHER */
	if (wol->sopass.len && wol->sopass.type == ARPHRD_VOID &&
	    wol->sopass.len == ni_link_address_length(ARPHRD_ETHER))
		__ni_objectmodel_dict_add_hwaddr(result, "sopass", &wol->sopass);

	return TRUE;
}
Esempio n. 3
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;
}
Esempio n. 4
0
File: arp.c Progetto: gsanso/wicked
int
ni_arp_send(ni_arp_socket_t *arph, const ni_arp_packet_t *packet)
{
	unsigned int hwlen, pktlen;
	struct arphdr *arp;
	ni_buffer_t buf;
	int rv;

	hwlen = ni_link_address_length(arph->dev_info.hwaddr.type);
	pktlen = sizeof(*arp) + 2 * hwlen + 2 * 4;

	arp = calloc(1, pktlen);
	ni_buffer_init(&buf, arp, pktlen);

	arp = ni_buffer_push_tail(&buf, sizeof(*arp));
	arp->ar_hrd = htons(arph->dev_info.hwaddr.type);
	arp->ar_pro = htons(ETHERTYPE_IP);
	arp->ar_hln = hwlen;
	arp->ar_pln = 4;
	arp->ar_op = htons(packet->op);

	if (packet->sha.len == hwlen) {
		ni_buffer_put(&buf, packet->sha.data, packet->sha.len);
	} else {
		ni_buffer_put(&buf, NULL, hwlen);
	}
	ni_buffer_put(&buf, &packet->sip, 4);
	if (packet->tha.len == hwlen) {
		ni_buffer_put(&buf, packet->tha.data, packet->tha.len);
	} else {
		ni_buffer_put(&buf, NULL, hwlen);
	}
	ni_buffer_put(&buf, &packet->tip, 4);

	rv = ni_capture_send(arph->capture, &buf, NULL);
	free(buf.base);
	return rv;
}
Esempio n. 5
0
File: arp.c Progetto: gsanso/wicked
int
ni_arp_parse(ni_arp_socket_t *arph, ni_buffer_t *bp, ni_arp_packet_t *p)
{
	struct arphdr *arp;

	if (!(arp = ni_buffer_pull_head(bp, sizeof(*arp))))
		return -1;

	if (arp->ar_pro != htons(ETHERTYPE_IP)
	 || arp->ar_pln != 4)
		return -1;

	p->op = ntohs(arp->ar_op);
	p->sha.type = arph->dev_info.hwaddr.type;
	p->sha.len = ni_link_address_length(arph->dev_info.hwaddr.type);
	p->tha = p->sha;

	if (ni_buffer_get(bp, p->sha.data, p->sha.len) < 0 || ni_buffer_get(bp, &p->sip, 4) < 0
	 || ni_buffer_get(bp, p->tha.data, p->tha.len) < 0 || ni_buffer_get(bp, &p->tip, 4) < 0)
		return -1;

	return 0;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
/*
 * 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;
}