diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-01-02 15:36:20 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2023-01-02 15:36:20 +0100 |
commit | e01c75d54359422b6072e94eadb3af1fe73baf2e (patch) | |
tree | 1926413c8e8738cb53e335d6df6c164a5c5412d5 /src/evaluate.c | |
parent | 77fd4fa2827087dc00615137da78730500823259 (diff) |
src: add eval_proto_ctx()
Add eval_proto_ctx() to access protocol context (struct proto_ctx).
Rename struct proto_ctx field to _pctx to highlight that this field
is internal and the helper function should be used.
This patch comes in preparation for supporting outer and inner
protocol context.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r-- | src/evaluate.c | 188 |
1 files changed, 115 insertions, 73 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 70adb847..40e26467 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -39,6 +39,11 @@ #include <utils.h> #include <xt.h> +struct proto_ctx *eval_proto_ctx(struct eval_ctx *ctx) +{ + return &ctx->_pctx; +} + static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr); static const char * const byteorder_names[] = { @@ -448,11 +453,13 @@ conflict_resolution_gen_dependency(struct eval_ctx *ctx, int protocol, const struct proto_hdr_template *tmpl; const struct proto_desc *desc = NULL; struct expr *dep, *left, *right; + struct proto_ctx *pctx; struct stmt *stmt; assert(expr->payload.base == PROTO_BASE_LL_HDR); - desc = ctx->pctx.protocol[base].desc; + pctx = eval_proto_ctx(ctx); + desc = pctx->protocol[base].desc; tmpl = &desc->templates[desc->protocol_key]; left = payload_expr_alloc(&expr->location, desc, desc->protocol_key); @@ -598,6 +605,7 @@ static int expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **exprp) const struct proto_desc *base, *dependency = NULL; enum proto_bases pb = PROTO_BASE_NETWORK_HDR; struct expr *expr = *exprp; + struct proto_ctx *pctx; struct stmt *nstmt; switch (expr->exthdr.op) { @@ -615,7 +623,8 @@ static int expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **exprp) assert(dependency); - base = ctx->pctx.protocol[pb].desc; + pctx = eval_proto_ctx(ctx); + base = pctx->protocol[pb].desc; if (base == dependency) return __expr_evaluate_exthdr(ctx, exprp); @@ -678,8 +687,11 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx, { enum proto_bases base = payload->payload.base; struct stmt *nstmt = NULL; + struct proto_ctx *pctx; int link, err; + pctx = eval_proto_ctx(ctx); + if (payload->payload.base == PROTO_BASE_LL_HDR) { if (proto_is_dummy(desc)) { err = meta_iiftype_gen_dependency(ctx, payload, &nstmt); @@ -692,8 +704,8 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx, unsigned int i; /* payload desc stored in the L2 header stack? No conflict. */ - for (i = 0; i < ctx->pctx.stacked_ll_count; i++) { - if (ctx->pctx.stacked_ll[i] == payload->payload.desc) + for (i = 0; i < pctx->stacked_ll_count; i++) { + if (pctx->stacked_ll[i] == payload->payload.desc) return 0; } } @@ -701,7 +713,7 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx, assert(base <= PROTO_BASE_MAX); /* This payload and the existing context don't match, conflict. */ - if (ctx->pctx.protocol[base + 1].desc != NULL) + if (pctx->protocol[base + 1].desc != NULL) return 1; link = proto_find_num(desc, payload->payload.desc); @@ -712,8 +724,8 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx, if (base == PROTO_BASE_LL_HDR) { unsigned int i; - for (i = 0; i < ctx->pctx.stacked_ll_count; i++) - payload->payload.offset += ctx->pctx.stacked_ll[i]->length; + for (i = 0; i < pctx->stacked_ll_count; i++) + payload->payload.offset += pctx->stacked_ll[i]->length; } rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt); @@ -731,19 +743,22 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr) struct expr *payload = expr; enum proto_bases base = payload->payload.base; const struct proto_desc *desc; + struct proto_ctx *pctx; struct stmt *nstmt; int err; if (expr->etype == EXPR_PAYLOAD && expr->payload.is_raw) return 0; - desc = ctx->pctx.protocol[base].desc; + pctx = eval_proto_ctx(ctx); + desc = pctx->protocol[base].desc; if (desc == NULL) { if (payload_gen_dependency(ctx, payload, &nstmt) < 0) return -1; rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt); - desc = ctx->pctx.protocol[base].desc; + + desc = pctx->protocol[base].desc; if (desc == expr->payload.desc) goto check_icmp; @@ -759,15 +774,16 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr) desc->name, payload->payload.desc->name); - payload->payload.offset += ctx->pctx.stacked_ll[0]->length; + payload->payload.offset += pctx->stacked_ll[0]->length; rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt); return 1; } + goto check_icmp; } if (payload->payload.base == desc->base && - proto_ctx_is_ambiguous(&ctx->pctx, base)) { - desc = proto_ctx_find_conflict(&ctx->pctx, base, payload->payload.desc); + proto_ctx_is_ambiguous(pctx, base)) { + desc = proto_ctx_find_conflict(pctx, base, payload->payload.desc); assert(desc); return expr_error(ctx->msgs, payload, @@ -785,8 +801,8 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr) if (desc->base == PROTO_BASE_LL_HDR) { unsigned int i; - for (i = 0; i < ctx->pctx.stacked_ll_count; i++) - payload->payload.offset += ctx->pctx.stacked_ll[i]->length; + for (i = 0; i < pctx->stacked_ll_count; i++) + payload->payload.offset += pctx->stacked_ll[i]->length; } check_icmp: if (desc != &proto_icmp && desc != &proto_icmp6) @@ -813,13 +829,13 @@ check_icmp: if (err <= 0) return err; - desc = ctx->pctx.protocol[base].desc; + desc = pctx->protocol[base].desc; if (desc == payload->payload.desc) return 0; } return expr_error(ctx->msgs, payload, "conflicting protocols specified: %s vs. %s", - ctx->pctx.protocol[base].desc->name, + pctx->protocol[base].desc->name, payload->payload.desc->name); } @@ -857,20 +873,22 @@ static int expr_evaluate_rt(struct eval_ctx *ctx, struct expr **expr) { static const char emsg[] = "cannot determine ip protocol version, use \"ip nexthop\" or \"ip6 nexthop\" instead"; struct expr *rt = *expr; + struct proto_ctx *pctx; - rt_expr_update_type(&ctx->pctx, rt); + pctx = eval_proto_ctx(ctx); + rt_expr_update_type(pctx, rt); switch (rt->rt.key) { case NFT_RT_NEXTHOP4: if (rt->dtype != &ipaddr_type) return expr_error(ctx->msgs, rt, "%s", emsg); - if (ctx->pctx.family == NFPROTO_IPV6) + if (pctx->family == NFPROTO_IPV6) return expr_error(ctx->msgs, rt, "%s nexthop will not match", "ip"); break; case NFT_RT_NEXTHOP6: if (rt->dtype != &ip6addr_type) return expr_error(ctx->msgs, rt, "%s", emsg); - if (ctx->pctx.family == NFPROTO_IPV4) + if (pctx->family == NFPROTO_IPV4) return expr_error(ctx->msgs, rt, "%s nexthop will not match", "ip6"); break; default: @@ -885,8 +903,10 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) const struct proto_desc *base, *base_now; struct expr *left, *right, *dep; struct stmt *nstmt = NULL; + struct proto_ctx *pctx; - base_now = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + pctx = eval_proto_ctx(ctx); + base_now = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; switch (ct->ct.nfproto) { case NFPROTO_IPV4: @@ -896,7 +916,7 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) base = &proto_ip6; break; default: - base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + base = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (base == &proto_ip) ct->ct.nfproto = NFPROTO_IPV4; else if (base == &proto_ip) @@ -918,8 +938,8 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) return expr_error(ctx->msgs, ct, "conflicting dependencies: %s vs. %s\n", base->name, - ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc->name); - switch (ctx->pctx.family) { + pctx->protocol[PROTO_BASE_NETWORK_HDR].desc->name); + switch (pctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: return 0; @@ -932,7 +952,7 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) constant_data_ptr(ct->ct.nfproto, left->len)); dep = relational_expr_alloc(&ct->location, OP_EQ, left, right); - relational_expr_pctx_update(&ctx->pctx, dep); + relational_expr_pctx_update(pctx, dep); nstmt = expr_stmt_alloc(&dep->location, dep); rule_stmt_insert_at(ctx->rule, nstmt, ctx->stmt); @@ -948,8 +968,10 @@ static int expr_evaluate_ct(struct eval_ctx *ctx, struct expr **expr) { const struct proto_desc *base, *error; struct expr *ct = *expr; + struct proto_ctx *pctx; - base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + pctx = eval_proto_ctx(ctx); + base = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; switch (ct->ct.key) { case NFT_CT_SRC: @@ -974,13 +996,13 @@ static int expr_evaluate_ct(struct eval_ctx *ctx, struct expr **expr) break; } - ct_expr_update_type(&ctx->pctx, ct); + ct_expr_update_type(pctx, ct); return expr_evaluate_primary(ctx, expr); err_conflict: return stmt_binary_error(ctx, ct, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: %s vs. %s", base->name, error->name); } @@ -2146,6 +2168,7 @@ static bool range_needs_swap(const struct expr *range) static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) { struct expr *rel = *expr, *left, *right; + struct proto_ctx *pctx; struct expr *range; int ret; @@ -2153,6 +2176,8 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) return -1; left = rel->left; + pctx = eval_proto_ctx(ctx); + if (rel->right->etype == EXPR_RANGE && lhs_is_meta_hour(rel->left)) { ret = __expr_evaluate_range(ctx, &rel->right); if (ret) @@ -2220,7 +2245,7 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) * Update protocol context for payload and meta iiftype * equality expressions. */ - relational_expr_pctx_update(&ctx->pctx, rel); + relational_expr_pctx_update(pctx, rel); /* fall through */ case OP_NEQ: @@ -2332,11 +2357,12 @@ static int expr_evaluate_fib(struct eval_ctx *ctx, struct expr **exprp) static int expr_evaluate_meta(struct eval_ctx *ctx, struct expr **exprp) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); struct expr *meta = *exprp; switch (meta->meta.key) { case NFT_META_NFPROTO: - if (ctx->pctx.family != NFPROTO_INET && + if (pctx->family != NFPROTO_INET && meta->flags & EXPR_F_PROTOCOL) return expr_error(ctx->msgs, meta, "meta nfproto is only useful in the inet family"); @@ -2403,9 +2429,10 @@ static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp) static int expr_evaluate_xfrm(struct eval_ctx *ctx, struct expr **exprp) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); struct expr *expr = *exprp; - switch (ctx->pctx.family) { + switch (pctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: case NFPROTO_INET: @@ -2848,9 +2875,10 @@ static int reject_payload_gen_dependency_tcp(struct eval_ctx *ctx, struct stmt *stmt, struct expr **payload) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *desc; - desc = ctx->pctx.protocol[PROTO_BASE_TRANSPORT_HDR].desc; + desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc; if (desc != NULL) return 0; *payload = payload_expr_alloc(&stmt->location, &proto_tcp, @@ -2862,9 +2890,10 @@ static int reject_payload_gen_dependency_family(struct eval_ctx *ctx, struct stmt *stmt, struct expr **payload) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *base; - base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + base = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (base != NULL) return 0; @@ -2931,6 +2960,7 @@ static int stmt_evaluate_reject_inet_family(struct eval_ctx *ctx, struct stmt *stmt, const struct proto_desc *desc) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *base; int protocol; @@ -2940,7 +2970,7 @@ static int stmt_evaluate_reject_inet_family(struct eval_ctx *ctx, case NFT_REJECT_ICMPX_UNREACH: break; case NFT_REJECT_ICMP_UNREACH: - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + base = pctx->protocol[PROTO_BASE_LL_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case NFPROTO_IPV4: @@ -2948,14 +2978,14 @@ static int stmt_evaluate_reject_inet_family(struct eval_ctx *ctx, if (stmt->reject.family == NFPROTO_IPV4) break; return stmt_binary_error(ctx, stmt->reject.expr, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: ip vs ip6"); case NFPROTO_IPV6: case __constant_htons(ETH_P_IPV6): if (stmt->reject.family == NFPROTO_IPV6) break; return stmt_binary_error(ctx, stmt->reject.expr, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: ip vs ip6"); default: return stmt_error(ctx, stmt, @@ -2970,9 +3000,10 @@ static int stmt_evaluate_reject_inet_family(struct eval_ctx *ctx, static int stmt_evaluate_reject_inet(struct eval_ctx *ctx, struct stmt *stmt, struct expr *expr) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *desc; - desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (desc != NULL && stmt_evaluate_reject_inet_family(ctx, stmt, desc) < 0) return -1; @@ -2987,13 +3018,14 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx, struct stmt *stmt, const struct proto_desc *desc) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *base; int protocol; switch (stmt->reject.type) { case NFT_REJECT_ICMPX_UNREACH: case NFT_REJECT_TCP_RST: - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + base = pctx->protocol[PROTO_BASE_LL_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case __constant_htons(ETH_P_IP): @@ -3001,29 +3033,29 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx, break; default: return stmt_binary_error(ctx, stmt, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "cannot reject this network family"); } break; case NFT_REJECT_ICMP_UNREACH: - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + base = pctx->protocol[PROTO_BASE_LL_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case __constant_htons(ETH_P_IP): if (NFPROTO_IPV4 == stmt->reject.family) break; return stmt_binary_error(ctx, stmt->reject.expr, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: ip vs ip6"); case __constant_htons(ETH_P_IPV6): if (NFPROTO_IPV6 == stmt->reject.family) break; return stmt_binary_error(ctx, stmt->reject.expr, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: ip vs ip6"); default: return stmt_binary_error(ctx, stmt, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "cannot reject this network family"); } break; @@ -3035,14 +3067,15 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx, static int stmt_evaluate_reject_bridge(struct eval_ctx *ctx, struct stmt *stmt, struct expr *expr) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *desc; - desc = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + desc = pctx->protocol[PROTO_BASE_LL_HDR].desc; if (desc != &proto_eth && desc != &proto_vlan && desc != &proto_netdev) return __stmt_binary_error(ctx, &stmt->location, NULL, "cannot reject from this link layer protocol"); - desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (desc != NULL && stmt_evaluate_reject_bridge_family(ctx, stmt, desc) < 0) return -1; @@ -3056,7 +3089,9 @@ static int stmt_evaluate_reject_bridge(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_reject_family(struct eval_ctx *ctx, struct stmt *stmt, struct expr *expr) { - switch (ctx->pctx.family) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); + + switch (pctx->family) { case NFPROTO_ARP: return stmt_error(ctx, stmt, "cannot use reject with arp"); case NFPROTO_IPV4: @@ -3070,7 +3105,7 @@ static int stmt_evaluate_reject_family(struct eval_ctx *ctx, struct stmt *stmt, return stmt_binary_error(ctx, stmt->reject.expr, stmt, "abstracted ICMP unreachable not supported"); case NFT_REJECT_ICMP_UNREACH: - if (stmt->reject.family == ctx->pctx.family) + if (stmt->reject.family == pctx->family) break; return stmt_binary_error(ctx, stmt->reject.expr, stmt, "conflicting protocols specified: ip vs ip6"); @@ -3094,28 +3129,29 @@ static int stmt_evaluate_reject_family(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_reject_default(struct eval_ctx *ctx, struct stmt *stmt) { - int protocol; + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *desc, *base; + int protocol; - switch (ctx->pctx.family) { + switch (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.family = pctx->family; + if (pctx->family == NFPROTO_IPV4) stmt->reject.icmp_code = ICMP_PORT_UNREACH; else stmt->reject.icmp_code = ICMP6_DST_UNREACH_NOPORT; break; case NFPROTO_INET: - desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (desc == NULL) { stmt->reject.type = NFT_REJECT_ICMPX_UNREACH; stmt->reject.icmp_code = NFT_REJECT_ICMPX_PORT_UNREACH; break; } stmt->reject.type = NFT_REJECT_ICMP_UNREACH; - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + base = pctx->protocol[PROTO_BASE_LL_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case NFPROTO_IPV4: @@ -3132,14 +3168,14 @@ static int stmt_evaluate_reject_default(struct eval_ctx *ctx, break; case NFPROTO_BRIDGE: case NFPROTO_NETDEV: - desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + desc = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (desc == NULL) { stmt->reject.type = NFT_REJECT_ICMPX_UNREACH; stmt->reject.icmp_code = NFT_REJECT_ICMPX_PORT_UNREACH; break; } stmt->reject.type = NFT_REJECT_ICMP_UNREACH; - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + base = pctx->protocol[PROTO_BASE_LL_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case __constant_htons(ETH_P_IP): @@ -3175,9 +3211,9 @@ static int stmt_evaluate_reject_icmp(struct eval_ctx *ctx, struct stmt *stmt) static int stmt_evaluate_reset(struct eval_ctx *ctx, struct stmt *stmt) { - int protonum; + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *desc, *base; - struct proto_ctx *pctx = &ctx->pctx; + int protonum; desc = pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc; if (desc == NULL) @@ -3194,7 +3230,7 @@ static int stmt_evaluate_reset(struct eval_ctx *ctx, struct stmt *stmt) default: if (stmt->reject.type == NFT_REJECT_TCP_RST) { return stmt_binary_error(ctx, stmt, - &ctx->pctx.protocol[PROTO_BASE_TRANSPORT_HDR], + &pctx->protocol[PROTO_BASE_TRANSPORT_HDR], "you cannot use tcp reset with this protocol"); } break; @@ -3222,13 +3258,14 @@ static int stmt_evaluate_reject(struct eval_ctx *ctx, struct stmt *stmt) static int nat_evaluate_family(struct eval_ctx *ctx, struct stmt *stmt) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *nproto; - switch (ctx->pctx.family) { + switch (pctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: if (stmt->nat.family == NFPROTO_UNSPEC) - stmt->nat.family = ctx->pctx.family; + stmt->nat.family = pctx->family; return 0; case NFPROTO_INET: if (!stmt->nat.addr) { @@ -3238,7 +3275,7 @@ static int nat_evaluate_family(struct eval_ctx *ctx, struct stmt *stmt) if (stmt->nat.family != NFPROTO_UNSPEC) return 0; - nproto = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + nproto = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if (nproto == &proto_ip) stmt->nat.family = NFPROTO_IPV4; @@ -3267,7 +3304,7 @@ static const struct datatype *get_addr_dtype(uint8_t family) static int evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, struct expr **expr) { - struct proto_ctx *pctx = &ctx->pctx; + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct datatype *dtype; dtype = get_addr_dtype(pctx->family); @@ -3320,7 +3357,7 @@ static bool nat_evaluate_addr_has_th_expr(const struct expr *map) static int nat_evaluate_transport(struct eval_ctx *ctx, struct stmt *stmt, struct expr **expr) { - struct proto_ctx *pctx = &ctx->pctx; + struct proto_ctx *pctx = eval_proto_ctx(ctx); if (pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc == NULL && !nat_evaluate_addr_has_th_expr(stmt->nat.addr)) @@ -3336,16 +3373,17 @@ static int nat_evaluate_transport(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_l3proto(struct eval_ctx *ctx, struct stmt *stmt, uint8_t family) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct proto_desc *nproto; - nproto = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + nproto = pctx->protocol[PROTO_BASE_NETWORK_HDR].desc; if ((nproto == &proto_ip && family != NFPROTO_IPV4) || (nproto == &proto_ip6 && family != NFPROTO_IPV6)) return stmt_binary_error(ctx, stmt, - &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], + &pctx->protocol[PROTO_BASE_NETWORK_HDR], "conflicting protocols specified: %s vs. %s. You must specify ip or ip6 family in %s statement", - ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc->name, + pctx->protocol[PROTO_BASE_NETWORK_HDR].desc->name, family2str(family), stmt->ops->name); return 0; @@ -3355,10 +3393,11 @@ static int stmt_evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, uint8_t family, struct expr **addr) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct datatype *dtype; int err; - if (ctx->pctx.family == NFPROTO_INET) { + if (pctx->family == NFPROTO_INET) { dtype = get_addr_dtype(family); if (dtype->size == 0) return stmt_error(ctx, stmt, @@ -3375,7 +3414,7 @@ static int stmt_evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt) { - struct proto_ctx *pctx = &ctx->pctx; + struct proto_ctx *pctx = eval_proto_ctx(ctx); struct expr *one, *two, *data, *tmp; const struct datatype *dtype; int addr_type, err; @@ -3524,13 +3563,14 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt) static int stmt_evaluate_tproxy(struct eval_ctx *ctx, struct stmt *stmt) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); int err; - switch (ctx->pctx.family) { + switch (pctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: /* fallthrough */ if (stmt->tproxy.family == NFPROTO_UNSPEC) - stmt->tproxy.family = ctx->pctx.family; + stmt->tproxy.family = pctx->family; break; case NFPROTO_INET: break; @@ -3539,7 +3579,7 @@ static int stmt_evaluate_tproxy(struct eval_ctx *ctx, struct stmt *stmt) "tproxy is only supported for IPv4/IPv6/INET"); } - if (ctx->pctx.protocol[PROTO_BASE_TRANSPORT_HDR].desc == NULL) + if (pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc == NULL) return stmt_error(ctx, stmt, "Transparent proxy support requires" " transport protocol match"); @@ -3649,9 +3689,10 @@ static int stmt_evaluate_optstrip(struct eval_ctx *ctx, struct stmt *stmt) static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); int err; - switch (ctx->pctx.family) { + switch (pctx->family) { case NFPROTO_IPV4: case NFPROTO_IPV6: if (stmt->dup.to == NULL) @@ -3691,10 +3732,11 @@ static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt) static int stmt_evaluate_fwd(struct eval_ctx *ctx, struct stmt *stmt) { + struct proto_ctx *pctx = eval_proto_ctx(ctx); const struct datatype *dtype; int err, len; - switch (ctx->pctx.family) { + switch (pctx->family) { case NFPROTO_NETDEV: if (stmt->fwd.dev == NULL) return stmt_error(ctx, stmt, @@ -4523,7 +4565,7 @@ static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule, struct stmt *stmt, *tstmt = NULL; struct error_record *erec; - proto_ctx_init(&ctx->pctx, rule->handle.family, ctx->nft->debug_mask); + proto_ctx_init(&ctx->_pctx, rule->handle.family, ctx->nft->debug_mask); memset(&ctx->ectx, 0, sizeof(ctx->ectx)); ctx->rule = rule; |