summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorTomasz Bursztyka <tomasz.bursztyka@linux.intel.com>2013-09-04 12:50:19 +0300
committerPablo Neira Ayuso <pablo@netfilter.org>2013-09-04 12:31:17 +0200
commit108d9f6b3af0f70459fb7ccc1dfc5452d3f3646e (patch)
tree69f0d49bbc5e8daf02129b47caeee7ea4457d87b /src/evaluate.c
parentffad92b5f34d9960d8c6b1c70041b347634a2a76 (diff)
src: Wrap netfilter hooks around human readable strings
This allows to use unique, human readable, hook names for the command line and let the user being unaware of the complex netfilter's hook names and there difference depending on the netfilter family. So: add chain foo bar { type route hook NF_INET_LOCAL_IN 0; } becomes: add chain foo bar { type route hook input 0; } It also fixes then the difference in hook values between families. I.e. ARP family has different values for input, forward and output compared to IPv4, IPv6 or bridge. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 85c647e5..29fa32bd 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -14,6 +14,8 @@
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_arp.h>
#include <linux/netfilter/nf_tables.h>
#include <expression.h>
@@ -54,6 +56,8 @@ static int __fmtstring(4, 5) __stmt_binary_error(struct eval_ctx *ctx,
__stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
#define stmt_binary_error(ctx, s1, s2, fmt, args...) \
__stmt_binary_error(ctx, &(s1)->location, &(s2)->location, fmt, ## args)
+#define chain_error(ctx, s1, fmt, args...) \
+ __stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args)
static int __fmtstring(3, 4) set_error(struct eval_ctx *ctx,
const struct set *set,
@@ -1247,10 +1251,49 @@ static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule)
return 0;
}
+static uint32_t str2hooknum(uint32_t family, const char *hook)
+{
+ switch (family) {
+ case NFPROTO_IPV4:
+ case NFPROTO_BRIDGE:
+ case NFPROTO_IPV6:
+ /* These families have overlapping values for each hook */
+ if (!strcmp(hook, "prerouting"))
+ return NF_INET_PRE_ROUTING;
+ else if (!strcmp(hook, "input"))
+ return NF_INET_LOCAL_IN;
+ else if (!strcmp(hook, "forward"))
+ return NF_INET_FORWARD;
+ else if (!strcmp(hook, "postrouting"))
+ return NF_INET_POST_ROUTING;
+ else if (!strcmp(hook, "output"))
+ return NF_INET_LOCAL_OUT;
+ case NFPROTO_ARP:
+ if (!strcmp(hook, "input"))
+ return NF_ARP_IN;
+ else if (!strcmp(hook, "forward"))
+ return NF_ARP_FORWARD;
+ else if (!strcmp(hook, "output"))
+ return NF_ARP_OUT;
+ default:
+ break;
+ }
+
+ return NF_INET_NUMHOOKS;
+}
+
static int chain_evaluate(struct eval_ctx *ctx, struct chain *chain)
{
struct rule *rule;
+ if (chain->flags & CHAIN_F_BASECHAIN) {
+ chain->hooknum = str2hooknum(chain->handle.family,
+ chain->hookstr);
+ if (chain->hooknum == NF_INET_NUMHOOKS)
+ return chain_error(ctx, chain, "invalid hook %s",
+ chain->hookstr);
+ }
+
list_for_each_entry(rule, &chain->rules, list) {
handle_merge(&rule->handle, &chain->handle);
if (rule_evaluate(ctx, rule) < 0)