diff options
Diffstat (limited to 'src/statement.c')
-rw-r--r-- | src/statement.c | 119 |
1 files changed, 94 insertions, 25 deletions
diff --git a/src/statement.c b/src/statement.c index 7537c07f..ab144d63 100644 --- a/src/statement.c +++ b/src/statement.c @@ -8,12 +8,11 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ +#include <nft.h> + #include <stddef.h> -#include <stdlib.h> #include <stdio.h> -#include <stdint.h> #include <inttypes.h> -#include <string.h> #include <syslog.h> #include <rule.h> @@ -23,6 +22,7 @@ #include <netinet/ip_icmp.h> #include <netinet/icmp6.h> #include <statement.h> +#include <tcpopt.h> #include <utils.h> #include <list.h> #include <xt.h> @@ -51,7 +51,7 @@ void stmt_free(struct stmt *stmt) return; if (stmt->ops->destroy) stmt->ops->destroy(stmt); - xfree(stmt); + free(stmt); } void stmt_list_free(struct list_head *list) @@ -183,7 +183,7 @@ static void meter_stmt_destroy(struct stmt *stmt) expr_free(stmt->meter.key); expr_free(stmt->meter.set); stmt_free(stmt->meter.stmt); - xfree(stmt->meter.name); + free_const(stmt->meter.name); } static const struct stmt_ops meter_stmt_ops = { @@ -248,6 +248,37 @@ struct stmt *counter_stmt_alloc(const struct location *loc) return stmt; } +static void last_stmt_print(const struct stmt *stmt, struct output_ctx *octx) +{ + nft_print(octx, "last"); + + if (nft_output_stateless(octx)) + return; + + nft_print(octx, " used "); + + if (stmt->last.set) + time_print(stmt->last.used, octx); + else + nft_print(octx, "never"); +} + +static const struct stmt_ops last_stmt_ops = { + .type = STMT_LAST, + .name = "last", + .print = last_stmt_print, + .json = last_stmt_json, +}; + +struct stmt *last_stmt_alloc(const struct location *loc) +{ + struct stmt *stmt; + + stmt = stmt_alloc(loc, &last_stmt_ops); + stmt->flags |= STMT_F_STATEFUL; + return stmt; +} + static const char *objref_type[NFT_OBJECT_MAX + 1] = { [NFT_OBJECT_COUNTER] = "counter", [NFT_OBJECT_QUOTA] = "quota", @@ -454,9 +485,7 @@ static void limit_stmt_print(const struct stmt *stmt, struct output_ctx *octx) nft_print(octx, "limit rate %s%" PRIu64 "/%s", inv ? "over " : "", stmt->limit.rate, get_unit(stmt->limit.unit)); - if (stmt->limit.burst && stmt->limit.burst != 5) - nft_print(octx, " burst %u packets", - stmt->limit.burst); + nft_print(octx, " burst %u packets", stmt->limit.burst); break; case NFT_LIMIT_PKT_BYTES: data_unit = get_rate(stmt->limit.rate, &rate); @@ -464,7 +493,7 @@ static void limit_stmt_print(const struct stmt *stmt, struct output_ctx *octx) nft_print(octx, "limit rate %s%" PRIu64 " %s/%s", inv ? "over " : "", rate, data_unit, get_unit(stmt->limit.unit)); - if (stmt->limit.burst != 5) { + if (stmt->limit.burst != 0) { uint64_t burst; data_unit = get_rate(stmt->limit.burst, &burst); @@ -493,20 +522,25 @@ struct stmt *limit_stmt_alloc(const struct location *loc) static void queue_stmt_print(const struct stmt *stmt, struct output_ctx *octx) { - const char *delim = " "; + struct expr *e = stmt->queue.queue; + const char *delim = " flags "; nft_print(octx, "queue"); - if (stmt->queue.queue != NULL) { - nft_print(octx, " num "); - expr_print(stmt->queue.queue, octx); - } + if (stmt->queue.flags & NFT_QUEUE_FLAG_BYPASS) { nft_print(octx, "%sbypass", delim); delim = ","; } + if (stmt->queue.flags & NFT_QUEUE_FLAG_CPU_FANOUT) nft_print(octx, "%sfanout", delim); + if (e) { + nft_print(octx, " to "); + expr_print(stmt->queue.queue, octx); + } else { + nft_print(octx, " to 0"); + } } static void queue_stmt_destroy(struct stmt *stmt) @@ -522,9 +556,15 @@ static const struct stmt_ops queue_stmt_ops = { .destroy = queue_stmt_destroy, }; -struct stmt *queue_stmt_alloc(const struct location *loc) +struct stmt *queue_stmt_alloc(const struct location *loc, struct expr *e, uint16_t flags) { - return stmt_alloc(loc, &queue_stmt_ops); + struct stmt *stmt; + + stmt = stmt_alloc(loc, &queue_stmt_ops); + stmt->queue.queue = e; + stmt->queue.flags = flags; + + return stmt; } static void quota_stmt_print(const struct stmt *stmt, struct output_ctx *octx) @@ -569,7 +609,7 @@ static void reject_stmt_print(const struct stmt *stmt, struct output_ctx *octx) case NFT_REJECT_ICMPX_UNREACH: if (stmt->reject.icmp_code == NFT_REJECT_ICMPX_PORT_UNREACH) break; - nft_print(octx, " with icmpx type "); + nft_print(octx, " with icmpx "); expr_print(stmt->reject.expr, octx); break; case NFT_REJECT_ICMP_UNREACH: @@ -578,14 +618,14 @@ static void reject_stmt_print(const struct stmt *stmt, struct output_ctx *octx) if (!stmt->reject.verbose_print && stmt->reject.icmp_code == ICMP_PORT_UNREACH) break; - nft_print(octx, " with icmp type "); + nft_print(octx, " with icmp "); expr_print(stmt->reject.expr, octx); break; case NFPROTO_IPV6: if (!stmt->reject.verbose_print && stmt->reject.icmp_code == ICMP6_DST_UNREACH_NOPORT) break; - nft_print(octx, " with icmpv6 type "); + nft_print(octx, " with icmpv6 "); expr_print(stmt->reject.expr, octx); break; } @@ -657,12 +697,8 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx) break; } - if (stmt->nat.type_flags & STMT_NAT_F_CONCAT) - nft_print(octx, " addr . port"); - else if (stmt->nat.type_flags & STMT_NAT_F_PREFIX) + if (stmt->nat.type_flags & STMT_NAT_F_PREFIX) nft_print(octx, " prefix"); - else if (stmt->nat.type_flags & STMT_NAT_F_INTERVAL) - nft_print(octx, " interval"); nft_print(octx, " to"); } @@ -811,6 +847,7 @@ static const struct stmt_ops map_stmt_ops = { .name = "map", .print = map_stmt_print, .destroy = map_stmt_destroy, + .json = map_stmt_json, }; struct stmt *map_stmt_alloc(const struct location *loc) @@ -902,6 +939,37 @@ struct stmt *fwd_stmt_alloc(const struct location *loc) return stmt_alloc(loc, &fwd_stmt_ops); } +static void optstrip_stmt_print(const struct stmt *stmt, struct output_ctx *octx) +{ + const struct expr *expr = stmt->optstrip.expr; + + nft_print(octx, "reset "); + expr_print(expr, octx); +} + +static void optstrip_stmt_destroy(struct stmt *stmt) +{ + expr_free(stmt->optstrip.expr); +} + +static const struct stmt_ops optstrip_stmt_ops = { + .type = STMT_OPTSTRIP, + .name = "optstrip", + .print = optstrip_stmt_print, + .json = optstrip_stmt_json, + .destroy = optstrip_stmt_destroy, +}; + +struct stmt *optstrip_stmt_alloc(const struct location *loc, struct expr *e) +{ + struct stmt *stmt = stmt_alloc(loc, &optstrip_stmt_ops); + + e->exthdr.flags |= NFT_EXTHDR_F_PRESENT; + stmt->optstrip.expr = e; + + return stmt; +} + static void tproxy_stmt_print(const struct stmt *stmt, struct output_ctx *octx) { nft_print(octx, "tproxy"); @@ -921,7 +989,7 @@ static void tproxy_stmt_print(const struct stmt *stmt, struct output_ctx *octx) expr_print(stmt->tproxy.addr, octx); } } - if (stmt->tproxy.port && stmt->tproxy.port->etype == EXPR_VALUE) { + if (stmt->tproxy.port) { if (!stmt->tproxy.addr) nft_print(octx, " "); nft_print(octx, ":"); @@ -958,6 +1026,7 @@ static const struct stmt_ops xt_stmt_ops = { .name = "xt", .print = xt_stmt_print, .destroy = xt_stmt_destroy, + .json = xt_stmt_json, }; struct stmt *xt_stmt_alloc(const struct location *loc) |