summaryrefslogtreecommitdiffstats
path: root/src/netlink_linearize.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2021-07-13 20:21:01 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2021-07-13 20:33:05 +0200
commit66746e7dedeb0cdc5d63b388ad923ac35b25a2ca (patch)
tree47e15f9be8d4033adf147fd581a6cd3d3405ab9d /src/netlink_linearize.c
parentc68314dd4263575abaed43e052c7e61f6b359040 (diff)
src: support for nat with interval concatenation
This patch allows you to combine concatenation and interval in NAT mappings, e.g. add rule x y dnat to ip saddr . tcp dport map { 192.168.1.2 . 80 : 10.141.10.2-10.141.10.5 . 8888-8999 } This generates the following NAT expression: [ nat dnat ip addr_min reg 1 addr_max reg 10 proto_min reg 9 proto_max reg 11 ] which expects to obtain the following tuple: IP address (min), source port (min), IP address (max), source port (max) to be obtained from the map. This representation simplifies the delinearize path, since the datatype is specified as: ipv4_addr . inet_service. A few more notes on this update: - alloc_nftnl_setelem() needs a variant netlink_gen_data() to deal with the representation of the range on the rhs of the mapping. In contrast to interval concatenation in the key side, where the range is expressed as two netlink attributes, the data side of the set element mapping stores the interval concatenation in a contiguos memory area, see __netlink_gen_concat_expand() for reference. - add range_expr_postprocess() to postprocess the data mapping range. If either one single IP address or port is used, then the minimum and maximum value in the range is the same value, e.g. to avoid listing 80-80, this round simplify the range. This also invokes the range to prefix conversion routine. - add concat_elem_expr() helper function to consolidate code to build the concatenation expression on the rhs element data side. This patch also adds tests/py and tests/shell. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_linearize.c')
-rw-r--r--src/netlink_linearize.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index b1f3feee..9ab3ec3e 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -1165,11 +1165,14 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
amin_reg);
if (stmt->nat.addr->etype == EXPR_MAP &&
stmt->nat.addr->mappings->set->data->flags & EXPR_F_INTERVAL) {
- amax_reg = get_register(ctx, NULL);
- registers++;
amin_reg += netlink_register_space(nat_addrlen(family));
- netlink_put_register(nle, NFTNL_EXPR_NAT_REG_ADDR_MAX,
- amin_reg);
+ if (stmt->nat.type_flags & STMT_NAT_F_CONCAT) {
+ netlink_put_register(nle, nftnl_reg_pmin,
+ amin_reg);
+ } else {
+ netlink_put_register(nle, NFTNL_EXPR_NAT_REG_ADDR_MAX,
+ amin_reg);
+ }
}
}
@@ -1181,6 +1184,12 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
pmin_reg = amin_reg;
+ if (stmt->nat.type_flags & STMT_NAT_F_INTERVAL) {
+ pmin_reg += netlink_register_space(nat_addrlen(family));
+ netlink_put_register(nle, NFTNL_EXPR_NAT_REG_ADDR_MAX,
+ pmin_reg);
+ }
+
/* if STMT_NAT_F_CONCAT is set, the mapped type is a
* concatenation of 'addr . inet_service'.
* The map lookup will then return the
@@ -1189,7 +1198,10 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
* will hold the inet_service part.
*/
pmin_reg += netlink_register_space(nat_addrlen(family));
- netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
+ if (stmt->nat.type_flags & STMT_NAT_F_INTERVAL)
+ netlink_put_register(nle, nftnl_reg_pmax, pmin_reg);
+ else
+ netlink_put_register(nle, nftnl_reg_pmin, pmin_reg);
}
}