Re: [nft PATCH 4/4 v4] nft: complete reject support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



First off, thanks for the effort. Several comments below.

On Fri, Sep 26, 2014 at 06:50:55PM +0200, Alvaro Neira Ayuso wrote:
> +/* The reason to reject this hasn't been specified */

You can remove this comment above. You selected a function to
encapsulate the code per reason that explains the thing by itself.

> +static int stmt_evaluate_reject_no_reason(struct eval_ctx *ctx,
> +					  struct stmt *stmt)
> +{
> +	switch (ctx->pctx.family) {
> +	case NFPROTO_IPV4:
> +	case NFPROTO_IPV6:
> +		stmt->reject.type = NFT_REJECT_ICMP_UNREACH;
> +		stmt->reject.family = ctx->pctx.family;
> +		if (ctx->pctx.family == NFPROTO_IPV4)
> +			stmt->reject.icmp_code = ICMP_PORT_UNREACH;
> +		else
> +			stmt->reject.icmp_code = ICMP6_DST_UNREACH_NOPORT;
> +		break;
> +	case NFPROTO_INET:
> +	case NFPROTO_BRIDGE:
> +		stmt->reject.type = NFT_REJECT_ICMPX_UNREACH;
> +		stmt->reject.icmp_code = NFT_REJECT_ICMPX_PORT_UNREACH;
> +		break;
> +	}
> +	return 0;
> +}
> +
> +/* The reason to reject this has been specified with icmp reason */

Same thing here.

> +static int stmt_evaluate_reject_icmp_reason(struct eval_ctx *ctx,
> +					    struct stmt *stmt)

I'd suggest: stmt_evaluate_reject_with_icmp(...)

> +{
> +	struct error_record *erec;
> +	struct expr *code;
> +
> +	erec = symbol_parse(stmt->reject.expr, &code);
> +	if (erec != NULL) {
> +		erec_queue(erec, ctx->msgs);
> +		return -1;
> +	}
> +	stmt->reject.icmp_code = mpz_get_uint8(code->value);
> +	return 0;
> +}
> +
> +/* The reason to reject this has been specified with tcp reset */

And here.

> +static int stmt_evaluate_reject_tcp_reason(struct eval_ctx *ctx,
> +					   struct stmt *stmt)

I'd suggest: stmt_evaluate_reject_with_tcp(...)

