From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH iptables-nft 2/7] nft-shared: support native tcp port range delinearize
Date: Tue, 25 Jan 2022 17:52:56 +0100 [thread overview]
Message-ID: <20220125165301.5960-3-fw@strlen.de> (raw)
In-Reply-To: <20220125165301.5960-1-fw@strlen.de>
adds support for
nft ... tcp dport != min-max
Signed-off-by: Florian Westphal <fw@strlen.de>
---
iptables/nft-shared.c | 113 ++++++++++++++++++++++++++++++++++++++++++
iptables/nft-shared.h | 1 +
iptables/nft.c | 1 +
3 files changed, 115 insertions(+)
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 674c72b35ae7..7f6b4ff392d9 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -513,6 +513,43 @@ static struct xt_tcp *nft_tcp_match(struct nft_xt_ctx *ctx,
return tcp;
}
+static void nft_complete_tcp_range(struct nft_xt_ctx *ctx,
+ struct iptables_command_state *cs,
+ int sport_from, int sport_to,
+ int dport_from, int dport_to,
+ uint8_t op)
+{
+ struct xt_tcp *tcp = nft_tcp_match(ctx, cs);
+
+ if (!tcp)
+ return;
+
+ if (sport_from >= 0) {
+ switch (op) {
+ case NFT_RANGE_NEQ:
+ tcp->invflags |= XT_TCP_INV_SRCPT;
+ /* fallthrough */
+ case NFT_RANGE_EQ:
+ tcp->spts[0] = sport_from;
+ tcp->spts[1] = sport_to;
+ break;
+ }
+ }
+
+ if (dport_to >= 0) {
+ switch (op) {
+ case NFT_CMP_NEQ:
+ tcp->invflags |= XT_TCP_INV_DSTPT;
+ /* fallthrough */
+ case NFT_CMP_EQ:
+ tcp->dpts[0] = dport_from;
+ tcp->dpts[1] = dport_to;
+ break;
+ }
+ }
+}
+
+
static void nft_complete_tcp(struct nft_xt_ctx *ctx,
struct iptables_command_state *cs,
int sport, int dport,
@@ -584,6 +621,20 @@ static void nft_complete_th_port(struct nft_xt_ctx *ctx,
}
}
+static void nft_complete_th_port_range(struct nft_xt_ctx *ctx,
+ struct iptables_command_state *cs,
+ uint8_t proto,
+ int sport_from, int sport_to,
+ int dport_from, int dport_to, uint8_t op)
+{
+ switch (proto) {
+ case IPPROTO_TCP:
+ nft_complete_tcp_range(ctx, cs, sport_from, sport_to, dport_from, dport_to, op);
+ break;
+ }
+}
+
+
static void nft_complete_transport(struct nft_xt_ctx *ctx,
struct nftnl_expr *e, void *data)
{
@@ -632,6 +683,47 @@ static void nft_complete_transport(struct nft_xt_ctx *ctx,
}
}
+static void nft_complete_transport_range(struct nft_xt_ctx *ctx,
+ struct nftnl_expr *e,
+ struct iptables_command_state *cs)
+{
+ unsigned int len_from, len_to;
+ uint8_t proto, op;
+ uint16_t from, to;
+
+ switch (ctx->h->family) {
+ case NFPROTO_IPV4:
+ proto = ctx->cs->fw.ip.proto;
+ break;
+ case NFPROTO_IPV6:
+ proto = ctx->cs->fw6.ipv6.proto;
+ break;
+ default:
+ proto = 0;
+ break;
+ }
+
+ nftnl_expr_get(e, NFTNL_EXPR_RANGE_FROM_DATA, &len_from);
+ nftnl_expr_get(e, NFTNL_EXPR_RANGE_FROM_DATA, &len_to);
+ if (len_to != len_from || len_to != 2)
+ return;
+
+ op = nftnl_expr_get_u32(e, NFTNL_EXPR_RANGE_OP);
+
+ from = ntohs(nftnl_expr_get_u16(e, NFTNL_EXPR_RANGE_FROM_DATA));
+ to = ntohs(nftnl_expr_get_u16(e, NFTNL_EXPR_RANGE_TO_DATA));
+
+ switch(ctx->payload.offset) {
+ case 0:
+ nft_complete_th_port_range(ctx, cs, proto, from, to, -1, -1, op);
+ return;
+ case 2:
+ to = ntohs(nftnl_expr_get_u16(e, NFTNL_EXPR_RANGE_TO_DATA));
+ nft_complete_th_port_range(ctx, cs, proto, -1, -1, from, to, op);
+ return;
+ }
+}
+
static void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
void *data = ctx->cs;
@@ -811,6 +903,25 @@ static void nft_parse_lookup(struct nft_xt_ctx *ctx, struct nft_handle *h,
ctx->h->ops->parse_lookup(ctx, e, NULL);
}
+static void nft_parse_range(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
+{
+ uint32_t reg;
+
+ reg = nftnl_expr_get_u32(e, NFTNL_EXPR_RANGE_SREG);
+ if (reg != ctx->reg)
+ return;
+
+ if (ctx->flags & NFT_XT_CTX_PAYLOAD) {
+ switch (ctx->payload.base) {
+ case NFT_PAYLOAD_TRANSPORT_HEADER:
+ nft_complete_transport_range(ctx, e, ctx->cs);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
void nft_rule_to_iptables_command_state(struct nft_handle *h,
const struct nftnl_rule *r,
struct iptables_command_state *cs)
@@ -855,6 +966,8 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h,
nft_parse_lookup(&ctx, h, expr);
else if (strcmp(name, "log") == 0)
nft_parse_log(&ctx, expr);
+ else if (strcmp(name, "range") == 0)
+ nft_parse_range(&ctx, expr);
expr = nftnl_expr_iter_next(iter);
}
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 0a8be7099aa2..1468d5608158 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -45,6 +45,7 @@ enum {
NFT_XT_CTX_BITWISE = (1 << 2),
NFT_XT_CTX_IMMEDIATE = (1 << 3),
NFT_XT_CTX_PREV_PAYLOAD = (1 << 4),
+ NFT_XT_CTX_RANGE = (1 << 5),
};
struct nft_xt_ctx {
diff --git a/iptables/nft.c b/iptables/nft.c
index b5de687c5c4c..f7f5950625d0 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3529,6 +3529,7 @@ static const char *supported_exprs[] = {
"counter",
"immediate",
"lookup",
+ "range",
};
--
2.34.1
next prev parent reply other threads:[~2022-01-25 16:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-25 16:52 [PATCH iptables-nft 0/7] iptables: prefer native expressions for udp and tcp matches Florian Westphal
2022-01-25 16:52 ` [PATCH iptables-nft 1/7] nft-shared: support native tcp port delinearize Florian Westphal
2022-01-25 16:52 ` Florian Westphal [this message]
2022-01-25 16:52 ` [PATCH iptables-nft 3/7] nft-shared: support native udp " Florian Westphal
2022-01-25 16:52 ` [PATCH iptables-nft 4/7] nft: prefer native expressions instead of udp match Florian Westphal
2022-01-25 16:52 ` [PATCH iptables-nft 5/7] nft: prefer native expressions instead of tcp match Florian Westphal
2022-01-25 16:53 ` [PATCH iptables-nft 6/7] nft-shared: add tcp flag dissection Florian Westphal
2022-01-25 16:53 ` [PATCH iptables-nft 7/7] nft: add support for native tcp flag matching Florian Westphal
2022-01-29 12:44 ` [PATCH iptables-nft 0/7] iptables: prefer native expressions for udp and tcp matches Florian Westphal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220125165301.5960-3-fw@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.