Beispiel #1
0
int nf_logger_find_get(int pf, enum nf_log_type type)
{
	struct nf_logger *logger;
	int ret = -ENOENT;

	if (pf == NFPROTO_INET) {
		ret = nf_logger_find_get(NFPROTO_IPV4, type);
		if (ret < 0)
			return ret;

		ret = nf_logger_find_get(NFPROTO_IPV6, type);
		if (ret < 0) {
			nf_logger_put(NFPROTO_IPV4, type);
			return ret;
		}

		return 0;
	}

	if (rcu_access_pointer(loggers[pf][type]) == NULL)
		request_module("nf-logger-%u-%u", pf, type);

	rcu_read_lock();
	logger = rcu_dereference(loggers[pf][type]);
	if (logger == NULL)
		goto out;

	if (try_module_get(logger->me))
		ret = 0;
out:
	rcu_read_unlock();
	return ret;
}
Beispiel #2
0
static void nft_log_destroy(const struct nft_ctx *ctx,
			    const struct nft_expr *expr)
{
	struct nft_log *priv = nft_expr_priv(expr);
	struct nf_loginfo *li = &priv->loginfo;

	if (priv->prefix != nft_log_null_prefix)
		kfree(priv->prefix);

	if (ctx->afi->family == NFPROTO_INET) {
		nf_logger_put(NFPROTO_IPV4, li->type);
		nf_logger_put(NFPROTO_IPV6, li->type);
	} else {
		nf_logger_put(ctx->afi->family, li->type);
	}
}
Beispiel #3
0
void nf_logger_put(int pf, enum nf_log_type type)
{
	struct nf_logger *logger;

	if (pf == NFPROTO_INET) {
		nf_logger_put(NFPROTO_IPV4, type);
		nf_logger_put(NFPROTO_IPV6, type);
		return;
	}

	BUG_ON(loggers[pf][type] == NULL);

	rcu_read_lock();
	logger = rcu_dereference(loggers[pf][type]);
	module_put(logger->me);
	rcu_read_unlock();
}
Beispiel #4
0
static void trace_tg_destroy(const struct xt_tgdtor_param *par)
{
	nf_logger_put(par->family, NF_LOG_TYPE_LOG);
}
Beispiel #5
0
static int nft_log_init(const struct nft_ctx *ctx,
			const struct nft_expr *expr,
			const struct nlattr * const tb[])
{
	struct nft_log *priv = nft_expr_priv(expr);
	struct nf_loginfo *li = &priv->loginfo;
	const struct nlattr *nla;
	int ret;

	nla = tb[NFTA_LOG_PREFIX];
	if (nla != NULL) {
		priv->prefix = kmalloc(nla_len(nla) + 1, GFP_KERNEL);
		if (priv->prefix == NULL)
			return -ENOMEM;
		nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
	} else {
		priv->prefix = (char *)nft_log_null_prefix;
	}

	li->type = NF_LOG_TYPE_LOG;
	if (tb[NFTA_LOG_LEVEL] != NULL &&
	    tb[NFTA_LOG_GROUP] != NULL)
		return -EINVAL;
	if (tb[NFTA_LOG_GROUP] != NULL)
		li->type = NF_LOG_TYPE_ULOG;

	switch (li->type) {
	case NF_LOG_TYPE_LOG:
		if (tb[NFTA_LOG_LEVEL] != NULL) {
			li->u.log.level =
				ntohl(nla_get_be32(tb[NFTA_LOG_LEVEL]));
		} else {
			li->u.log.level = 4;
		}
		if (tb[NFTA_LOG_FLAGS] != NULL) {
			li->u.log.logflags =
				ntohl(nla_get_be32(tb[NFTA_LOG_FLAGS]));
		}
		break;
	case NF_LOG_TYPE_ULOG:
		li->u.ulog.group = ntohs(nla_get_be16(tb[NFTA_LOG_GROUP]));
		if (tb[NFTA_LOG_SNAPLEN] != NULL) {
			li->u.ulog.copy_len =
				ntohl(nla_get_be32(tb[NFTA_LOG_SNAPLEN]));
		}
		if (tb[NFTA_LOG_QTHRESHOLD] != NULL) {
			li->u.ulog.qthreshold =
				ntohs(nla_get_be16(tb[NFTA_LOG_QTHRESHOLD]));
		}
		break;
	}

	if (ctx->afi->family == NFPROTO_INET) {
		ret = nf_logger_find_get(NFPROTO_IPV4, li->type);
		if (ret < 0)
			return ret;

		ret = nf_logger_find_get(NFPROTO_IPV6, li->type);
		if (ret < 0) {
			nf_logger_put(NFPROTO_IPV4, li->type);
			return ret;
		}
		return 0;
	}

	return nf_logger_find_get(ctx->afi->family, li->type);
}