Blame src/cache.c

Packit c5a612
/*
Packit c5a612
 * Copyright (c) 2019 Pablo Neira Ayuso <pablo@netfilter.org>
Packit c5a612
 *
Packit c5a612
 * This program is free software; you can redistribute it and/or modify
Packit c5a612
 * it under the terms of the GNU General Public License version 2 (or any
Packit c5a612
 * later) as published by the Free Software Foundation.
Packit c5a612
 */
Packit c5a612
Packit c5a612
#include <expression.h>
Packit c5a612
#include <statement.h>
Packit c5a612
#include <rule.h>
Packit c5a612
#include <erec.h>
Packit c5a612
#include <utils.h>
Packit c5a612
#include <cache.h>
Packit c5a612
Packit c5a612
static unsigned int evaluate_cache_add(struct cmd *cmd, unsigned int flags)
Packit c5a612
{
Packit c5a612
	switch (cmd->obj) {
Packit c5a612
	case CMD_OBJ_CHAIN:
Packit c5a612
	case CMD_OBJ_SET:
Packit c5a612
	case CMD_OBJ_COUNTER:
Packit c5a612
	case CMD_OBJ_QUOTA:
Packit c5a612
	case CMD_OBJ_LIMIT:
Packit c5a612
	case CMD_OBJ_SECMARK:
Packit c5a612
	case CMD_OBJ_FLOWTABLE:
Packit c5a612
		flags |= NFT_CACHE_TABLE;
Packit c5a612
		break;
Packit c5a612
	case CMD_OBJ_SETELEM:
Packit c5a612
		flags |= NFT_CACHE_TABLE |
Packit c5a612
			 NFT_CACHE_CHAIN |
Packit c5a612
			 NFT_CACHE_SET |
Packit c5a612
			 NFT_CACHE_OBJECT |
Packit c5a612
			 NFT_CACHE_SETELEM;
Packit c5a612
		break;
Packit c5a612
	case CMD_OBJ_RULE:
Packit c5a612
		flags |= NFT_CACHE_TABLE |
Packit c5a612
			 NFT_CACHE_CHAIN |
Packit c5a612
			 NFT_CACHE_SET |
Packit c5a612
			 NFT_CACHE_OBJECT |
Packit c5a612
			 NFT_CACHE_FLOWTABLE;
Packit c5a612
Packit c5a612
		if (cmd->handle.index.id ||
Packit c5a612
		    cmd->handle.position.id)
Packit c5a612
			flags |= NFT_CACHE_RULE | NFT_CACHE_UPDATE;
Packit c5a612
		break;
Packit c5a612
	default:
Packit c5a612
		break;
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}
Packit c5a612
Packit c5a612
static unsigned int evaluate_cache_del(struct cmd *cmd, unsigned int flags)
Packit c5a612
{
Packit c5a612
	switch (cmd->obj) {
Packit c5a612
	case CMD_OBJ_SETELEM:
Packit c5a612
		flags |= NFT_CACHE_SETELEM;
Packit c5a612
		break;
Packit c5a612
	default:
Packit c5a612
		break;
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}
Packit c5a612
Packit c5a612
static unsigned int evaluate_cache_get(struct cmd *cmd, unsigned int flags)
Packit c5a612
{
Packit c5a612
	switch (cmd->obj) {
Packit c5a612
	case CMD_OBJ_SETELEM:
Packit c5a612
		flags |= NFT_CACHE_TABLE |
Packit c5a612
			 NFT_CACHE_SET |
Packit c5a612
			 NFT_CACHE_SETELEM;
Packit c5a612
		break;
Packit c5a612
	default:
Packit c5a612
		break;
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}
Packit c5a612
Packit c5a612
static unsigned int evaluate_cache_flush(struct cmd *cmd, unsigned int flags)
Packit c5a612
{
Packit c5a612
	switch (cmd->obj) {
Packit c5a612
	case CMD_OBJ_SET:
Packit c5a612
	case CMD_OBJ_MAP:
Packit c5a612
	case CMD_OBJ_METER:
Packit c5a612
		flags |= NFT_CACHE_SET;
Packit c5a612
		break;
Packit c5a612
	case CMD_OBJ_RULESET:
Packit c5a612
		flags |= NFT_CACHE_FLUSHED;
Packit c5a612
		break;
Packit c5a612
	default:
Packit c5a612
		break;
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}
Packit c5a612
Packit c5a612
static unsigned int evaluate_cache_rename(struct cmd *cmd, unsigned int flags)
Packit c5a612
{
Packit c5a612
	switch (cmd->obj) {
Packit c5a612
	case CMD_OBJ_CHAIN:
Packit c5a612
		flags |= NFT_CACHE_CHAIN;
Packit c5a612
		break;
Packit c5a612
	default:
Packit c5a612
		break;
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}
Packit c5a612
Packit c5a612
unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds)
Packit c5a612
{
Packit c5a612
	unsigned int flags = NFT_CACHE_EMPTY;
Packit c5a612
	struct cmd *cmd;
Packit c5a612
Packit c5a612
	list_for_each_entry(cmd, cmds, list) {
Packit c5a612
		switch (cmd->op) {
Packit c5a612
		case CMD_ADD:
Packit c5a612
		case CMD_INSERT:
Packit c5a612
		case CMD_CREATE:
Packit c5a612
			flags = evaluate_cache_add(cmd, flags);
Packit c5a612
			if (nft_output_echo(&nft->output))
Packit c5a612
				flags |= NFT_CACHE_FULL;
Packit c5a612
			break;
Packit c5a612
		case CMD_REPLACE:
Packit c5a612
			flags = NFT_CACHE_FULL;
Packit c5a612
			break;
Packit c5a612
		case CMD_DELETE:
Packit c5a612
			flags |= NFT_CACHE_TABLE |
Packit c5a612
				 NFT_CACHE_CHAIN |
Packit c5a612
				 NFT_CACHE_SET |
Packit c5a612
				 NFT_CACHE_FLOWTABLE |
Packit c5a612
				 NFT_CACHE_OBJECT;
Packit c5a612
Packit c5a612
			flags = evaluate_cache_del(cmd, flags);
Packit c5a612
			break;
Packit c5a612
		case CMD_GET:
Packit c5a612
			flags = evaluate_cache_get(cmd, flags);
Packit c5a612
			break;
Packit c5a612
		case CMD_RESET:
Packit fcdabb
			flags |= NFT_CACHE_TABLE;
Packit fcdabb
			break;
Packit fcdabb
		case CMD_LIST:
Packit c5a612
		case CMD_EXPORT:
Packit c5a612
		case CMD_MONITOR:
Packit c5a612
			flags |= NFT_CACHE_FULL;
Packit c5a612
			break;
Packit c5a612
		case CMD_FLUSH:
Packit c5a612
			flags = evaluate_cache_flush(cmd, flags);
Packit c5a612
			break;
Packit c5a612
		case CMD_RENAME:
Packit c5a612
			flags = evaluate_cache_rename(cmd, flags);
Packit c5a612
			break;
Packit c5a612
		case CMD_DESCRIBE:
Packit c5a612
		case CMD_IMPORT:
Packit c5a612
			break;
Packit c5a612
		default:
Packit c5a612
			break;
Packit c5a612
		}
Packit c5a612
	}
Packit c5a612
Packit c5a612
	return flags;
Packit c5a612
}