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->rm.prefix);
		if (error)
			return respond_error(nl_hdr, error);

		if (xlat_is_nat64() && !request->flush.quick)
			sessiondb_delete_taddr6s(&request->rm.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 (xlat_is_nat64() && !request->flush.quick)
			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_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. 3
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. 4
0
static int validate_version(struct request_hdr *hdr)
{
	if (hdr->magic[0] != 'j' || hdr->magic[1] != 'o')
		goto magic_fail;
	if (hdr->magic[2] != 'o' || hdr->magic[3] != 'l')
		goto magic_fail;

	switch (hdr->type) {
	case 's':
		if (xlat_is_nat64()) {
			log_err("You're speaking to NAT64 Jool using "
					"the SIIT Jool application.");
			return -EINVAL;
		}
		break;
	case 'n':
		if (xlat_is_siit()) {
			log_err("You're speaking to SIIT Jool using "
					"the NAT64 Jool application.");
			return -EINVAL;
		}
		break;
	default:
		goto magic_fail;
	}

	if (xlat_version() == hdr->version)
		return 0;

	log_err("Version mismatch. The kernel module is %u.%u.%u.%u, "
			"but the userspace application is %u.%u.%u.%u. "
			"Please update Jool's %s.",
			JOOL_VERSION_MAJOR, JOOL_VERSION_MINOR,
			JOOL_VERSION_REV, JOOL_VERSION_DEV,
			hdr->version >> 24, (hdr->version >> 16) & 0xFFU,
			(hdr->version >> 8) & 0xFFU, hdr->version & 0xFFU,
			(xlat_version() > hdr->version)
				? "userspace application"
				: "kernel module");
	return -EINVAL;

magic_fail:
	log_err("It appears you're trying to speak to Jool using some other "
			"Netlink client or an older userspace application. "
			"If the latter is true, please update your userspace "
			"application.");
	return -EINVAL;
}
Esempio n. 5
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. 6
0
File: pool4.c Progetto: NICMx/Jool
static int handle_pool4_rm(struct xlator *jool, struct genl_info *info,
		union request_pool4 *request)
{
	int error;

	log_debug("Removing elements from pool4.");

	error = pool4db_rm_usr(jool->nat64.pool4, &request->rm.entry);

	if (xlat_is_nat64() && !request->rm.quick) {
		bib_rm_range(jool, request->rm.entry.proto,
				&request->rm.entry.range);
	}

	return nlcore_respond(info, error);
}
Esempio n. 7
0
File: pool4.c Progetto: NICMx/Jool
static int handle_pool4_flush(struct xlator *jool, struct genl_info *info,
		union request_pool4 *request)
{
	log_debug("Flushing pool4.");

	pool4db_flush(jool->nat64.pool4);
	if (xlat_is_nat64() && !request->flush.quick) {
		/*
		 * This will also clear *previously* orphaned entries, but given
		 * that "not quick" generally means "please clean up", this is
		 * more likely what people wants.
		 */
		bib_flush(jool);
	}

	return nlcore_respond(info, 0);
}
Esempio n. 8
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. 9
0
int handle_eamt_config(struct xlator *jool, struct genl_info *info)
{
	struct request_hdr *hdr;
	union request_eamt *request;
	int error;

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

	hdr = get_jool_hdr(info);
	request = (union request_eamt *)(hdr + 1);

	error = validate_request_size(info, sizeof(*request));
	if (error)
		return nlcore_respond(info, error);

	switch (be16_to_cpu(hdr->operation)) {
	case OP_DISPLAY:
		return handle_eamt_display(jool->siit.eamt, info, request);
	case OP_COUNT:
		return handle_eamt_count(jool->siit.eamt, info);
	case OP_ADD:
		error = handle_eamt_add(jool->siit.eamt, request);
		break;
	case OP_REMOVE:
		error = handle_eamt_rm(jool->siit.eamt, request);
		break;
	case OP_FLUSH:
		error = handle_eamt_flush(jool->siit.eamt);
		break;
	default:
		log_err("Unknown operation: %u", be16_to_cpu(hdr->operation));
		error = -EINVAL;
	}

	return nlcore_respond(info, error);
}
Esempio n. 10
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);
}