Esempio n. 1
0
static int handle_pool6_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool6 *request)
{
	__u64 count;
	int error;

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool6_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv6 prefix count.");
		error = pool6_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
	case OP_UPDATE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding a prefix to the IPv6 pool.");

		return respond_error(nl_hdr, pool6_add(&request->add.prefix));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing a prefix from the IPv6 pool.");
		error = pool6_remove(&request->remove.prefix);
		if (error)
			return respond_error(nl_hdr, error);

		if (nat64_is_stateful() && !request->flush.quick)
			error = sessiondb_delete_by_prefix6(&request->remove.prefix);

		return respond_error(nl_hdr, error);

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Flushing the IPv6 pool...");
		error = pool6_flush();
		if (error)
			return respond_error(nl_hdr, error);

		if (nat64_is_stateful() && !request->flush.quick)
			error = sessiondb_flush();

		return respond_error(nl_hdr, error);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 2
0
static int handle_rfc6791_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		union request_pool4 *request)
{
	__u64 count;
	int error;

	if (nat64_is_stateful()) {
		log_err("RFC 6791 does not apply to Stateful NAT64.");
		return -EINVAL;
	}

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		return handle_pool6791_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning IPv4 address count.");
		error = rfc6791_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding an address to the IPv4 pool.");
		return respond_error(nl_hdr, rfc6791_add(&request->add.addrs));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing an address from the IPv4 pool.");

		error = rfc6791_remove(&request->remove.addrs);
		if (error)
			return respond_error(nl_hdr, error);

		return respond_error(nl_hdr, error);

	case OP_FLUSH:
		if (verify_superpriv()) {
			return respond_error(nl_hdr, -EPERM);
		}

		log_debug("Flushing the IPv4 pool...");
		error = rfc6791_flush();
		if (error)
			return respond_error(nl_hdr, error);

		return respond_error(nl_hdr, error);

	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 3
0
static int handle_eamt_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_eamt *request)
{
	__u64 count;
	int error;

	if (xlat_is_nat64()) {
		log_err("Stateful NAT64 doesn't have an EAMT.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		return handle_eamt_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning EAMT count.");
		error = eamt_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_TEST:
		return handle_eamt_test(nl_hdr, request);

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding EAMT entry.");
		return respond_error(nl_hdr, eamt_add(&request->add.prefix6,
				&request->add.prefix4, request->add.force));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing EAMT entry.");
		return respond_error(nl_hdr, eamt_rm(
				request->rm.prefix6_set ? &request->rm.prefix6 : NULL,
				request->rm.prefix4_set ? &request->rm.prefix4 : NULL));

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		eamt_flush();
		return respond_error(nl_hdr, 0);

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 4
0
static int handle_blacklist_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_pool *request)
{
	__u64 count;
	int error;

	if (xlat_is_nat64()) {
		log_err("Blacklist does not apply to Stateful NAT64.");
		return -EINVAL;
	}

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Sending Blacklist pool to userspace.");
		return handle_blacklist_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning address count in the Blacklist pool.");
		error = blacklist_count(&count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding an address to the Blacklist pool.");
		return respond_error(nl_hdr, blacklist_add(&request->add.addrs));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing an address from the Blacklist pool.");
		return respond_error(nl_hdr, blacklist_rm(&request->rm.addrs));

	case OP_FLUSH:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Flushing the Blacklist pool...");
		return respond_error(nl_hdr, blacklist_flush());

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 5
0
static int handle_expect_add(struct genl_info *info)
{
	struct expected_packet pkt;
	struct nlattr *attr;

	if (verify_superpriv())
		return -EPERM;

	attr = info->attrs[ATTR_FILENAME];
	if (!attr) {
		log_err("Request lacks a file name.");
		return -EINVAL;
	}
	pkt.filename = nla_data(attr);

	attr = info->attrs[ATTR_PKT];
	if (!attr) {
		log_err("Request lacks a packet.");
		return -EINVAL;
	}
	pkt.bytes = nla_data(attr);
	pkt.bytes_len = nla_len(attr);

	attr = info->attrs[ATTR_EXCEPTIONS];
	pkt.exceptions = attr ? nla_data(attr) : NULL;
	pkt.exceptions_len = attr ? (nla_len(attr) / sizeof(*pkt.exceptions)) : 0;

	return genl_respond(info, expecter_add(&pkt));
}
Esempio n. 6
0
static int handle_send(struct genl_info *info)
{
	char *filename;
	struct nlattr *attr;
	int error;

	if (verify_superpriv())
		return -EPERM;

	attr = info->attrs[ATTR_FILENAME];
	if (!attr) {
		log_err("Request lacks a file name.");
		return -EINVAL;
	}
	filename = nla_data(attr);

	attr = info->attrs[ATTR_PKT];
	if (!attr) {
		log_err("Request lacks a packet.");
		return -EINVAL;
	}

	error = sender_send(filename, nla_data(attr), nla_len(attr));
	return genl_respond(info, error);
}
Esempio n. 7
0
static int handle_expect_flush(struct genl_info *info)
{
	if (verify_superpriv())
		return -EPERM;

	expecter_flush();
	return genl_respond(info, 0);
}
Esempio n. 8
0
static int handle_eamt_flush(struct eam_table *eamt)
{
	if (verify_superpriv())
		return -EPERM;

	eamt_flush(eamt);
	return 0;
}
Esempio n. 9
0
static int handle_eamt_add(struct eam_table *eamt, union request_eamt *request)
{
	if (verify_superpriv())
		return -EPERM;

	log_debug("Adding EAMT entry.");
	return eamt_add(eamt, &request->add.prefix6, &request->add.prefix4,
			request->add.force);
}
Esempio n. 10
0
static int handle_pool4_add(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Adding elements to the IPv4 pool.");

	return respond_error(nl_hdr, pool4db_add(request->add.mark,
			request->add.proto, &request->add.addrs,
			&request->add.ports));
}
Esempio n. 11
0
static int handle_bib_config(struct nlmsghdr *nl_hdr, struct request_hdr *nat64_hdr,
		struct request_bib *request)
{
	__u64 count;
	int error;

	if (nat64_is_stateless()) {
		log_err("SIIT doesn't have BIBs.");
		return -EINVAL;
	}

	switch (nat64_hdr->operation) {
	case OP_DISPLAY:
		return handle_bib_display(nl_hdr, request);

	case OP_COUNT:
		log_debug("Returning BIB count.");
		error = bibdb_count(request->l4_proto, &count);
		if (error)
			return respond_error(nl_hdr, error);
		return respond_setcfg(nl_hdr, &count, sizeof(count));

	case OP_ADD:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Adding BIB entry.");
		return respond_error(nl_hdr, add_static_route(request));

	case OP_REMOVE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Removing BIB entry.");
		return respond_error(nl_hdr, delete_static_route(request));

	default:
		log_err("Unknown operation: %d", nat64_hdr->operation);
		return respond_error(nl_hdr, -EINVAL);
	}
}
Esempio n. 12
0
static int handle_eamt_rm(struct eam_table *eamt, union request_eamt *request)
{
	struct ipv6_prefix *prefix6;
	struct ipv4_prefix *prefix4;

	if (verify_superpriv())
		return -EPERM;

	log_debug("Removing EAMT entry.");

	prefix6 = request->rm.prefix6_set ? &request->rm.prefix6 : NULL;
	prefix4 = request->rm.prefix4_set ? &request->rm.prefix4 : NULL;
	return eamt_rm(eamt, prefix6, prefix4);
}
Esempio n. 13
0
int handle_atomconfig_request(struct xlator *jool, struct genl_info *info)
{
	struct request_hdr *hdr;
	size_t total_len;
	int error;

	if (verify_superpriv())
		return nlcore_respond(info, -EPERM);

	hdr = nla_data(info->attrs[ATTR_DATA]);
	total_len = nla_len(info->attrs[ATTR_DATA]);

	error = atomconfig_add(jool, hdr + 1, total_len - sizeof(*hdr));
	return nlcore_respond(info, error);
}
Esempio n. 14
0
static int handle_global_config(struct nlmsghdr *nl_hdr, struct request_hdr *jool_hdr,
		union request_global *request)
{
	struct global_config response = { .mtu_plateaus = NULL };
	unsigned char *buffer;
	size_t buffer_len;
	bool disabled;
	int error;

	switch (jool_hdr->operation) {
	case OP_DISPLAY:
		log_debug("Returning 'Global' options.");

		error = config_clone(&response);
		if (error)
			goto end;

		disabled = xlat_is_nat64()
				? pool6_is_empty()
				: (pool6_is_empty() && eamt_is_empty());
		error = serialize_global_config(&response, disabled, &buffer, &buffer_len);
		if (error)
			goto end;

		error = respond_setcfg(nl_hdr, buffer, buffer_len);
		kfree(buffer);
		break;

	case OP_UPDATE:
		if (verify_superpriv())
			return respond_error(nl_hdr, -EPERM);

		log_debug("Updating 'Global' options.");

		buffer = (unsigned char *) (request + 1);
		buffer_len = jool_hdr->length - sizeof(*jool_hdr) - sizeof(*request);

		error = handle_global_update(request->update.type, buffer_len, buffer);
		break;

	default:
		log_err("Unknown operation: %d", jool_hdr->operation);
		error = -EINVAL;
	}

end:
	return respond_error(nl_hdr, error);
}
Esempio n. 15
0
static int handle_pool4_rm(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	int error;

	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Removing elements from the IPv4 pool.");

	error = pool4db_rm(request->rm.mark, request->rm.proto,
			&request->rm.addrs, &request->rm.ports);

	if (xlat_is_nat64() && !request->rm.quick) {
		sessiondb_delete_taddr4s(&request->rm.addrs, &request->rm.ports);
		bibdb_delete_taddr4s(&request->rm.addrs, &request->rm.ports);
	}

	return respond_error(nl_hdr, error);
}
Esempio n. 16
0
static int handle_pool4_flush(struct nlmsghdr *nl_hdr, union request_pool4 *request)
{
	int error;

	if (verify_superpriv())
		return respond_error(nl_hdr, -EPERM);

	log_debug("Flushing the IPv4 pool...");
	error = pool4db_flush();

	/*
	 * Well, pool4db_flush only errors on memory allocation failures,
	 * so I guess clearing BIB and session even if pool4db_flush fails
	 * is a good idea.
	 */
	if (xlat_is_nat64() && !request->flush.quick) {
		sessiondb_flush();
		bibdb_flush();
	}

	return respond_error(nl_hdr, error);
}
Esempio n. 17
0
static int handle_session_display(struct bib *db, struct genl_info *info,
		struct request_session *request)
{
	struct nlcore_buffer buffer;
	struct session_foreach_func func = {
			.cb = session_entry_to_userspace,
			.arg = &buffer,
	};
	struct session_foreach_offset offset_struct;
	struct session_foreach_offset *offset = NULL;
	int error;

	if (verify_superpriv())
		return nlcore_respond(info, -EPERM);

	log_debug("Sending session table to userspace.");

	error = nlbuffer_init_response(&buffer, info, nlbuffer_response_max_size());
	if (error)
		return nlcore_respond(info, error);

	if (request->display.offset_set) {
		offset_struct.offset = request->display.offset;
		offset_struct.include_offset = false;
		offset = &offset_struct;
	}

	error = bib_foreach_session(db, request->l4_proto, &func, offset);
	nlbuffer_set_pending_data(&buffer, error > 0);
	error = (error >= 0)
			? nlbuffer_send(info, &buffer)
			: nlcore_respond(info, error);

	nlbuffer_free(&buffer);
	return error;
}