From: Alan T. DeKok Date: Fri, 8 Dec 2023 19:01:16 +0000 (-0500) Subject: add operations and upcast on combo-ips and prefixes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a4300f9e0d6ef2869bdc52935134dbb678e2949e;p=thirdparty%2Ffreeradius-server.git add operations and upcast on combo-ips and prefixes --- diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index d5ad61012c7..aa30f9066e9 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -138,6 +138,48 @@ static const fr_type_t upcast_op[FR_TYPE_MAX + 1][FR_TYPE_MAX + 1] = { [FR_TYPE_FLOAT64] = FR_TYPE_IPV6_ADDR, }, + [FR_TYPE_COMBO_IP_ADDR] = { + [FR_TYPE_IPV6_PREFIX] = FR_TYPE_COMBO_IP_PREFIX, + + [FR_TYPE_BOOL] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_UINT8] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT16] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT64] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_SIZE] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_INT8] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT16] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT64] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_FLOAT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_FLOAT64] = FR_TYPE_COMBO_IP_ADDR, + }, + + [FR_TYPE_COMBO_IP_PREFIX] = { + [FR_TYPE_IPV6_PREFIX] = FR_TYPE_COMBO_IP_PREFIX, + + [FR_TYPE_BOOL] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_UINT8] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT16] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_UINT64] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_SIZE] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_INT8] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT16] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_INT64] = FR_TYPE_COMBO_IP_ADDR, + + [FR_TYPE_FLOAT32] = FR_TYPE_COMBO_IP_ADDR, + [FR_TYPE_FLOAT64] = FR_TYPE_COMBO_IP_ADDR, + }, + /* * Bools and to pretty much any numerical type result in * the other integer. @@ -1177,7 +1219,7 @@ static int calc_ipv4_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_ fr_value_box_t one, two; fr_value_box_t *a, *b; - fr_assert(dst->type == FR_TYPE_IPV4_ADDR); + fr_assert((dst->type == FR_TYPE_IPV4_ADDR) || (dst->type == FR_TYPE_COMBO_IP_ADDR)); if (cast_ipv4_addr(&one, in1) < 0) return -1; a = &one; @@ -1226,7 +1268,7 @@ static int calc_ipv4_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_valu int prefix; fr_value_box_t one, two, tmp; - fr_assert(dst->type == FR_TYPE_IPV4_PREFIX); + fr_assert((dst->type == FR_TYPE_IPV4_PREFIX) || (dst->type == FR_TYPE_COMBO_IP_PREFIX)); switch (op) { case T_AND: @@ -1376,7 +1418,7 @@ static int calc_ipv6_addr(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_ int i; uint64_t mask; - fr_assert(dst->type == FR_TYPE_IPV6_ADDR); + fr_assert((dst->type == FR_TYPE_IPV6_ADDR) || (dst->type == FR_TYPE_COMBO_IP_ADDR)); if (cast_ipv6_addr(&one, in1) < 0) return -1; a = &one; @@ -1462,7 +1504,7 @@ static int calc_ipv6_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_valu uint8_t const *pa, *pb; uint8_t *pdst; - fr_assert(dst->type == FR_TYPE_IPV6_PREFIX); + fr_assert((dst->type == FR_TYPE_IPV6_PREFIX) || (dst->type == FR_TYPE_COMBO_IP_PREFIX)); if (a->type == FR_TYPE_OCTETS) { if (a->vb_length != (128 / 8)) { @@ -1514,6 +1556,30 @@ static int calc_ipv6_prefix(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_valu return 0; } +#define is_ipv6(_x) (((_x)->type == FR_TYPE_IPV6_ADDR) || ((_x)->type == FR_TYPE_IPV6_PREFIX) || ((((_x)->type == FR_TYPE_COMBO_IP_ADDR) || ((_x)->type == FR_TYPE_COMBO_IP_PREFIX)) && ((_x)->vb_ip.af == AF_INET6))) + +static int calc_combo_ip_addr(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2) +{ + /* + * IPv6 is better than IPv4! + */ + if (is_ipv6(in1) || is_ipv6(in2)) { + return calc_ipv6_addr(ctx, dst, in1, op, in2); + } + + return calc_ipv4_addr(ctx, dst, in1, op, in2); +} + +static int calc_combo_ip_prefix(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2) +{ + if (is_ipv6(in1) || is_ipv6(in2)) { + return calc_ipv6_prefix(ctx, dst, in1, op, in2); + } + + return calc_ipv4_prefix(ctx, dst, in1, op, in2); +} + + static int calc_float32(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *in1, fr_token_t op, fr_value_box_t const *in2) { fr_value_box_t one, two; @@ -1775,6 +1841,9 @@ static int calc_int64(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const typedef int (*fr_binary_op_t)(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b); +/** Map output type to its associated function + * + */ static const fr_binary_op_t calc_type[FR_TYPE_MAX + 1] = { [FR_TYPE_BOOL] = calc_bool, @@ -1783,9 +1852,13 @@ static const fr_binary_op_t calc_type[FR_TYPE_MAX + 1] = { [FR_TYPE_IPV4_ADDR] = calc_ipv4_addr, [FR_TYPE_IPV4_PREFIX] = calc_ipv4_prefix, + [FR_TYPE_IPV6_ADDR] = calc_ipv6_addr, [FR_TYPE_IPV6_PREFIX] = calc_ipv6_prefix, + [FR_TYPE_COMBO_IP_ADDR] = calc_combo_ip_addr, + [FR_TYPE_COMBO_IP_PREFIX] = calc_combo_ip_prefix, + [FR_TYPE_UINT8] = calc_uint64, [FR_TYPE_UINT16] = calc_uint64, [FR_TYPE_UINT32] = calc_uint64, diff --git a/src/tests/unit/calc.txt b/src/tests/unit/calc.txt index b6b4f580c2c..4306e1dea13 100644 --- a/src/tests/unit/calc.txt +++ b/src/tests/unit/calc.txt @@ -173,6 +173,12 @@ match Cannot compare IPv4 with IPv6 address calc combo-prefix 127/8 + uint8 1 -> ipaddr match 127.0.0.1 +calc combo-prefix 127/8 + uint8 1 -> combo-ip +match 127.0.0.1 + +calc ipv4addr 192.168.2.1 & uint32 0xffff0000 -> combo-prefix +match 192.168.0.0/16 + ###################################################################### # # Float @@ -203,4 +209,4 @@ calc string "2" += string "test" match 2test count -match 92 +match 96