summaryrefslogtreecommitdiffstats
path: root/iptables
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2023-02-16 22:24:16 +0100
committerPhil Sutter <phil@nwl.cc>2023-02-17 18:18:48 +0100
commite69c2b467d7567027db14d48570fe277495ed52f (patch)
treec5b887ac2312c2623a7bb4c32146e3a6d4f5acd6 /iptables
parent073d4deddd8f3fc5b6c0b6e62b28f5b1895974b1 (diff)
nft-shared: Simplify using nft_create_match()
Perform the nft_family_ops::parse_match call from inside nft_create_match(). It frees callers from having to access the match itself. Then return a pointer to match data instead of the match itself. Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables')
-rw-r--r--iptables/nft-shared.c106
1 files changed, 40 insertions, 66 deletions
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 52e745fe..1b22eb7a 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -301,7 +301,7 @@ static void parse_ifname(const char *name, unsigned int len, char *dst, unsigned
memset(mask, 0xff, len - 2);
}
-static struct xtables_match *
+static void *
nft_create_match(struct nft_xt_ctx *ctx,
struct iptables_command_state *cs,
const char *name, bool reuse);
@@ -319,15 +319,12 @@ static uint32_t get_meta_mask(struct nft_xt_ctx *ctx, enum nft_registers sreg)
static int parse_meta_mark(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
struct xt_mark_mtinfo1 *mark;
- struct xtables_match *match;
uint32_t value;
- match = nft_create_match(ctx, ctx->cs, "mark", false);
- if (!match)
+ mark = nft_create_match(ctx, ctx->cs, "mark", false);
+ if (!mark)
return -1;
- mark = (void*)match->m->data;
-
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
mark->invert = 1;
@@ -341,15 +338,12 @@ static int parse_meta_mark(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
static int parse_meta_pkttype(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
{
struct xt_pkttype_info *pkttype;
- struct xtables_match *match;
uint8_t value;
- match = nft_create_match(ctx, ctx->cs, "pkttype", false);
- if (!match)
+ pkttype = nft_create_match(ctx, ctx->cs, "pkttype", false);
+ if (!pkttype)
return -1;
- pkttype = (void*)match->m->data;
-
if (nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP) == NFT_CMP_NEQ)
pkttype->invert = 1;
@@ -659,7 +653,7 @@ nft_find_match_in_cs(struct iptables_command_state *cs, const char *name)
return NULL;
}
-static struct xtables_match *
+static void *
nft_create_match(struct nft_xt_ctx *ctx,
struct iptables_command_state *cs,
const char *name, bool reuse)
@@ -671,7 +665,7 @@ nft_create_match(struct nft_xt_ctx *ctx,
if (reuse) {
match = nft_find_match_in_cs(cs, name);
if (match)
- return match;
+ return match->m->data;
}
match = xtables_find_match(name, XTF_TRY_LOAD,
@@ -689,32 +683,10 @@ nft_create_match(struct nft_xt_ctx *ctx,
xs_init_match(match);
- return match;
-}
-
-static struct xt_udp *nft_udp_match(struct nft_xt_ctx *ctx,
- struct iptables_command_state *cs)
-{
- struct xtables_match *match;
-
- match = nft_create_match(ctx, cs, "udp", true);
- if (!match)
- return NULL;
-
- return (struct xt_udp *)match->m->data;
-}
-
-static struct xt_tcp *nft_tcp_match(struct nft_xt_ctx *ctx,
- struct iptables_command_state *cs)
-{
- struct xtables_match *match;
+ if (ctx->h->ops->parse_match)
+ ctx->h->ops->parse_match(match, cs);
- match = nft_create_match(ctx, cs, "tcp", true);
- if (!match) {
- ctx->errmsg = "tcp match extension not found";
- return NULL;
- }
- return (struct xt_tcp *)match->m->data;
+ return match->m->data;
}
static void nft_parse_udp_range(struct nft_xt_ctx *ctx,
@@ -723,10 +695,12 @@ static void nft_parse_udp_range(struct nft_xt_ctx *ctx,
int dport_from, int dport_to,
uint8_t op)
{
- struct xt_udp *udp = nft_udp_match(ctx, cs);
+ struct xt_udp *udp = nft_create_match(ctx, cs, "udp", true);
- if (!udp)
+ if (!udp) {
+ ctx->errmsg = "udp match extension not found";
return;
+ }
if (sport_from >= 0) {
switch (op) {
@@ -759,10 +733,12 @@ static void nft_parse_tcp_range(struct nft_xt_ctx *ctx,
int dport_from, int dport_to,
uint8_t op)
{
- struct xt_tcp *tcp = nft_tcp_match(ctx, cs);
+ struct xt_tcp *tcp = nft_create_match(ctx, cs, "tcp", true);
- if (!tcp)
+ if (!tcp) {
+ ctx->errmsg = "tcp match extension not found";
return;
+ }
if (sport_from >= 0) {
switch (op) {
@@ -823,10 +799,12 @@ static void nft_parse_udp(struct nft_xt_ctx *ctx,
int sport, int dport,
uint8_t op)
{
- struct xt_udp *udp = nft_udp_match(ctx, cs);
+ struct xt_udp *udp = nft_create_match(ctx, cs, "udp", true);
- if (!udp)
+ if (!udp) {
+ ctx->errmsg = "udp match extension not found";
return;
+ }
port_match_single_to_range(udp->spts, &udp->invflags,
op, sport, XT_UDP_INV_SRCPT);
@@ -839,10 +817,12 @@ static void nft_parse_tcp(struct nft_xt_ctx *ctx,
int sport, int dport,
uint8_t op)
{
- struct xt_tcp *tcp = nft_tcp_match(ctx, cs);
+ struct xt_tcp *tcp = nft_create_match(ctx, cs, "tcp", true);
- if (!tcp)
+ if (!tcp) {
+ ctx->errmsg = "tcp match extension not found";
return;
+ }
port_match_single_to_range(tcp->spts, &tcp->invflags,
op, sport, XT_TCP_INV_SRCPT);
@@ -855,11 +835,10 @@ static void nft_parse_icmp(struct nft_xt_ctx *ctx,
struct nft_xt_ctx_reg *sreg,
uint8_t op, const char *data, size_t dlen)
{
- struct xtables_match *match;
struct ipt_icmp icmp = {
.type = UINT8_MAX,
.code = { 0, UINT8_MAX },
- };
+ }, *icmpp;
if (dlen < 1)
goto out_err_len;
@@ -884,25 +863,25 @@ static void nft_parse_icmp(struct nft_xt_ctx *ctx,
switch (ctx->h->family) {
case NFPROTO_IPV4:
- match = nft_create_match(ctx, cs, "icmp", false);
+ icmpp = nft_create_match(ctx, cs, "icmp", false);
break;
case NFPROTO_IPV6:
if (icmp.type == UINT8_MAX) {
ctx->errmsg = "icmp6 code with any type match not supported";
return;
}
- match = nft_create_match(ctx, cs, "icmp6", false);
+ icmpp = nft_create_match(ctx, cs, "icmp6", false);
break;
default:
ctx->errmsg = "unexpected family for icmp match";
return;
}
- if (!match) {
+ if (!icmpp) {
ctx->errmsg = "icmp match extension not found";
return;
}
- memcpy(match->m->data, &icmp, sizeof(icmp));
+ memcpy(icmpp, &icmp, sizeof(icmp));
return;
out_err_len:
@@ -946,10 +925,12 @@ static void nft_parse_tcp_flags(struct nft_xt_ctx *ctx,
struct iptables_command_state *cs,
uint8_t op, uint8_t flags, uint8_t mask)
{
- struct xt_tcp *tcp = nft_tcp_match(ctx, cs);
+ struct xt_tcp *tcp = nft_create_match(ctx, cs, "tcp", true);
- if (!tcp)
+ if (!tcp) {
+ ctx->errmsg = "tcp match extension not found";
return;
+ }
if (op == NFT_CMP_NEQ)
tcp->invflags |= XT_TCP_INV_FLAGS;
@@ -1202,7 +1183,6 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
__u32 burst = nftnl_expr_get_u32(e, NFTNL_EXPR_LIMIT_BURST);
__u64 unit = nftnl_expr_get_u64(e, NFTNL_EXPR_LIMIT_UNIT);
__u64 rate = nftnl_expr_get_u64(e, NFTNL_EXPR_LIMIT_RATE);
- struct xtables_match *match;
struct xt_rateinfo *rinfo;
switch (ctx->h->family) {
@@ -1216,18 +1196,14 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
exit(EXIT_FAILURE);
}
- match = nft_create_match(ctx, ctx->cs, "limit", false);
- if (match == NULL) {
+ rinfo = nft_create_match(ctx, ctx->cs, "limit", false);
+ if (!rinfo) {
ctx->errmsg = "limit match extension not found";
return;
}
- rinfo = (void *)match->m->data;
rinfo->avg = XT_LIMIT_SCALE * unit / rate;
rinfo->burst = burst;
-
- if (ctx->h->ops->parse_match != NULL)
- ctx->h->ops->parse_match(match, ctx->cs);
}
static void nft_parse_log(struct nft_xt_ctx *ctx, struct nftnl_expr *e)
@@ -1599,7 +1575,6 @@ int nft_parse_hl(struct nft_xt_ctx *ctx,
struct nftnl_expr *e,
struct iptables_command_state *cs)
{
- struct xtables_match *match;
struct ip6t_hl_info *info;
uint8_t hl, mode;
int op;
@@ -1642,19 +1617,18 @@ int nft_parse_hl(struct nft_xt_ctx *ctx,
*/
switch (ctx->h->family) {
case NFPROTO_IPV4:
- match = nft_create_match(ctx, ctx->cs, "ttl", false);
+ info = nft_create_match(ctx, ctx->cs, "ttl", false);
break;
case NFPROTO_IPV6:
- match = nft_create_match(ctx, ctx->cs, "hl", false);
+ info = nft_create_match(ctx, ctx->cs, "hl", false);
break;
default:
return -1;
}
- if (!match)
+ if (!info)
return -1;
- info = (void*)match->m->data;
info->hop_limit = hl;
info->mode = mode;