This patch reverts Alvaro's
34040b1 ("reject: add ICMP code parameter
for indicating the type of error") and
11b2bb2 ("reject: Use protocol
context for indicating the reject type").
These patches are flawed by two things:
1) IPv6 support is broken, only ICMP codes are considered.
2) If you don't specify any transport context, the utility exits without
adding the rule, eg. nft add rule ip filter input reject.
The kernel is also flawed when it comes to the inet table. Let's revert
this until we can provide decent reject reason support.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
struct reject_stmt {
enum nft_reject_types type;
- int8_t icmp_code;
};
extern struct stmt *reject_stmt_alloc(const struct location *loc);
#include <linux/netfilter.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter/nf_tables.h>
-#include <linux/icmp.h>
#include <expression.h>
#include <statement.h>
static int stmt_evaluate_reject(struct eval_ctx *ctx, struct stmt *stmt)
{
- struct proto_ctx *pctx = &ctx->pctx;
- const struct proto_desc *base;
-
- base = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
- if (base == NULL)
- return -1;
-
- if (strcmp(base->name, "tcp") == 0 && stmt->reject.icmp_code == -1) {
- stmt->reject.type = NFT_REJECT_TCP_RST;
- stmt->reject.icmp_code = ICMP_NET_UNREACH;
- } else {
- stmt->reject.type = NFT_REJECT_ICMP_UNREACH;
- if (stmt->reject.icmp_code < 0)
- stmt->reject.icmp_code = ICMP_NET_UNREACH;
- }
-
stmt->flags |= STMT_F_TERMINAL;
return 0;
}
struct stmt *stmt;
stmt = reject_stmt_alloc(loc);
- stmt->reject.type = nft_rule_expr_get_u32(expr, NFT_EXPR_REJECT_TYPE);
- stmt->reject.icmp_code =
- nft_rule_expr_get_u8(expr, NFT_EXPR_REJECT_CODE);
list_add_tail(&stmt->list, &ctx->rule->stmts);
}
nle = alloc_nft_expr("reject");
nft_rule_expr_set_u32(nle, NFT_EXPR_REJECT_TYPE, stmt->reject.type);
- nft_rule_expr_set_u8(nle, NFT_EXPR_REJECT_CODE, stmt->reject.icmp_code);
+ nft_rule_expr_set_u8(nle, NFT_EXPR_REJECT_CODE, 0);
nft_rule_add_expr(ctx->nlr, nle);
}
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#include <linux/icmp.h>
#include <libnftnl/common.h>
#include <rule.h>
%token WEEK "week"
%token _REJECT "reject"
-%token WITH "with"
%token SNAT "snat"
%token DNAT "dnat"
%type <stmt> limit_stmt
%destructor { stmt_free($$); } limit_stmt
%type <val> time_unit
-%type <stmt> reject_stmt reject_stmt_alloc
-%destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
+%type <stmt> reject_stmt
+%destructor { stmt_free($$); } reject_stmt
%type <stmt> nat_stmt nat_stmt_alloc
%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc
%type <stmt> queue_stmt queue_stmt_alloc queue_range
| WEEK { $$ = 1ULL * 60 * 60 * 24 * 7; }
;
-
-reject_stmt : reject_stmt_alloc reject_opts
-
-reject_stmt_alloc : _REJECT
+reject_stmt : _REJECT
{
$$ = reject_stmt_alloc(&@$);
}
;
-reject_opts : /* empty */
- {
- $<stmt>0->reject.icmp_code = -1;
- }
- | WITH STRING
- {
- if (strcmp($2, "net-unreach") == 0)
- $<stmt>0->reject.icmp_code = ICMP_NET_UNREACH;
- else if (strcmp($2, "host-unreach") == 0)
- $<stmt>0->reject.icmp_code = ICMP_HOST_UNREACH;
- else if (strcmp($2, "prot-unreach") == 0)
- $<stmt>0->reject.icmp_code = ICMP_PROT_UNREACH;
- else if (strcmp($2, "port-unreach") == 0)
- $<stmt>0->reject.icmp_code = ICMP_PORT_UNREACH;
- else if (strcmp($2, "net-prohibited") == 0)
- $<stmt>0->reject.icmp_code = ICMP_NET_ANO;
- else if (strcmp($2, "host-prohibited") == 0)
- $<stmt>0->reject.icmp_code = ICMP_HOST_ANO;
- else if (strcmp($2, "admin-prohibited") == 0)
- $<stmt>0->reject.icmp_code = ICMP_PKT_FILTERED;
- }
- ;
-
nat_stmt : nat_stmt_alloc nat_stmt_args
;
"week" { return WEEK; }
"reject" { return _REJECT; }
-"with" { return WITH; }
"snat" { return SNAT; }
"dnat" { return DNAT; }
#include <statement.h>
#include <utils.h>
#include <list.h>
-#include <linux/icmp.h>
struct stmt *stmt_alloc(const struct location *loc,
const struct stmt_ops *ops)
static void reject_stmt_print(const struct stmt *stmt)
{
- const char *icmp_code_name = NULL;
-
printf("reject");
- if (stmt->reject.type != NFT_REJECT_TCP_RST) {
- switch (stmt->reject.icmp_code) {
- case ICMP_NET_UNREACH:
- icmp_code_name = "net-unreach";
- break;
- case ICMP_HOST_UNREACH:
- icmp_code_name = "host-unreach";
- break;
- case ICMP_PROT_UNREACH:
- icmp_code_name = "prot-unreach";
- break;
- case ICMP_PORT_UNREACH:
- icmp_code_name = "port-unreach";
- break;
- case ICMP_NET_ANO:
- icmp_code_name = "net-prohibited";
- break;
- case ICMP_HOST_ANO:
- icmp_code_name = "host-prohibited";
- break;
- case ICMP_PKT_FILTERED:
- icmp_code_name = "admin-prohibited";
- break;
- default:
- icmp_code_name = "Unknown icmp code";
- }
- printf(" with %s", icmp_code_name);
- }
}
static const struct stmt_ops reject_stmt_ops = {