> +{
> +	int protonum;
> +	const struct proto_desc *desc, *base;
> +	struct proto_ctx *pctx = &ctx->pctx;
> +
> +	base = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
> +	desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
> +	if (desc == NULL)
> +		return 0;
> +
> +	protonum = proto_find_num(base, desc);
> +	switch (protonum) {
> +	case IPPROTO_TCP:
> +		break;
> +	default:
> +		if (stmt->reject.type == NFT_REJECT_TCP_RST) {
> +			return stmt_error(ctx, stmt,
> +				 "you cannot use tcp reset with this protocol");
> +		}
> +		break;
> +	}
> +	return 0;
> +}
> +
> +static int stmt_evaluate_reject(struct eval_ctx *ctx, struct stmt *stmt)
> +{
> +	struct expr *expr = ctx->cmd->expr;
> +
> +	if (stmt->reject.icmp_code < 0) {
> +		stmt_evaluate_reject_no_reason(ctx, stmt);
> +	} else if (stmt->reject.expr != NULL) {
> +		if (stmt_evaluate_reject_icmp_reason(ctx, stmt) < 0)
> +			return -1;
> +	} else {
> +		if (stmt_evaluate_reject_tcp_reason(ctx, stmt) < 0)
> +			return -1;
> +	}
> +
> +	return stmt_evaluate_reject_family(ctx, stmt, expr);
> +}
> +
>  static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
>  {
>  	struct proto_ctx *pctx = &ctx->pctx;
> diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
> index 796b632..12cb9e0 100644
> --- a/src/netlink_delinearize.c
> +++ b/src/netlink_delinearize.c
> @@ -14,6 +14,9 @@
>  #include <string.h>
>  #include <limits.h>
>  #include <linux/netfilter/nf_tables.h>
> +#include <arpa/inet.h>
> +#include <linux/netfilter.h>
> +#include <net/ethernet.h>
>  #include <netlink.h>
>  #include <rule.h>
>  #include <statement.h>
> @@ -474,6 +477,9 @@ static void netlink_parse_reject(struct netlink_parse_ctx *ctx,
>  	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);
>  }
>  
> @@ -899,6 +905,38 @@ static void expr_postprocess(struct rule_pp_ctx *ctx,
>  	}
>  }
>  
> +static void stmt_reject_postprocess(struct rule_pp_ctx rctx, struct stmt *stmt)
> +{
> +	const struct proto_desc *desc, *base;
> +	int protocol;
> +
> +	switch (rctx.pctx.family) {
> +	case NFPROTO_IPV4:
> +	case NFPROTO_IPV6:
> +		stmt->reject.family = rctx.pctx.family;
> +		break;
> +	case NFPROTO_INET:
> +	case NFPROTO_BRIDGE:
> +		if (rctx.pbase == PROTO_BASE_INVALID)
> +			return;
> +
> +		if (stmt->reject.type == NFT_REJECT_ICMPX_UNREACH)
> +			break;
> +
> +		base = rctx.pctx.protocol[PROTO_BASE_LL_HDR].desc;
> +		desc = rctx.pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
> +		protocol = proto_find_num(base, desc);
> +		if (protocol == __constant_htons(ETH_P_IP))
> +			stmt->reject.family = NFPROTO_IPV4;
> +		else if (protocol == __constant_htons(ETH_P_IPV6))
> +			stmt->reject.family = NFPROTO_IPV6;
> +		else
> +			stmt->reject.family = protocol;

I think you can generate an expression here to set up
stmt->reject.expr. That should help to simplify reject_stmt_print()
since you can use the new datatypes that you have defined.

I mean, with stmt->reject.expr, you can skip this:

+const char *reject_stmt_code_ip[] = {
+       [ICMP_NET_UNREACH]      = "net-unreach",
...

and get reject_stmt_print() in a diet.

I'm refering to the code in src/statement.c

[...]
> +reject_opts		:       /* empty */
> +			{
> +				$<stmt>0->reject.type = -1;
> +				$<stmt>0->reject.icmp_code = -1;
> +			}
> +			|	WITH	ICMP	TYPE	STRING
> +	       		{
> +				$<stmt>0->reject.family = NFPROTO_IPV4;
> +				$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
> +				$<stmt>0->reject.expr = symbol_expr_alloc(&@$,
> +								   SYMBOL_VALUE,
> +							   current_scope(state),
> +									 $4);

To fulfill the 80-chars per line rule, I'd suggest:

				$<stmt>0->reject.expr =
                                        symbol_expr_alloc(&@$, SYMBOL_VALUE,
                                                          current_scope(state),
                                                          $4);

> +				$<stmt>0->reject.expr->dtype = &icmp_code_type;
> +			}
> +			|	WITH	ICMP6	TYPE	STRING
> +			{
> +				$<stmt>0->reject.family = NFPROTO_IPV6;
> +				$<stmt>0->reject.type = NFT_REJECT_ICMP_UNREACH;
> +				$<stmt>0->reject.expr = symbol_expr_alloc(&@$,
> +								   SYMBOL_VALUE,
> +							   current_scope(state),
> +									 $4);

Same here.

> +				$<stmt>0->reject.expr->dtype = &icmpv6_code_type;
> +			}
> +			|	WITH	ICMPX	TYPE	STRING
> +			{
> +				$<stmt>0->reject.type = NFT_REJECT_ICMPX_UNREACH;
> +				$<stmt>0->reject.expr = symbol_expr_alloc(&@$,
> +								   SYMBOL_VALUE,
> +							   current_scope(state),
> +									 $4);

And here.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux