From 4117d85abff84d8a1c9358d7d98da7be06eaf642 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Mon, 5 Apr 2021 12:15:01 +0100 Subject: [PATCH] Treat combo IP address attributes as normal types --- src/bin/dhcpclient.c | 3 +- src/bin/radclient.c | 6 +- src/bin/radmin.c | 3 +- src/bin/radsniff.c | 3 +- src/bin/unit_test_attribute.c | 7 +- src/lib/server/command.c | 10 +- src/lib/server/cond_tokenize.c | 2 +- src/lib/server/map_async.c | 2 +- src/lib/server/tmpl.h | 2 - src/lib/server/tmpl_eval.c | 4 +- src/lib/server/tmpl_tokenize.c | 59 +-------- src/lib/sim/base.c | 8 +- src/lib/unlang/compile.c | 16 --- src/lib/unlang/tmpl.c | 2 +- src/lib/unlang/xlat_builtin.c | 11 +- src/lib/unlang/xlat_eval.c | 2 +- src/lib/util/dict.h | 3 - src/lib/util/dict_fixup.c | 4 +- src/lib/util/dict_priv.h | 5 +- src/lib/util/dict_tokenize.c | 20 ++-- src/lib/util/dict_unknown.c | 14 +-- src/lib/util/dict_util.c | 144 +--------------------- src/lib/util/dict_validate.c | 30 ++--- src/lib/util/pair.c | 50 +------- src/lib/util/struct.c | 2 +- src/lib/util/types.c | 12 +- src/lib/util/types.h | 67 ++++++----- src/lib/util/value.c | 153 ++++++++++++++++-------- src/lib/util/value.h | 4 +- src/modules/rlm_csv/rlm_csv.c | 8 +- src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c | 11 +- src/modules/rlm_lua/lua.c | 4 +- src/modules/rlm_mruby/rlm_mruby.c | 2 +- src/modules/rlm_python/rlm_python.c | 4 +- src/protocols/internal/encode.c | 4 +- src/protocols/radius/base.c | 8 +- src/protocols/radius/decode.c | 34 +----- src/protocols/radius/encode.c | 8 +- 38 files changed, 237 insertions(+), 494 deletions(-) diff --git a/src/bin/dhcpclient.c b/src/bin/dhcpclient.c index 5c64c2e474..ded7f6bc0a 100644 --- a/src/bin/dhcpclient.c +++ b/src/bin/dhcpclient.c @@ -184,8 +184,7 @@ static int request_init(fr_radius_packet_t **out, fr_pair_list_t *packet_vps, ch * Xlat expansions are not supported. Convert xlat to value box (if possible). */ if (vp->type == VT_XLAT) { - fr_type_t type = vp->da->type; - if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) { + if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) { fr_perror("dhcpclient"); fr_radius_packet_free(&packet); if (fp && (fp != stdin)) fclose(fp); diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 428aeffcb6..c8d250a0ab 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -452,8 +452,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files) * Xlat expansions are not supported. Convert xlat to value box (if possible). */ if (vp->type == VT_XLAT) { - fr_type_t type = vp->da->type; - if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) { + if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) { fr_perror("radclient"); goto error; } @@ -487,8 +486,7 @@ static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files) * Xlat expansions are not supported. Convert xlat to value box (if possible). */ if (vp->type == VT_XLAT) { - fr_type_t type = vp->da->type; - if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) { + if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) { fr_perror("radclient"); goto error; } diff --git a/src/bin/radmin.c b/src/bin/radmin.c index 9ee54fc8a3..305059d809 100644 --- a/src/bin/radmin.c +++ b/src/bin/radmin.c @@ -519,10 +519,9 @@ static int cmd_show_debug_level(FILE *fp, UNUSED FILE *fp_err, UNUSED void *ctx, static int cmd_set_profile_status(UNUSED FILE *fp, FILE *fp_err, UNUSED void *ctx, fr_cmd_info_t const *info) { fr_value_box_t box; - fr_type_t type = FR_TYPE_BOOL; struct ProfilerState state; - if (fr_value_box_from_str(NULL, &box, &type, NULL, info->argv[0], strlen(info->argv[0]), '\0', false) < 0) { + if (fr_value_box_from_str(NULL, &box, FR_TYPE_BOOL, NULL, info->argv[0], strlen(info->argv[0]), '\0', false) < 0) { fprintf(fp_err, "Failed setting profile status '%s' - %s\n", info->argv[0], fr_strerror()); return -1; } diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index 923ba0002b..641f2fe9ac 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -2048,8 +2048,7 @@ static int rs_build_filter(fr_pair_list_t *out, char const *filter) * Xlat expansions are not supported. Convert xlat to value box (if possible). */ if (vp->type == VT_XLAT) { - fr_type_t type = vp->da->type; - if (fr_value_box_from_str(vp, &vp->data, &type, NULL, vp->xlat, -1, '\0', false) < 0) { + if (fr_value_box_from_str(vp, &vp->data, vp->da->type, NULL, vp->xlat, -1, '\0', false) < 0) { fr_perror("radsniff"); return -1; } diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 875c677617..0333bde11f 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -1509,12 +1509,11 @@ static size_t command_encode_dns_label(command_result_t *result, command_file_ct enc_p = cc->buffer_start; while (p) { - fr_type_t type = FR_TYPE_STRING; fr_value_box_t *box = talloc_zero(NULL, fr_value_box_t); fr_skip_whitespace(p); - if (fr_value_box_from_str(box, box, &type, NULL, p, -1, '"', false) < 0) { + if (fr_value_box_from_str(box, box, FR_TYPE_STRING, NULL, p, -1, '"', false) < 0) { talloc_free(box); RETURN_OK_WITH_ERROR(); } @@ -2212,7 +2211,7 @@ static size_t command_value_box_normalise(command_result_t *result, UNUSED comma p = in + match_len; fr_skip_whitespace(p); - if (fr_value_box_from_str(box, box, &type, NULL, p, -1, '"', false) < 0) { + if (fr_value_box_from_str(box, box, type, NULL, p, -1, '"', false) < 0) { error: talloc_free(box); RETURN_OK_WITH_ERROR(); @@ -2235,7 +2234,7 @@ static size_t command_value_box_normalise(command_result_t *result, UNUSED comma * box as last time. */ box2 = talloc_zero(NULL, fr_value_box_t); - if (fr_value_box_from_str(box2, box2, &type, NULL, data, slen, '"', false) < 0) { + if (fr_value_box_from_str(box2, box2, type, NULL, data, slen, '"', false) < 0) { talloc_free(box2); talloc_free(box); RETURN_OK_WITH_ERROR(); diff --git a/src/lib/server/command.c b/src/lib/server/command.c index 26ea204514..6d7bf0ffa6 100644 --- a/src/lib/server/command.c +++ b/src/lib/server/command.c @@ -1834,7 +1834,7 @@ redo: /* * Parse the data to be sure it's well formed. */ - if (fr_value_box_from_str(ctx, box, &type, + if (fr_value_box_from_str(ctx, box, type, NULL, name, -1, quote, true) < 0) { fr_strerror_printf_push("Failed parsing argument '%s'", name); return -1; @@ -1968,8 +1968,8 @@ static int syntax_str_to_argv(int start_argc, fr_cmd_argv_t *start, fr_cmd_info_ } ret = fr_value_box_from_str(info->box[argc], info->box[argc], - &type, NULL, - word + offset, len - (offset << 1), quote, false); + type, NULL, + word + offset, len - (offset << 1), quote, false); if (ret < 0) return -1; /* @@ -2586,8 +2586,8 @@ static int expand_syntax(fr_cmd_t *cmd, fr_cmd_info_t *info, fr_cmd_argv_t *argv } ret = fr_value_box_from_str(info->box[info->argc], info->box[info->argc], - &type, NULL, - word + offset, len - (offset << 1), quote, false); + type, NULL, + word + offset, len - (offset << 1), quote, false); if (ret < 0) return -1; info->argc++; *word_p = word = p; diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 2399cb481e..2f5cd0de51 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -928,7 +928,7 @@ static int cond_forbid_groups(tmpl_t *vpt, fr_sbuff_t *in, fr_sbuff_marker_t *m_ if (!tmpl_is_attr(vpt)) return 0; switch (tmpl_da(vpt)->type) { - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: break; default: diff --git a/src/lib/server/map_async.c b/src/lib/server/map_async.c index 1d8b11c220..849f4ffc9a 100644 --- a/src/lib/server/map_async.c +++ b/src/lib/server/map_async.c @@ -452,7 +452,7 @@ int map_to_list_mod(TALLOC_CTX *ctx, vp_list_mod_t **out, fr_dcursor_init(&values, &head); if (fr_value_box_from_str(fr_dlist_head(&n->mod), - tmpl_value(fr_map_list_head(&n->mod)->rhs), &type, + tmpl_value(fr_map_list_head(&n->mod)->rhs), type, tmpl_da(mutated->lhs), mutated->rhs->name, mutated->rhs->len, mutated->rhs->quote, false)) { RPEDEBUG("Assigning value to \"%s\" failed", tmpl_da(mutated->lhs)->name); diff --git a/src/lib/server/tmpl.h b/src/lib/server/tmpl.h index 4f53e926a3..597d45464b 100644 --- a/src/lib/server/tmpl.h +++ b/src/lib/server/tmpl.h @@ -942,8 +942,6 @@ int tmpl_attr_to_xlat(TALLOC_CTX *ctx, tmpl_t **vpt_p); void tmpl_attr_to_raw(tmpl_t *vpt); -int tmpl_attr_abstract_to_concrete(tmpl_t *vpt, fr_type_t type); - int tmpl_attr_unknown_add(tmpl_t *vpt); int tmpl_attr_unresolved_add(fr_dict_t *dict, tmpl_t *vpt, diff --git a/src/lib/server/tmpl_eval.c b/src/lib/server/tmpl_eval.c index dba8802623..92166fbf98 100644 --- a/src/lib/server/tmpl_eval.c +++ b/src/lib/server/tmpl_eval.c @@ -618,7 +618,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out, * * @fixme We need a way of signalling xlat not to escape things. */ - ret = fr_value_box_from_str(tmp_ctx, &tmp, &src_type, NULL, + ret = fr_value_box_from_str(tmp_ctx, &tmp, src_type, NULL, value.vb_strvalue, value.vb_length, '"', false); if (ret < 0) goto error; @@ -648,7 +648,7 @@ ssize_t _tmpl_to_atype(TALLOC_CTX *ctx, void *out, * * @fixme We need a way of signalling xlat not to escape things. */ - ret = fr_value_box_from_str(tmp_ctx, &tmp, &src_type, NULL, + ret = fr_value_box_from_str(tmp_ctx, &tmp, src_type, NULL, value.vb_strvalue, value.vb_length, '"', false); if (ret < 0) goto error; diff --git a/src/lib/server/tmpl_tokenize.c b/src/lib/server/tmpl_tokenize.c index fd4d0f21f3..b5906dc650 100644 --- a/src/lib/server/tmpl_tokenize.c +++ b/src/lib/server/tmpl_tokenize.c @@ -2257,7 +2257,7 @@ static ssize_t tmpl_afrom_ipv4_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t } MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in))); - if (fr_value_box_from_str(vpt, &vpt->data.literal, &type, NULL, + if (fr_value_box_from_str(vpt, &vpt->data.literal, type, NULL, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), '\0', false) < 0) { talloc_free(vpt); goto error; @@ -2373,7 +2373,7 @@ static ssize_t tmpl_afrom_ipv6_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t } MEM(vpt = tmpl_alloc(ctx, TMPL_TYPE_DATA, T_BARE_WORD, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in))); - if (fr_value_box_from_str(vpt, &vpt->data.literal, &type, NULL, + if (fr_value_box_from_str(vpt, &vpt->data.literal, type, NULL, fr_sbuff_start(&our_in), fr_sbuff_used(&our_in), '\0', false) < 0) { talloc_free(vpt); goto error; @@ -2785,7 +2785,7 @@ ssize_t tmpl_cast_from_substr(fr_type_t *out, fr_sbuff_t *in) fr_strerror_const("Unknown data type"); FR_SBUFF_ERROR_RETURN(&our_in); } - if (fr_dict_non_data_types[cast]) { + if (fr_type_is_non_leaf(cast)) { fr_strerror_const("Forbidden data type in cast"); FR_SBUFF_MARKER_ERROR_RETURN(&m); } @@ -2828,7 +2828,7 @@ int tmpl_cast_set(tmpl_t *vpt, fr_type_t dst_type) * Only "base" data types are allowed. Structural types * and horrid WiMAX crap is forbidden. */ - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: break; } @@ -2963,7 +2963,7 @@ int tmpl_cast_in_place(tmpl_t *vpt, fr_type_t type, fr_dict_attr_t const *enumv) * Why do we pass a pointer to a temporary type * variable? Goddamn WiMAX. */ - if (fr_value_box_from_str(vpt, &vpt->data.literal, &type, + if (fr_value_box_from_str(vpt, &vpt->data.literal, type, enumv, unescaped, talloc_array_length(unescaped) - 1, '\0', false) < 0) return -1; talloc_free(unescaped); @@ -3377,41 +3377,6 @@ void tmpl_attr_to_raw(tmpl_t *vpt) attr_to_raw(vpt, fr_dlist_tail(&vpt->data.attribute.ar)); } -/** Convert an abstract da into a concrete one - * - * Usually used to fixup combo ip addresses - */ -int tmpl_attr_abstract_to_concrete(tmpl_t *vpt, fr_type_t type) -{ - fr_dict_attr_t const *abstract; - fr_dict_attr_t const *concrete; - tmpl_attr_t *ref; - - tmpl_assert_type(tmpl_is_attr(vpt)); - - abstract = tmpl_da(vpt); - if (abstract->type != FR_TYPE_COMBO_IP_ADDR) { - fr_strerror_printf("Abstract attribute \"%s\" is of incorrect type '%s'", abstract->name, - fr_table_str_by_value(fr_value_box_type_table, abstract->type, "")); - return -1; - } - - concrete = fr_dict_attr_by_type(abstract, type); - if (!concrete) { - fr_strerror_printf("Can't convert abstract type '%s' to concrete type '%s'", - fr_table_str_by_value(fr_value_box_type_table, abstract->type, ""), - fr_table_str_by_value(fr_value_box_type_table, type, "")); - return -1; - } - - ref = fr_dlist_tail(&vpt->data.attribute.ar); - ref->da = concrete; - - TMPL_ATTR_VERIFY(vpt); - - return 0; -} - /** Add an unknown #fr_dict_attr_t specified by a #tmpl_t to the main dictionary * * @param vpt to add. ``tmpl_da`` pointer will be updated to point to the @@ -4210,18 +4175,6 @@ void tmpl_verify(char const *file, int line, tmpl_t const *vpt) } da = tmpl_da(vpt); - - if ((da->type == FR_TYPE_COMBO_IP_ADDR) && (da->type != tmpl_da(vpt)->type)) { - da = fr_dict_attr_by_type(tmpl_da(vpt), tmpl_da(vpt)->type); - if (!da) { - fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR " - "attribute \"%s\" variant (%s) not found in dictionary (%s)", - file, line, tmpl_da(vpt)->name, - fr_table_str_by_value(fr_value_box_type_table, tmpl_da(vpt)->type, ""), - fr_dict_root(dict)->name); - } - } - if (!tmpl_da(vpt)->flags.is_unknown && !tmpl_da(vpt)->flags.is_raw && (da != tmpl_da(vpt))) { fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR " "dictionary pointer %p \"%s\" (%s) " @@ -4394,7 +4347,7 @@ ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t i * We can only cast to basic data types. Complex ones * are forbidden. */ - if (fr_dict_non_data_types[cast]) { + if (fr_type_is_non_leaf(cast)) { return_P("Forbidden data type in cast"); } diff --git a/src/lib/sim/base.c b/src/lib/sim/base.c index 3a2c757655..5f84a88ff9 100644 --- a/src/lib/sim/base.c +++ b/src/lib/sim/base.c @@ -165,15 +165,15 @@ size_t const fr_sim_attr_sizes[FR_TYPE_MAX + 1][2] = { size_t fr_sim_attr_len(fr_pair_t const *vp) { switch (vp->vp_type) { + case FR_TYPE_STRUCTURAL: + fr_assert_fail(NULL); + return 0; + case FR_TYPE_VARIABLE_SIZE: return vp->vp_length; default: return fr_sim_attr_sizes[vp->vp_type][0]; - - case FR_TYPE_STRUCTURAL: - fr_assert_fail(NULL); - return 0; } } diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index cea14344f0..52d8b36267 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -972,14 +972,6 @@ int unlang_fixup_update(map_t *map, UNUSED void *ctx) fr_table_str_by_value(fr_value_box_type_table, tmpl_da(map->lhs)->type, "")); return -1; } - - /* - * Fixup LHS da if it doesn't match the type - * of the RHS. - */ - if (tmpl_da(map->lhs)->type != tmpl_value_type(map->rhs)) { - if (tmpl_attr_abstract_to_concrete(map->lhs, tmpl_value_type(map->rhs)) < 0) return -1; - } } /* else we can't precompile the data */ return 0; @@ -1090,14 +1082,6 @@ static int unlang_fixup_filter(map_t *map, UNUSED void *ctx) fr_table_str_by_value(fr_value_box_type_table, tmpl_da(map->lhs)->type, "")); return -1; } - - /* - * Fixup LHS da if it doesn't match the type - * of the RHS. - */ - if (tmpl_da(map->lhs)->type != tmpl_value_type(map->rhs)) { - if (tmpl_attr_abstract_to_concrete(map->lhs, tmpl_value_type(map->rhs)) < 0) return -1; - } } /* else we can't precompile the data */ return 0; diff --git a/src/lib/unlang/tmpl.c b/src/lib/unlang/tmpl.c index 6358ce1e2d..cd2d6bdb6c 100644 --- a/src/lib/unlang/tmpl.c +++ b/src/lib/unlang/tmpl.c @@ -393,7 +393,7 @@ static unlang_action_t unlang_tmpl_exec_wait_final(rlm_rcode_t *p_result, reques fr_value_box_list_init(&state->box); MEM(box = fr_value_box_alloc(state->ctx, FR_TYPE_STRING, NULL, true)); - if (fr_value_box_from_str(state->ctx, box, &type, NULL, + if (fr_value_box_from_str(state->ctx, box, type, NULL, fr_sbuff_buff(&state->exec.stdout_buff), fr_sbuff_used(&state->exec.stdout_buff), 0, true) < 0) { talloc_free(box); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 95437b6362..05de5e65c3 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -331,7 +331,7 @@ static inline int xlat_arg_parser_validate(xlat_arg_parser_t const *arg, bool la } switch (arg->type) { - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: case FR_TYPE_VOID: break; @@ -911,13 +911,8 @@ static xlat_action_t xlat_func_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcur if (vendor) RIDEBUG2("vendor : %i (%s)", vendor->pen, vendor->name); RIDEBUG3("type : %s", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "")); - switch (vp->vp_type) { - case FR_TYPE_VARIABLE_SIZE: + if (fr_box_is_variable_size(&vp->data)) { RIDEBUG3("length : %zu", vp->vp_length); - break; - - default: - break; } if (!RDEBUG_ENABLED4) continue; @@ -932,7 +927,7 @@ static xlat_action_t xlat_func_debug_attr(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcur if ((fr_type_t) type->value == vp->vp_type) goto next_type; switch (type->value) { - case FR_TYPE_NON_VALUES: /* Skip everything that's not a value */ + case FR_TYPE_NON_LEAF: /* Skip everything that's not a value */ goto next_type; default: diff --git a/src/lib/unlang/xlat_eval.c b/src/lib/unlang/xlat_eval.c index 7aa23cdc0d..f6b96fae18 100644 --- a/src/lib/unlang/xlat_eval.c +++ b/src/lib/unlang/xlat_eval.c @@ -1587,7 +1587,7 @@ static char *xlat_sync_eval(TALLOC_CTX *ctx, request_t *request, xlat_exp_t cons fr_value_box_t data; type = FR_TYPE_STRING; - if (fr_value_box_from_str(ctx, &data, &type, NULL, child, + if (fr_value_box_from_str(ctx, &data, type, NULL, child, talloc_array_length(child) - 1, '"', false) < 0) { talloc_free(child); return NULL; diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index f49c3bf668..b57c294c8b 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -314,7 +314,6 @@ typedef struct fr_dict_gctx_s fr_dict_gctx_t; * */ extern bool const fr_dict_attr_allowed_chars[UINT8_MAX + 1]; -extern bool const fr_dict_non_data_types[FR_TYPE_MAX + 1]; /** @name Dictionary structure extensions * @@ -537,8 +536,6 @@ fr_dict_attr_t const *fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr char const *attr) CC_HINT(nonnull(2,3)); -fr_dict_attr_t const *fr_dict_attr_by_type(fr_dict_attr_t const *da, fr_type_t type); - fr_dict_attr_t const *fr_dict_attr_child_by_da(fr_dict_attr_t const *parent, fr_dict_attr_t const *child) CC_HINT(nonnull); fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr); diff --git a/src/lib/util/dict_fixup.c b/src/lib/util/dict_fixup.c index 82bb5c6283..33514cc8c6 100644 --- a/src/lib/util/dict_fixup.c +++ b/src/lib/util/dict_fixup.c @@ -173,7 +173,7 @@ static inline CC_HINT(always_inline) int dict_fixup_enumv_apply(UNUSED dict_fixu da = fr_dict_attr_unconst(da_const); type = da->type; - if (fr_value_box_from_str(fixup, &value, &type, NULL, + if (fr_value_box_from_str(fixup, &value, type, NULL, fixup->value, talloc_array_length(fixup->value) - 1, '\0', false) < 0) { fr_strerror_printf_push("Invalid VALUE for Attribute '%s' at %s[%d]", da->name, @@ -460,7 +460,7 @@ static inline CC_HINT(always_inline) int dict_fixup_clone_apply(UNUSED dict_fixu return -1; } - if (dict_attr_add_to_namespace(dict, fixup->parent, cloned) < 0) return -1; + if (dict_attr_add_to_namespace(fixup->parent, cloned) < 0) return -1; return 0; } diff --git a/src/lib/util/dict_priv.h b/src/lib/util/dict_priv.h index 1e132e022f..ee7fe10074 100644 --- a/src/lib/util/dict_priv.h +++ b/src/lib/util/dict_priv.h @@ -75,8 +75,6 @@ struct fr_dict { fr_hash_table_t *vendors_by_name; //!< Lookup vendor by name. fr_hash_table_t *vendors_by_num; //!< Lookup vendor by PEN. - fr_hash_table_t *attributes_combo; //!< Lookup variants of polymorphic attributes. - fr_dict_attr_t *root; //!< Root attribute of this dictionary. TALLOC_CTX *pool; //!< Talloc memory pool to reduce allocs. @@ -154,8 +152,7 @@ int dict_protocol_add(fr_dict_t *dict); int dict_vendor_add(fr_dict_t *dict, char const *name, unsigned int num); -int dict_attr_add_to_namespace(fr_dict_t *dict, - fr_dict_attr_t const *parent, fr_dict_attr_t *da) CC_HINT(nonnull); +int dict_attr_add_to_namespace(fr_dict_attr_t const *parent, fr_dict_attr_t *da) CC_HINT(nonnull); bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, UNUSED char const *name, int *attr, fr_type_t type, diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 2e5a7d3df6..d7f4914deb 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -1132,13 +1132,9 @@ static int dict_read_process_value(dict_tokenize_ctx_t *ctx, char **argv, int ar break; } - { - fr_type_t type = da->type; /* Might change - Stupid combo IP */ - - if (fr_value_box_from_str(NULL, &value, &type, NULL, argv[2], -1, '\0', false) < 0) { - fr_strerror_printf_push("Invalid VALUE for Attribute '%s'", da->name); - return -1; - } + if (fr_value_box_from_str(NULL, &value, da->type, NULL, argv[2], -1, '\0', false) < 0) { + fr_strerror_printf_push("Invalid VALUE for Attribute '%s'", da->name); + return -1; } if (fr_dict_enum_add_name(da, argv[1], &value, false, true) < 0) { @@ -1190,7 +1186,6 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *ctx, char **argv, int a fr_dict_attr_t const *da; fr_dict_attr_t const *parent = NULL; fr_value_box_t value; - fr_type_t type; unsigned int attr; fr_dict_attr_flags_t flags; char *key_attr = argv[1]; @@ -1243,8 +1238,7 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *ctx, char **argv, int a /* * Parse the value. */ - type = parent->type; /* because of combo-IP nonsense */ - if (fr_value_box_from_str(NULL, &value, &type, NULL, argv[2], -1, '\0', false) < 0) { + if (fr_value_box_from_str(NULL, &value, parent->type, NULL, argv[2], -1, '\0', false) < 0) { fr_strerror_printf_push("Invalid value for STRUCT \"%s\"", argv[2]); return -1; } @@ -1252,7 +1246,7 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *ctx, char **argv, int a /* * @todo - auto-number from a parent UNION, instead of overloading the value. */ - switch (type) { + switch (parent->type) { case FR_TYPE_UINT8: attr = value.vb_uint8; break; @@ -2201,7 +2195,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, goto error; } - if (dict_attr_add_to_namespace(ctx->dict, UNCONST(fr_dict_attr_t *, vsa_da), new) < 0) { + if (dict_attr_add_to_namespace(UNCONST(fr_dict_attr_t *, vsa_da), new) < 0) { talloc_free(new); goto error; } @@ -2381,7 +2375,7 @@ int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir) goto error; } - if (dict_attr_add_to_namespace(dict, dict->root, n) < 0) { + if (dict_attr_add_to_namespace(dict->root, n) < 0) { fr_strerror_printf_push("Failed inserting '%s' into internal dictionary", type_name); talloc_free(type_name); goto error; diff --git a/src/lib/util/dict_unknown.c b/src/lib/util/dict_unknown.c index f4030e3e12..a76f39ae6e 100644 --- a/src/lib/util/dict_unknown.c +++ b/src/lib/util/dict_unknown.c @@ -114,7 +114,7 @@ fr_dict_attr_t const *fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const * is responsible for converting "Attr-26 = 0x..." to an actual attribute, * if it so desires. */ - if (dict_attr_add_to_namespace(dict, parent, n) < 0) { + if (dict_attr_add_to_namespace(parent, n) < 0) { talloc_free(n); return NULL; } @@ -291,11 +291,7 @@ fr_dict_attr_t *fr_dict_unknown_tlv_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t co .is_unknown = true, }; - switch (parent->type) { - case FR_TYPE_STRUCTURAL_EXCEPT_VSA: - break; - - default: + if (!fr_type_is_structural_except_vsa(parent->type)) { fr_strerror_printf("%s: Cannot allocate unknown tlv attribute (%u) with parent type %s", __FUNCTION__, num, @@ -321,11 +317,7 @@ fr_dict_attr_t *fr_dict_unknown_attr_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t c .is_unknown = true, }; - switch (parent->type) { - case FR_TYPE_STRUCTURAL_EXCEPT_VSA: - break; - - default: + if (!fr_type_is_structural_except_vsa(parent->type)) { fr_strerror_printf("%s: Cannot allocate unknown octets attribute (%u) with parent type %s", __FUNCTION__, num, diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index 5b72e6edc9..8a36b854e7 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -77,17 +77,6 @@ bool const fr_dict_attr_allowed_chars[UINT8_MAX + 1] = { ['z'] = true }; -/** Structural data types - * - */ -bool const fr_dict_non_data_types[FR_TYPE_MAX + 1] = { - [FR_TYPE_GROUP] = true, - [FR_TYPE_STRUCT] = true, - [FR_TYPE_TLV] = true, - [FR_TYPE_VENDOR] = true, - [FR_TYPE_VSA] = true -}; - /* * Create the hash of the name. * @@ -194,36 +183,6 @@ static int dict_attr_name_cmp(void const *one, void const *two) return strcasecmp(a->name, b->name); } -/** Hash a combo attribute - * - */ -static uint32_t dict_attr_combo_hash(void const *data) -{ - uint32_t hash; - fr_dict_attr_t const *attr = data; - - hash = fr_hash(&attr->parent, sizeof(attr->parent)); //-V568 - hash = fr_hash_update(&attr->type, sizeof(attr->type), hash); - return fr_hash_update(&attr->attr, sizeof(attr->attr), hash); -} - -/** Compare two combo attribute entries - * - */ -static int dict_attr_combo_cmp(void const *one, void const *two) -{ - fr_dict_attr_t const *a = one, *b = two; - int ret; - - ret = (a->parent < b->parent) - (a->parent > b->parent); - if (ret != 0) return ret; - - ret = (a->type < b->type) - (a->type > b->type); - if (ret != 0) return ret; - - return (a->attr > b->attr) - (a->attr < b->attr); -} - /** Wrap name hash function for fr_dict_vendor_t * * @param data fr_dict_vendor_t to hash. @@ -733,7 +692,7 @@ int dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_ if (dict_attr_child_add(dst, copy) < 0) return -1; - if (dict_attr_add_to_namespace(dict, dst, copy) < 0) return -1; + if (dict_attr_add_to_namespace(dst, copy) < 0) return -1; if (!dict_attr_children(child)) continue; @@ -1021,14 +980,13 @@ int dict_attr_child_add(fr_dict_attr_t *parent, fr_dict_attr_t *child) /** Add an attribute to the name table for an attribute * - * @param[in] dict of protocol context we're operating in. * @param[in] parent containing the namespace to add this attribute to. * @param[in] da to add to the name lookup tables. * @return * - 0 on success. * - -1 on failure. */ -int dict_attr_add_to_namespace(fr_dict_t *dict, fr_dict_attr_t const *parent, fr_dict_attr_t *da) +int dict_attr_add_to_namespace(fr_dict_attr_t const *parent, fr_dict_attr_t *da) { fr_hash_table_t *namespace; @@ -1085,71 +1043,6 @@ int dict_attr_add_to_namespace(fr_dict_t *dict, fr_dict_attr_t const *parent, fr } } - /* - * Insert copies of the attribute into the - * polymorphic attribute table. - * - * This allows an abstract attribute type - * like combo IP to be resolved to a - * concrete one later. - */ - switch (da->type) { - case FR_TYPE_COMBO_IP_ADDR: - { - fr_dict_attr_t *v4, *v6; - - fr_assert(dict->attributes_combo); - - v4 = dict_attr_acopy(dict->pool, da, NULL); - if (!v4) goto error; - v4->type = FR_TYPE_IPV4_ADDR; - - v6 = dict_attr_acopy(dict->pool, da, NULL); - if (!v6) goto error; - v6->type = FR_TYPE_IPV6_ADDR; - - if (!fr_hash_table_replace(dict->attributes_combo, v4)) { - fr_strerror_const("Failed inserting IPv4 version of combo attribute"); - goto error; - } - - if (!fr_hash_table_replace(dict->attributes_combo, v6)) { - fr_strerror_const("Failed inserting IPv6 version of combo attribute"); - goto error; - } - break; - } - - case FR_TYPE_COMBO_IP_PREFIX: - { - fr_dict_attr_t *v4, *v6; - - fr_assert(dict->attributes_combo); - - v4 = dict_attr_acopy(dict->pool, da, NULL); - if (!v4) goto error; - v4->type = FR_TYPE_IPV4_PREFIX; - - v6 = dict_attr_acopy(dict->pool, da, NULL); - if (!v6) goto error; - v6->type = FR_TYPE_IPV6_PREFIX; - - if (!fr_hash_table_replace(dict->attributes_combo, v4)) { - fr_strerror_const("Failed inserting IPv4 version of combo attribute"); - goto error; - } - - if (!fr_hash_table_replace(dict->attributes_combo, v6)) { - fr_strerror_const("Failed inserting IPv6 version of combo attribute"); - goto error; - } - break; - } - - default: - break; - } - return 0; } @@ -1248,7 +1141,7 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, old = fr_dict_attr_child_by_num(parent, n->attr); if (old && (dict_attr_compatible(parent, old, n) < 0)) goto error; - if (dict_attr_add_to_namespace(dict, parent, n) < 0) { + if (dict_attr_add_to_namespace(parent, n) < 0) { error: talloc_free(n); return -1; @@ -2623,27 +2516,6 @@ fr_dict_attr_t const *fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr return dict_attr_by_name(err, parent, name); } - -/** Lookup a attribute by its its vendor and attribute numbers and data type - * - * @note Only works with FR_TYPE_COMBO_IP - * - * @param[in] da to look for type variant of. - * @param[in] type Variant of attribute to lookup. - * @return - * - Attribute matching parent/attr/type. - * - NULL if no matching attribute could be found. - */ -fr_dict_attr_t const *fr_dict_attr_by_type(fr_dict_attr_t const *da, fr_type_t type) -{ - return fr_hash_table_find_by_data(dict_by_da(da)->attributes_combo, - &(fr_dict_attr_t){ - .parent = da->parent, - .attr = da->attr, - .type = type - }); -} - /** Check if a child attribute exists in a parent using a pointer (da) * * @param[in] parent to check for child in. @@ -2875,7 +2747,6 @@ static int _dict_free(fr_dict_t *dict) * are still there. */ talloc_free(dict->vendors_by_name); - talloc_free(dict->attributes_combo); if (dict->autoref && (fr_hash_table_walk(dict->autoref, _dict_free_autoref, NULL) < 0)) { @@ -2962,15 +2833,6 @@ fr_dict_t *dict_alloc(TALLOC_CTX *ctx) goto error; } - /* - * Horrible hacks for combo-IP. - */ - dict->attributes_combo = fr_hash_table_create(dict, dict_attr_combo_hash, dict_attr_combo_cmp, hash_pool_free); - if (!dict->attributes_combo) { - fr_strerror_printf("Failed allocating \"attributes_combo\" table"); - goto error; - } - /* * Set default type size and length. */ diff --git a/src/lib/util/dict_validate.c b/src/lib/util/dict_validate.c index 7f5630ed72..d5311b772e 100644 --- a/src/lib/util/dict_validate.c +++ b/src/lib/util/dict_validate.c @@ -298,9 +298,15 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, break; case FR_TYPE_IPV6_ADDR: + case FR_TYPE_COMBO_IP_ADDR: flags->length = 16; break; + case FR_TYPE_IPV6_PREFIX: + case FR_TYPE_COMBO_IP_PREFIX: + flags->length = 17; + break; + case FR_TYPE_STRUCT: ALLOW_FLAG(internal); if (all_flags) { @@ -410,30 +416,8 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, } break; - case FR_TYPE_COMBO_IP_ADDR: - if (strcasecmp(dict->root->name, "RADIUS") != 0) { - fr_strerror_const("The 'combo-ip' type can only be used in the RADIUS dictionary."); - return false; - } - - /* - * RFC 6929 says that this is a terrible idea. - */ - for (v = parent; v != NULL; v = v->parent) { - if (v->type == FR_TYPE_VSA) { - break; - } - } - - if (!v) { - fr_strerror_const("Attributes of type 'combo-ip' can only be used in VSA dictionaries"); - return false; - } - break; - case FR_TYPE_NULL: case FR_TYPE_FLOAT64: - case FR_TYPE_COMBO_IP_PREFIX: fr_strerror_printf("Attributes of type '%s' cannot be used in dictionaries", fr_table_str_by_value(fr_value_box_type_table, type, "?Unknown?")); return false; @@ -507,7 +491,7 @@ bool dict_attr_flags_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, * the first member. */ if (sibling->flags.length == 0) switch (sibling->type) { - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: break; default: diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index 0277d30d3b..81535166f1 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -1640,12 +1640,8 @@ int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src) */ int fr_pair_value_from_str(fr_pair_t *vp, char const *value, ssize_t inlen, char quote, bool tainted) { - fr_type_t type; - if (!value) return -1; - type = vp->da->type; - /* * This is not yet supported because the rest of the APIs * to parse pair names, etc. don't yet enforce "inlen". @@ -1653,10 +1649,10 @@ int fr_pair_value_from_str(fr_pair_t *vp, char const *value, ssize_t inlen, char * haven't yet audited the uses of this function for that * behavior. */ - switch (type) { + switch (vp->da->type) { case FR_TYPE_STRUCTURAL: fr_strerror_printf("Attributes of type '%s' are not yet supported", - fr_table_str_by_value(fr_value_box_type_table, type, "")); + fr_table_str_by_value(fr_value_box_type_table, vp->da->type, "")); return -1; default: @@ -1667,29 +1663,7 @@ int fr_pair_value_from_str(fr_pair_t *vp, char const *value, ssize_t inlen, char * We presume that the input data is from a double quoted * string, and needs unescaping */ - if (fr_value_box_from_str(vp, &vp->data, &type, vp->da, value, inlen, quote, tainted) < 0) return -1; - - /* - * If we parsed to a different type than the DA associated with - * the fr_pair_t we now need to fixup the DA. - * - * This is for types COMBO_IP. fr_pair_ts have a fixed - * data type, and not a polymorphic one. So instead of - * hacking polymorphic crap through the entire server - * code, we have this hack to make them static. - */ - if (type != vp->da->type) { - fr_dict_attr_t const *da; - - da = fr_dict_attr_by_type(vp->da, type); - if (!da) { - fr_strerror_printf("Cannot find %s variant of attribute \"%s\"", - fr_table_str_by_value(fr_value_box_type_table, type, ""), vp->da->name); - return -1; - } - vp->da = da; - vp->data.enumv = da; - } + if (fr_value_box_from_str(vp, &vp->data, vp->da->type, vp->da, value, inlen, quote, tainted) < 0) return -1; vp->type = VT_DATA; VP_VERIFY(vp); @@ -2220,11 +2194,7 @@ char const *fr_pair_value_enum(fr_pair_t const *vp, char buff[20]) char const *str; fr_dict_enum_t const *enumv = NULL; - switch (vp->vp_type) { - case FR_TYPE_NUMERIC: - break; - - default: + if (!fr_box_is_numeric(&vp->data)) { fr_strerror_printf("Pair %s is not numeric", vp->da->name); return NULL; } @@ -2414,18 +2384,6 @@ void fr_pair_verify(char const *file, int line, fr_pair_t const *vp) fr_dict_attr_t const *da; da = vp->da; - - if (da->type == FR_TYPE_COMBO_IP_ADDR) { - da = fr_dict_attr_by_type(vp->da, vp->da->type); - if (!da) { - fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t attribute %p \"%s\" " - "variant (%s) not found in global dictionary", - file, line, vp->da, vp->da->name, - fr_table_str_by_value(fr_value_box_type_table, - vp->da->type, "")); - } - } - if (da != vp->da) { fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t " "dictionary pointer %p \"%s\" (%s) " diff --git a/src/lib/util/struct.c b/src/lib/util/struct.c index 48574bd180..1d17bee355 100644 --- a/src/lib/util/struct.c +++ b/src/lib/util/struct.c @@ -239,7 +239,7 @@ ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_dcursor_t *cursor, FR_PROTO_TRACE("fr_struct_from_network - unknown child type"); goto unknown; - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: break; } diff --git a/src/lib/util/types.c b/src/lib/util/types.c index ec092bc65c..fda81d3d59 100644 --- a/src/lib/util/types.c +++ b/src/lib/util/types.c @@ -38,12 +38,12 @@ bool const fr_type_ip[FR_TYPE_MAX + 1] = FR_TYPE_IP_DEF(ARRAY_BEG, ARRAY_MID, AR bool const fr_type_fixed_size[FR_TYPE_MAX + 1] = FR_TYPE_FIXED_SIZE_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); bool const fr_type_variable_size[FR_TYPE_MAX + 1] = FR_TYPE_VARIABLE_SIZE_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); -bool const fr_type_values[FR_TYPE_MAX + 1] = FR_TYPE_VALUES_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); bool const fr_type_quoted[FR_TYPE_MAX + 1] = FR_TYPE_QUOTED_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); bool const fr_type_structural_except_vsa[FR_TYPE_MAX + 1] = FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); bool const fr_type_structural[FR_TYPE_MAX + 1] = FR_TYPE_STRUCTURAL_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); -bool const fr_type_non_values[FR_TYPE_MAX + 1] = FR_TYPE_NON_VALUES_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); +bool const fr_type_leaf[FR_TYPE_MAX + 1] = FR_TYPE_LEAF_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); +bool const fr_type_non_leaf[FR_TYPE_MAX + 1] = FR_TYPE_NON_LEAF_DEF(ARRAY_BEG, ARRAY_MID, ARRAY_END); #define O(_x) [FR_TYPE_ ## _x] = true @@ -125,7 +125,7 @@ bool fr_type_cast(fr_type_t dst, fr_type_t src) * Invalid casts. */ switch (dst) { - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: return false; default: @@ -133,7 +133,7 @@ bool fr_type_cast(fr_type_t dst, fr_type_t src) } switch (src) { - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: return false; default: @@ -414,7 +414,7 @@ fr_type_t fr_type_promote(fr_type_t a, fr_type_t b) * Invalid types */ switch (a) { - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: return FR_TYPE_NULL; default: @@ -422,7 +422,7 @@ fr_type_t fr_type_promote(fr_type_t a, fr_type_t b) } switch (b) { - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: return FR_TYPE_NULL; default: diff --git a/src/lib/util/types.h b/src/lib/util/types.h index 07cb450c25..ab9876d80e 100644 --- a/src/lib/util/types.h +++ b/src/lib/util/types.h @@ -135,13 +135,17 @@ typedef enum { /** Types which can fit in an #fr_ipaddr_t * + * - Combo IP addresses + * - Combo IP prefixes * - IPv4 addresses * - IPv6 addresses * - IPv4 prefix * - IPv6 prefix */ #define FR_TYPE_IP_DEF(_beg, _mid, _end) \ - _beg(FR_TYPE_IPV4_ADDR) \ + _beg(FR_TYPE_COMBO_IP_ADDR) \ + _mid(FR_TYPE_COMBO_IP_PREFIX) \ + _mid(FR_TYPE_IPV4_ADDR) \ _mid(FR_TYPE_IPV4_PREFIX) \ _mid(FR_TYPE_IPV6_ADDR) \ _end(FR_TYPE_IPV6_PREFIX) @@ -155,10 +159,17 @@ typedef enum { #define FR_TYPE_FIXED_SIZE_DEF(_beg, _mid, _end) \ _beg(FR_TYPE_ETHERNET) \ _mid(FR_TYPE_IFID) \ - FR_TYPE_IP_DEF(_mid, _mid, _mid) \ + _mid(FR_TYPE_IPV4_ADDR) \ + _mid(FR_TYPE_IPV4_PREFIX) \ + _mid(FR_TYPE_IPV6_ADDR) \ + _mid(FR_TYPE_IPV6_PREFIX) \ FR_TYPE_NUMERIC_DEF(_mid, _mid, _end) /** Match all variable length types + * + * @note Whilst combo IP addresses and prefixes may technically be + * variable length on the wire, these groupings are referring + * to our internal box representation which is fixed size. * * - Strings * - Octets @@ -167,20 +178,6 @@ typedef enum { _beg(FR_TYPE_STRING) \ _end(FR_TYPE_OCTETS) -/** Types which represent concrete values - * - * - Network addresses - * - Strings - * - Octets - * - Numbers - */ -#define FR_TYPE_VALUES_DEF(_beg, _mid, _end) \ - _beg(FR_TYPE_ETHERNET) \ - _mid(FR_TYPE_IFID) \ - FR_TYPE_IP_DEF(_mid, _mid, _mid) \ - FR_TYPE_VARIABLE_SIZE_DEF(_mid, _mid, _mid) \ - FR_TYPE_NUMERIC_DEF(_mid, _mid, _end) - /** Types which should be wrapped in double quotes when printed * * - Strings @@ -215,20 +212,30 @@ typedef enum { _beg(FR_TYPE_VSA) \ FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(_mid, _mid, _end) -/** Types which do not represent concrete values +/** Types which represent concrete values + * + * - Network addresses + * - Strings + * - Octets + * - Numbers + */ +#define FR_TYPE_LEAF_DEF(_beg, _mid, _end) \ + _beg(FR_TYPE_ETHERNET) \ + _mid(FR_TYPE_IFID) \ + FR_TYPE_IP_DEF(_mid, _mid, _mid) \ + FR_TYPE_VARIABLE_SIZE_DEF(_mid, _mid, _mid) \ + FR_TYPE_NUMERIC_DEF(_mid, _mid, _end) + +/** Types which do not represent leaf values * - * - Combo IPs - * - Combo prefixes * - Structural * - Boxes (can represent any type) * - Void (opaque types) * - Null (lack of value) * - Invalid values */ -#define FR_TYPE_NON_VALUES_DEF(_beg, _mid, _end) \ - _beg(FR_TYPE_COMBO_IP_ADDR) \ - _mid(FR_TYPE_COMBO_IP_PREFIX) \ - _mid(FR_TYPE_VALUE_BOX) \ +#define FR_TYPE_NON_LEAF_DEF(_beg, _mid, _end) \ + _beg(FR_TYPE_VALUE_BOX) \ _mid(FR_TYPE_VOID) \ _mid(FR_TYPE_NULL) \ _mid(FR_TYPE_MAX) \ @@ -251,12 +258,12 @@ typedef enum { #define FR_TYPE_FIXED_SIZE FR_TYPE_FIXED_SIZE_DEF(CASE_BEG, CASE_MID, CASE_END) #define FR_TYPE_VARIABLE_SIZE FR_TYPE_VARIABLE_SIZE_DEF(CASE_BEG, CASE_MID, CASE_END) -#define FR_TYPE_VALUES FR_TYPE_VALUES_DEF(CASE_BEG, CASE_MID, CASE_END) #define FR_TYPE_QUOTED FR_TYPE_QUOTED_DEF(CASE_BEG, CASE_MID, CASE_END) #define FR_TYPE_STRUCTURAL_EXCEPT_VSA FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(CASE_BEG, CASE_MID, CASE_END) #define FR_TYPE_STRUCTURAL FR_TYPE_STRUCTURAL_DEF(CASE_BEG, CASE_MID, CASE_END) -#define FR_TYPE_NON_VALUES FR_TYPE_NON_VALUES_DEF(CASE_BEG, CASE_MID, CASE_END) +#define FR_TYPE_LEAF FR_TYPE_LEAF_DEF(CASE_BEG, CASE_MID, CASE_END) +#define FR_TYPE_NON_LEAF FR_TYPE_NON_LEAF_DEF(CASE_BEG, CASE_MID, CASE_END) /** @} */ /** @name Bool arrays that group types @@ -271,12 +278,12 @@ extern bool const fr_type_ip[FR_TYPE_MAX + 1]; extern bool const fr_type_fixed_size[FR_TYPE_MAX + 1]; extern bool const fr_type_variable_size[FR_TYPE_MAX + 1]; -extern bool const fr_type_values[FR_TYPE_MAX + 1]; extern bool const fr_type_quoted[FR_TYPE_MAX + 1]; extern bool const fr_type_structural_except_vsa[FR_TYPE_MAX + 1]; extern bool const fr_type_structural[FR_TYPE_MAX + 1]; -extern bool const fr_type_non_values[FR_TYPE_MAX + 1]; +extern bool const fr_type_leaf[FR_TYPE_MAX + 1]; +extern bool const fr_type_non_leaf[FR_TYPE_MAX + 1]; /** @} */ /** @name Type checking macros @@ -323,13 +330,13 @@ extern bool const fr_type_non_values[FR_TYPE_MAX + 1]; #define fr_type_is_ip(_x) (fr_type_ip[_x]) #define fr_type_is_fixed_size(_x) (fr_type_fixed_size[_x]) -#define fr_type_is_variable_size(_x) (fr_variable_size[_x]) -#define fr_type_is_value(_x) (fr_type_values[_x]) +#define fr_type_is_variable_size(_x) (fr_type_variable_size[_x]) #define fr_type_is_quoted(_x) (fr_type_quoted[_x]) #define fr_type_is_structural_except_vsa(_x) (fr_type_structural_except_vsa[_x]) #define fr_type_is_structural(_x) (fr_type_structural[_x]) -#define fr_type_is_non_value(_x) (fr_type_non_values[_x]) +#define fr_type_is_leaf(_x) (fr_type_leaf[_x]) +#define fr_type_is_non_leaf(_x) (fr_type_non_leaf[_x]) /** @} */ bool fr_type_cast(fr_type_t dst, fr_type_t src); diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 8cd93734a1..67b719df0c 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -177,6 +177,8 @@ static size_t const fr_value_box_network_sizes[FR_TYPE_MAX + 1][2] = { [FR_TYPE_IPV4_PREFIX] = {5, 5}, [FR_TYPE_IPV6_ADDR] = {16, 17}, [FR_TYPE_IPV6_PREFIX] = {17, 18}, + [FR_TYPE_COMBO_IP_ADDR] = {4, 17}, + [FR_TYPE_COMBO_IP_PREFIX] = {16, 18}, [FR_TYPE_IFID] = {8, 8}, [FR_TYPE_ETHERNET] = {6, 6}, @@ -636,6 +638,8 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_ADDR: case FR_TYPE_IPV6_PREFIX: + case FR_TYPE_COMBO_IP_ADDR: + case FR_TYPE_COMBO_IP_PREFIX: compare = memcmp(&a->vb_ip, &b->vb_ip, sizeof(a->vb_ip)); break; @@ -646,7 +650,7 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) /* * These should be handled at some point */ - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: (void)fr_cond_assert(0); /* unknown type */ return -2; @@ -1063,7 +1067,7 @@ int fr_value_box_hton(fr_value_box_t *dst, fr_value_box_t const *src) case FR_TYPE_OCTETS: case FR_TYPE_STRING: - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: fr_assert_fail(NULL); return -1; /* shouldn't happen */ } @@ -1241,6 +1245,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) switch (value->type) { case FR_TYPE_IPV4_ADDR: + ipv4addr: FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, (uint8_t const *)&value->vb_ip.addr.v4.s_addr, sizeof(value->vb_ip.addr.v4.s_addr)); @@ -1249,6 +1254,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) * Needs special mangling */ case FR_TYPE_IPV4_PREFIX: + ipv4prefix: FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.prefix); FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, (uint8_t const *)&value->vb_ip.addr.v4.s_addr, @@ -1256,11 +1262,13 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) break; case FR_TYPE_IPV6_ADDR: + ipv6addr: if (value->vb_ip.scope_id > 0) FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.scope_id); FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, value->vb_ip.addr.v6.s6_addr, sizeof(value->vb_ip.addr.v6.s6_addr)); break; case FR_TYPE_IPV6_PREFIX: + ipv6prefix: if (value->vb_ip.scope_id > 0) FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.scope_id); FR_DBUFF_IN_RETURN(&work_dbuff, value->vb_ip.prefix); FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, value->vb_ip.addr.v6.s6_addr, sizeof(value->vb_ip.addr.v6.s6_addr)); @@ -1270,6 +1278,36 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, value->datum.boolean); break; + case FR_TYPE_COMBO_IP_ADDR: + switch (value->vb_ip.af) { + case AF_INET: + goto ipv4addr; + + case AF_INET6: + goto ipv6addr; + + default: + break; + } + + fr_strerror_const("Combo IP value missing af"); + return 0; + + case FR_TYPE_COMBO_IP_PREFIX: + switch (value->vb_ip.af) { + case AF_INET: + goto ipv4prefix; + + case AF_INET6: + goto ipv6prefix; + + default: + break; + } + + fr_strerror_const("Combo IP value missing af"); + return 0; + /* * Already in network byte-order */ @@ -1426,7 +1464,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) case FR_TYPE_OCTETS: case FR_TYPE_STRING: case FR_TYPE_SIZE: - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: goto unsupported; } @@ -1524,6 +1562,7 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, * Already in network byte order */ case FR_TYPE_IPV4_ADDR: + ipv4addr: dst->vb_ip = (fr_ipaddr_t){ .af = AF_INET, .prefix = 32, @@ -1532,6 +1571,7 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, break; case FR_TYPE_IPV4_PREFIX: + ipv4prefix: dst->vb_ip = (fr_ipaddr_t){ .af = AF_INET, }; @@ -1540,6 +1580,7 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, break; case FR_TYPE_IPV6_ADDR: + ipv6addr: dst->vb_ip = (fr_ipaddr_t){ .af = AF_INET6, .scope_id = 0, @@ -1556,6 +1597,7 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, break; case FR_TYPE_IPV6_PREFIX: + ipv6prefix: dst->vb_ip = (fr_ipaddr_t){ .af = AF_INET6, .scope_id = 0, @@ -1571,6 +1613,22 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, FR_DBUFF_OUT_MEMCPY_RETURN((uint8_t *)&dst->vb_ip.addr.v6, &work_dbuff, len - 1); break; + case FR_TYPE_COMBO_IP_ADDR: + if ((len >= network_min_size(FR_TYPE_IPV6_ADDR)) && + (len <= network_max_size(FR_TYPE_IPV6_ADDR))) goto ipv6addr; /* scope is optional */ + else if ((len >= network_min_size(FR_TYPE_IPV4_ADDR)) && + (len <= network_max_size(FR_TYPE_IPV4_ADDR))) goto ipv4addr; + fr_strerror_const("Invalid combo ip address value"); + return 0; + + case FR_TYPE_COMBO_IP_PREFIX: + if ((len >= network_min_size(FR_TYPE_IPV6_PREFIX)) && + (len <= network_max_size(FR_TYPE_IPV6_PREFIX))) goto ipv6prefix; /* scope is optional */ + else if ((len >= network_min_size(FR_TYPE_IPV4_PREFIX)) && + (len <= network_max_size(FR_TYPE_IPV4_PREFIX))) goto ipv4prefix; + fr_strerror_const("Invalid combo ip prefix value"); + return 0; + case FR_TYPE_BOOL: { uint8_t val = 0; @@ -1723,7 +1781,7 @@ ssize_t fr_value_box_from_network_dbuff(TALLOC_CTX *ctx, break; /* Already dealt with */ case FR_TYPE_SIZE: - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: fr_strerror_printf("Cannot decode type \"%s\" - Is not a value", fr_table_str_by_value(fr_value_box_type_table, type, "")); break; @@ -1745,13 +1803,7 @@ static int fr_value_box_fixed_size_from_octets(fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src) { - switch (dst_type) { - case FR_TYPE_FIXED_SIZE: - break; - - default: - if (!fr_cond_assert(false)) return -1; - } + if (!fr_type_is_fixed_size(dst_type)) if (!fr_cond_assert(false)) return -1; if (src->vb_length < network_min_size(dst_type)) { fr_strerror_printf("Invalid cast from %s to %s. Source is length %zd is smaller than " @@ -2028,7 +2080,7 @@ static inline int fr_value_box_cast_to_ipv4addr(TALLOC_CTX *ctx, fr_value_box_t switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); default: @@ -2136,7 +2188,7 @@ static inline int fr_value_box_cast_to_ipv4prefix(TALLOC_CTX *ctx, fr_value_box_ switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); default: @@ -2247,7 +2299,7 @@ static inline int fr_value_box_cast_to_ipv6addr(TALLOC_CTX *ctx, fr_value_box_t switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); default: @@ -2352,7 +2404,7 @@ static inline int fr_value_box_cast_to_ipv6prefix(TALLOC_CTX *ctx, fr_value_box_ switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); default: @@ -2442,7 +2494,7 @@ static inline int fr_value_box_cast_to_ethernet(TALLOC_CTX *ctx, fr_value_box_t switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); case FR_TYPE_OCTETS: @@ -2501,7 +2553,7 @@ static inline int fr_value_box_cast_to_bool(TALLOC_CTX *ctx, fr_value_box_t *dst switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); case FR_TYPE_OCTETS: @@ -2766,7 +2818,7 @@ static inline int fr_value_box_cast_to_integer(TALLOC_CTX *ctx, fr_value_box_t * { switch (src->type) { case FR_TYPE_STRING: - return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); case FR_TYPE_OCTETS: @@ -2879,7 +2931,7 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, if (!fr_cond_assert(src != dst)) return -1; if (!fr_cond_assert(src->type != FR_TYPE_NULL)) return -1; - if (fr_dict_non_data_types[dst_type]) { + if (fr_type_is_non_leaf(dst_type)) { fr_strerror_printf("Invalid cast from %s to %s. Can only cast simple data types", fr_table_str_by_value(fr_value_box_type_table, src->type, ""), fr_table_str_by_value(fr_value_box_type_table, dst_type, "")); @@ -2939,12 +2991,13 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, case FR_TYPE_IPV6_PREFIX: return fr_value_box_cast_to_ipv6prefix(ctx, dst, dst_type, dst_enumv, src); + case FR_TYPE_COMBO_IP_ADDR: + case FR_TYPE_COMBO_IP_PREFIX: + break; /* * Need func */ case FR_TYPE_IFID: - case FR_TYPE_COMBO_IP_ADDR: - case FR_TYPE_COMBO_IP_PREFIX: break; case FR_TYPE_ETHERNET: @@ -2977,7 +3030,7 @@ int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, /* * Deserialise a fr_value_box_t */ - if (src->type == FR_TYPE_STRING) return fr_value_box_from_str(ctx, dst, &dst_type, dst_enumv, + if (src->type == FR_TYPE_STRING) return fr_value_box_from_str(ctx, dst, dst_type, dst_enumv, src->vb_strvalue, src->vb_length, '\0', src->tainted); @@ -3136,11 +3189,7 @@ int fr_value_box_ipaddr(fr_value_box_t *dst, fr_dict_attr_t const *enumv, fr_ipa */ int fr_value_unbox_ipaddr(fr_ipaddr_t *dst, fr_value_box_t *src) { - switch (src->type) { - case FR_TYPE_IP: - break; - - default: + if (!fr_type_is_ip(src->type)) { fr_strerror_printf("Unboxing failed. Needed IPv4/6 addr/prefix, had type %s", fr_table_str_by_value(fr_value_box_type_table, src->type, "?Unknown?")); return -1; @@ -4271,21 +4320,21 @@ static int fr_value_box_from_integer_str(fr_value_box_t *dst, fr_type_t dst_type * - -1 on parse error. */ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t *dst_type, fr_dict_attr_t const *dst_enumv, + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, ssize_t inlen, char quote, bool tainted) { size_t len; ssize_t ret; char buffer[256]; - if (!fr_cond_assert(*dst_type != FR_TYPE_NULL)) return -1; + if (!fr_cond_assert(dst_type != FR_TYPE_NULL)) return -1; len = (inlen < 0) ? strlen(in) : (size_t)inlen; /* * Set size for all fixed length attributes. */ - ret = network_max_size(*dst_type); + ret = network_max_size(dst_type); /* * Lookup any names before continuing @@ -4322,7 +4371,7 @@ parse: * It's a variable ret src->dst_type so we just alloc a new buffer * of size len and copy. */ - switch (*dst_type) { + switch (dst_type) { case FR_TYPE_STRING: { char *buff; @@ -4428,7 +4477,7 @@ parse: case FR_TYPE_MAX: case FR_TYPE_NULL: fr_strerror_printf("Invalid dst_type %s", - fr_table_str_by_value(fr_value_box_type_table, *dst_type, "")); + fr_table_str_by_value(fr_value_box_type_table, dst_type, "")); return -1; } @@ -4447,7 +4496,7 @@ parse: in = buffer; } - switch (*dst_type) { + switch (dst_type) { case FR_TYPE_IPV4_ADDR: case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_ADDR: @@ -4462,7 +4511,7 @@ parse: case FR_TYPE_INT16: case FR_TYPE_INT32: case FR_TYPE_INT64: - if (fr_value_box_from_integer_str(dst, *dst_type, in) < 0) return -1; + if (fr_value_box_from_integer_str(dst, dst_type, in) < 0) return -1; break; case FR_TYPE_SIZE: @@ -4574,24 +4623,37 @@ parse: * and attribute as the original. */ case FR_TYPE_COMBO_IP_ADDR: - { if (fr_inet_pton(&dst->vb_ip, in, inlen, AF_UNSPEC, fr_hostname_lookups, true) < 0) return -1; switch (dst->vb_ip.af) { case AF_INET: - *dst_type = FR_TYPE_IPV4_ADDR; - ret = network_min_size(*dst_type); + ret = network_max_size(FR_TYPE_IPV4_ADDR); break; case AF_INET6: - *dst_type = FR_TYPE_IPV6_ADDR; - ret = network_max_size(*dst_type); + ret = network_max_size(FR_TYPE_IPV6_ADDR); + break; + + default: + fr_strerror_printf("Bad address family %i", dst->vb_ip.af); + return -1; + } + break; + + case FR_TYPE_COMBO_IP_PREFIX: + if (fr_inet_pton(&dst->vb_ip, in, inlen, AF_UNSPEC, fr_hostname_lookups, true) < 0) return -1; + switch (dst->vb_ip.af) { + case AF_INET: + ret = network_max_size(FR_TYPE_IPV4_PREFIX); + break; + + case AF_INET6: + ret = network_max_size(FR_TYPE_IPV6_PREFIX); break; default: fr_strerror_printf("Bad address family %i", dst->vb_ip.af); return -1; } - } break; case FR_TYPE_BOOL: @@ -4605,22 +4667,19 @@ parse: } break; - case FR_TYPE_COMBO_IP_PREFIX: - break; - case FR_TYPE_VALUE_BOX: case FR_TYPE_VARIABLE_SIZE: /* Should have been dealt with above */ case FR_TYPE_STRUCTURAL: /* Listed again to suppress compiler warnings */ case FR_TYPE_VOID: case FR_TYPE_MAX: case FR_TYPE_NULL: - fr_strerror_printf("Unknown attribute dst_type %d", *dst_type); + fr_strerror_printf("Unknown attribute dst_type %d", dst_type); return -1; } finish: dst->vb_length = ret; - dst->type = *dst_type; + dst->type = dst_type; dst->tainted = tainted; /* @@ -4683,12 +4742,14 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff */ case FR_TYPE_IPV4_ADDR: case FR_TYPE_IPV6_ADDR: + case FR_TYPE_COMBO_IP_ADDR: if (!fr_inet_ntop(buf, sizeof(buf), &data->vb_ip)) return 0; FR_SBUFF_IN_STRCPY_RETURN(&our_out, buf); break; case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_PREFIX: + case FR_TYPE_COMBO_IP_PREFIX: if (!fr_inet_ntop_prefix(buf, sizeof(buf), &data->vb_ip)) return 0; FR_SBUFF_IN_STRCPY_RETURN(&our_out, buf); break; @@ -4892,8 +4953,6 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff case FR_TYPE_STRUCT: /* Not a box type */ case FR_TYPE_VSA: /* Not a box type */ case FR_TYPE_VENDOR: /* Not a box type */ - case FR_TYPE_COMBO_IP_ADDR: - case FR_TYPE_COMBO_IP_PREFIX: case FR_TYPE_VALUE_BOX: case FR_TYPE_VOID: case FR_TYPE_MAX: diff --git a/src/lib/util/value.h b/src/lib/util/value.h index 27a91c93b2..3468a13c08 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -769,9 +769,9 @@ void fr_value_box_increment(fr_value_box_t *vb); * @{ */ int fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, - fr_type_t *dst_type, fr_dict_attr_t const *dst_enumv, + fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *src, ssize_t src_len, char quote, bool tainted) - CC_HINT(nonnull(2,3,5)); + CC_HINT(nonnull(2,5)); /** @} */ /** @name Work with lists of boxed values diff --git a/src/modules/rlm_csv/rlm_csv.c b/src/modules/rlm_csv/rlm_csv.c index fe51b3a753..a6b1883696 100644 --- a/src/modules/rlm_csv/rlm_csv.c +++ b/src/modules/rlm_csv/rlm_csv.c @@ -245,7 +245,7 @@ static bool duplicate_entry(CONF_SECTION *conf, rlm_csv_t *inst, rlm_csv_entry_t talloc_set_type(e, rlm_csv_entry_t); e->key = talloc_zero(e, fr_value_box_t); - if (fr_value_box_from_str(e->key, e->key, &type, NULL, p, -1, 0, false) < 0) { + if (fr_value_box_from_str(e->key, e->key, type, NULL, p, -1, 0, false) < 0) { cf_log_err(conf, "Failed parsing key field in file %s line %d - %s", inst->filename, lineno, fr_strerror()); return false; @@ -328,7 +328,7 @@ static bool file2csv(CONF_SECTION *conf, rlm_csv_t *inst, int lineno, char *buff * Set the last entry to use 'e' */ e->key = talloc_zero(e, fr_value_box_t); - if (fr_value_box_from_str(e->key, e->key, &type, NULL, p, -1, 0, false) < 0) { + if (fr_value_box_from_str(e->key, e->key, type, NULL, p, -1, 0, false) < 0) { cf_log_err(conf, "Failed parsing key field in file %s line %d - %s", inst->filename, lineno, fr_strerror()); fail: @@ -350,7 +350,7 @@ static bool file2csv(CONF_SECTION *conf, rlm_csv_t *inst, int lineno, char *buff fr_value_box_t box; fr_type_t type = inst->field_types[i]; - if (fr_value_box_from_str(e, &box, &type, NULL, p, -1, 0, false) < 0) { + if (fr_value_box_from_str(e, &box, type, NULL, p, -1, 0, false) < 0) { cf_log_err(conf, "Failed parsing field '%s' in file %s line %d - %s", inst->field_names[i], inst->filename, lineno, fr_strerror()); goto fail; @@ -541,7 +541,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) if (inst->key) { inst->key_data_type = tmpl_expanded_type(inst->key); switch (inst->key_data_type) { - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: break; case FR_TYPE_NULL: diff --git a/src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c b/src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c index efc8cd8480..90fa0c9609 100644 --- a/src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c +++ b/src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c @@ -531,7 +531,8 @@ redo: */ static int match_subword(rlm_isc_dhcp_tokenizer_t *state, char const *cmd, rlm_isc_dhcp_info_t *info) { - int ret, type; + int ret; + fr_type_t type; int semicolon = NO_SEMICOLON; bool multi = false; char *p; @@ -652,8 +653,8 @@ static int match_subword(rlm_isc_dhcp_tokenizer_t *state, char const *cmd, rlm_i semicolon = MAYBE_SEMICOLON; } - type = fr_table_value_by_str(fr_value_box_type_table, type_name, -1); - if (type < 0) { + type = fr_table_value_by_str(fr_value_box_type_table, type_name, FR_TYPE_NULL); + if (type == FR_TYPE_NULL) { fr_strerror_printf("unknown data type '%.*s'", (int) (next - cmd), cmd); return -1; /* internal error */ @@ -692,7 +693,7 @@ redo_multi: */ info->argv[info->argc] = talloc_zero(info, fr_value_box_t); - ret = fr_value_box_from_str(info, info->argv[info->argc], (fr_type_t *) &type, NULL, + ret = fr_value_box_from_str(info, info->argv[info->argc], type, NULL, state->token, state->token_len, 0, false); if (ret < 0) return ret; @@ -882,7 +883,7 @@ static int parse_option_definition(rlm_isc_dhcp_info_t *parent, rlm_isc_dhcp_tok } type = FR_TYPE_UINT32; - ret = fr_value_box_from_str(NULL, &box, &type, NULL, + ret = fr_value_box_from_str(NULL, &box, type, NULL, state->token, state->token_len, 0, false); if (ret < 0) goto error; diff --git a/src/modules/rlm_lua/lua.c b/src/modules/rlm_lua/lua.c index c3543941eb..b53c7f1923 100644 --- a/src/modules/rlm_lua/lua.c +++ b/src/modules/rlm_lua/lua.c @@ -90,6 +90,8 @@ static int fr_lua_marshall(request_t *request, lua_State *L, fr_pair_t const *vp case FR_TYPE_IPV6_ADDR: case FR_TYPE_IPV4_PREFIX: case FR_TYPE_IPV6_PREFIX: + case FR_TYPE_COMBO_IP_ADDR: + case FR_TYPE_COMBO_IP_PREFIX: case FR_TYPE_IFID: case FR_TYPE_TIME_DELTA: { @@ -172,7 +174,7 @@ static int fr_lua_marshall(request_t *request, lua_State *L, fr_pair_t const *vp lua_pushinteger(L, (lua_Integer)vp->vp_size); break; - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: REDEBUG("Cannot convert %s to Lua type", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "")); return -1; } diff --git a/src/modules/rlm_mruby/rlm_mruby.c b/src/modules/rlm_mruby/rlm_mruby.c index df4b52d1cf..712c205f5e 100644 --- a/src/modules/rlm_mruby/rlm_mruby.c +++ b/src/modules/rlm_mruby/rlm_mruby.c @@ -286,7 +286,7 @@ static int mruby_vps_to_array(request_t *request, mrb_value *out, mrb_state *mrb val = mrb_convert_type(mrb, to_cast, MRB_TT_FLOAT, "Float", "to_f"); break; - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: fr_assert(0); return -1; } diff --git a/src/modules/rlm_python/rlm_python.c b/src/modules/rlm_python/rlm_python.c index 5c3dd988a7..e25b6c45d1 100644 --- a/src/modules/rlm_python/rlm_python.c +++ b/src/modules/rlm_python/rlm_python.c @@ -435,6 +435,8 @@ static int mod_populate_vptuple(rlm_python_t const *inst, request_t *request, Py case FR_TYPE_IPV6_PREFIX: case FR_TYPE_IPV4_ADDR: case FR_TYPE_IPV4_PREFIX: + case FR_TYPE_COMBO_IP_ADDR: + case FR_TYPE_COMBO_IP_PREFIX: case FR_TYPE_ETHERNET: { ssize_t slen; @@ -452,7 +454,7 @@ static int mod_populate_vptuple(rlm_python_t const *inst, request_t *request, Py } break; - case FR_TYPE_NON_VALUES: + case FR_TYPE_NON_LEAF: fr_assert(0); return -1; } diff --git a/src/protocols/internal/encode.c b/src/protocols/internal/encode.c index c4b00cb9bc..a0e7d51bef 100644 --- a/src/protocols/internal/encode.c +++ b/src/protocols/internal/encode.c @@ -77,7 +77,7 @@ static ssize_t internal_encode(fr_dbuff_t *dbuff, /* * Only leaf attributes can be tainted */ - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: if (vp->vp_tainted) enc_byte |= FR_INTERNAL_FLAG_TAINTED; break; @@ -117,7 +117,7 @@ static ssize_t internal_encode(fr_dbuff_t *dbuff, fr_dbuff_marker(&value_field, &value_dbuff); switch (da->type) { - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: slen = fr_value_box_to_network(&value_dbuff, &vp->data); if (slen < 0) return PAIR_ENCODE_FATAL_ERROR; FR_PROTO_HEX_DUMP(fr_dbuff_start(&value_dbuff), slen, "value %s", diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 9006d679b0..7e915a57e9 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -94,7 +94,7 @@ size_t const fr_radius_attr_sizes[FR_TYPE_MAX + 1][2] = { [FR_TYPE_IPV6_ADDR] = {16, 16}, [FR_TYPE_IPV6_PREFIX] = {2, 18}, [FR_TYPE_COMBO_IP_PREFIX] = {6, 18}, - [FR_TYPE_COMBO_IP_ADDR] = {4, 16}, + [FR_TYPE_COMBO_IP_ADDR] = {4, 17}, [FR_TYPE_IFID] = {8, 8}, [FR_TYPE_ETHERNET] = {6, 6}, @@ -213,12 +213,12 @@ size_t fr_radius_attr_len(fr_pair_t const *vp) if (vp->da->flags.length) return vp->da->flags.length; /* Variable type with fixed length */ return vp->vp_length; - default: - return fr_radius_attr_sizes[vp->vp_type][0]; - case FR_TYPE_STRUCTURAL: fr_assert_fail(NULL); return 0; + + default: + return fr_radius_attr_sizes[vp->vp_type][0]; } } diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 546b8db507..6992a733ba 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -1236,39 +1236,7 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_di } switch (parent->type) { - case FR_TYPE_VALUES: - break; - - case FR_TYPE_COMBO_IP_PREFIX: - if (data_len == min) { - child = fr_dict_attr_by_type(parent, FR_TYPE_IPV4_PREFIX); - } else if (data_len == max) { - child = fr_dict_attr_by_type(parent, FR_TYPE_IPV6_PREFIX); - } else { - FR_PROTO_TRACE("Combo attribute len %zu incorrect, must be %zu or %zu", data_len, min, max); - goto raw; - } - if (!child) { - FR_PROTO_TRACE("Missing type variant for combo attribute len %zu", data_len); - goto raw; - } - parent = child; /* re-write it */ - break; - - case FR_TYPE_COMBO_IP_ADDR: - if (data_len == min) { - child = fr_dict_attr_by_type(parent, FR_TYPE_IPV4_ADDR); - } else if (data_len == max) { - child = fr_dict_attr_by_type(parent, FR_TYPE_IPV6_ADDR); - } else { - FR_PROTO_TRACE("Combo attribute len %zu incorrect, must be %zu or %zu", data_len, min, max); - goto raw; - } - if (!child) { - FR_PROTO_TRACE("Missing type variant for combo attribute len %zu", data_len); - goto raw; - } - parent = child; /* re-write it */ + case FR_TYPE_LEAF: break; case FR_TYPE_VSA: diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index ca3396dbe4..9a8162de6f 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -413,14 +413,10 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, return PAIR_ENCODE_FATAL_ERROR; } - switch (da->type) { - case FR_TYPE_STRUCTURAL: + if (fr_type_is_structural(da->type)) { fr_strerror_printf("%s: Called with structural type %s", __FUNCTION__, fr_table_str_by_value(fr_value_box_type_table, da_stack->da[depth]->type, "?Unknown?")); return PAIR_ENCODE_FATAL_ERROR; - - default: - break; } /* @@ -957,7 +953,7 @@ static ssize_t encode_rfc_hdr_internal(fr_dbuff_t *dbuff, return PAIR_ENCODE_FATAL_ERROR; case FR_TYPE_STRUCT: - case FR_TYPE_VALUES: + case FR_TYPE_LEAF: if (((fr_dict_vendor_num_by_da(da_stack->da[depth]) == 0) && (da_stack->da[depth]->attr == 0)) || (da_stack->da[depth]->attr > 255)) { fr_strerror_printf("%s: Called with non-standard attribute %u", __FUNCTION__, -- 2.47.2