diff options
author | Alvaro Neira <alvaroneay@gmail.com> | 2014-09-30 17:21:40 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-10-09 13:53:11 +0200 |
commit | 5fdd0b6a0600e66f9ff6d9a1d6b749aa68a3ba99 (patch) | |
tree | 282a5201207e607a0ccc94c17cab9bebb12da723 /src/datatype.c | |
parent | 67094206871b3dbaabd48894bc171e67010762c4 (diff) |
nft: complete reject support
This patch allows to use the reject action in rules. For example:
nft add rule filter input udp dport 22 reject
In this rule, we assume that the reason is network unreachable. Also
we can specify the reason with the option "with" and the reason. For example:
nft add rule filter input tcp dport 22 reject with icmp type host-unreachable
In the bridge tables and inet tables, we can use this action too. For example:
nft add rule inet filter input reject with icmp type host-unreachable
In this rule above, this generates a meta nfproto dependency to match
ipv4 traffic because we use a icmpv4 reason to reject.
If the reason is not specified, we infer it from the context.
Moreover, we have the new icmpx datatype. You can use this datatype for
the bridge and the inet tables to simplify your ruleset. For example:
nft add rule inet filter input reject with icmpx type host-unreachable
We have four icmpx reason and the mapping is:
ICMPX reason | ICMPv6 | ICMPv4
| |
admin-prohibited | admin-prohibited | admin-prohibited
port-unreachable | port-unreachable | port-unreachable
no-route | no-route | net-unreachable
host-unreachable | addr-unreachable | host-unreachable
Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/datatype.c')
-rw-r--r-- | src/datatype.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/datatype.c b/src/datatype.c index 7090b0ba..8ad211c1 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -24,6 +24,9 @@ #include <gmputil.h> #include <erec.h> +#include <netinet/ip_icmp.h> +#include <netinet/icmp6.h> + static const struct datatype *datatypes[TYPE_MAX + 1] = { [TYPE_INVALID] = &invalid_type, [TYPE_VERDICT] = &verdict_type, @@ -41,6 +44,9 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = { [TYPE_TIME] = &time_type, [TYPE_MARK] = &mark_type, [TYPE_ARPHRD] = &arphrd_type, + [TYPE_ICMP_CODE] = &icmp_code_type, + [TYPE_ICMPV6_CODE] = &icmpv6_code_type, + [TYPE_ICMPX_CODE] = &icmpx_code_type, }; void datatype_register(const struct datatype *dtype) @@ -685,6 +691,105 @@ const struct datatype mark_type = { .flags = DTYPE_F_PREFIX, }; +static const struct symbol_table icmp_code_tbl = { + .symbols = { + SYMBOL("net-unreachable", ICMP_NET_UNREACH), + SYMBOL("host-unreachable", ICMP_HOST_UNREACH), + SYMBOL("prot-unreachable", ICMP_PROT_UNREACH), + SYMBOL("port-unreachable", ICMP_PORT_UNREACH), + SYMBOL("net-prohibited", ICMP_NET_ANO), + SYMBOL("host-prohibited", ICMP_HOST_ANO), + SYMBOL("admin-prohibited", ICMP_PKT_FILTERED), + SYMBOL_LIST_END + }, +}; + +static void icmp_code_type_print(const struct expr *expr) +{ + return symbolic_constant_print(&icmp_code_tbl, expr); +} + +static struct error_record *icmp_code_type_parse(const struct expr *sym, + struct expr **res) +{ + return symbolic_constant_parse(sym, &icmp_code_tbl, res); +} + +const struct datatype icmp_code_type = { + .type = TYPE_ICMP_CODE, + .name = "icmp code", + .desc = "icmp code", + .size = BITS_PER_BYTE, + .byteorder = BYTEORDER_BIG_ENDIAN, + .basetype = &integer_type, + .print = icmp_code_type_print, + .parse = icmp_code_type_parse, +}; + +static const struct symbol_table icmpv6_code_tbl = { + .symbols = { + SYMBOL("no-route", ICMP6_DST_UNREACH_NOROUTE), + SYMBOL("admin-prohibited", ICMP6_DST_UNREACH_ADMIN), + SYMBOL("addr-unreachable", ICMP6_DST_UNREACH_ADDR), + SYMBOL("port-unreachable", ICMP6_DST_UNREACH_NOPORT), + SYMBOL_LIST_END + }, +}; + +static void icmpv6_code_type_print(const struct expr *expr) +{ + return symbolic_constant_print(&icmpv6_code_tbl, expr); +} + +static struct error_record *icmpv6_code_type_parse(const struct expr *sym, + struct expr **res) +{ + return symbolic_constant_parse(sym, &icmpv6_code_tbl, res); +} + +const struct datatype icmpv6_code_type = { + .type = TYPE_ICMPV6_CODE, + .name = "icmpv6 code", + .desc = "icmpv6 code", + .size = BITS_PER_BYTE, + .byteorder = BYTEORDER_BIG_ENDIAN, + .basetype = &integer_type, + .print = icmpv6_code_type_print, + .parse = icmpv6_code_type_parse, +}; + +static const struct symbol_table icmpx_code_tbl = { + .symbols = { + SYMBOL("port-unreachable", NFT_REJECT_ICMPX_PORT_UNREACH), + SYMBOL("admin-prohibited", NFT_REJECT_ICMPX_ADMIN_PROHIBITED), + SYMBOL("no-route", NFT_REJECT_ICMPX_NO_ROUTE), + SYMBOL("host-unreachable", NFT_REJECT_ICMPX_HOST_UNREACH), + SYMBOL_LIST_END + }, +}; + +static void icmpx_code_type_print(const struct expr *expr) +{ + return symbolic_constant_print(&icmpx_code_tbl, expr); +} + +static struct error_record *icmpx_code_type_parse(const struct expr *sym, + struct expr **res) +{ + return symbolic_constant_parse(sym, &icmpx_code_tbl, res); +} + +const struct datatype icmpx_code_type = { + .type = TYPE_ICMPX_CODE, + .name = "icmpx code", + .desc = "icmpx code", + .size = BITS_PER_BYTE, + .byteorder = BYTEORDER_BIG_ENDIAN, + .basetype = &integer_type, + .print = icmpx_code_type_print, + .parse = icmpx_code_type_parse, +}; + static void time_type_print(const struct expr *expr) { uint64_t days, hours, minutes, seconds; |