]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Treat combo IP address attributes as normal types
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Apr 2021 11:15:01 +0000 (12:15 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 5 Apr 2021 11:53:22 +0000 (12:53 +0100)
38 files changed:
src/bin/dhcpclient.c
src/bin/radclient.c
src/bin/radmin.c
src/bin/radsniff.c
src/bin/unit_test_attribute.c
src/lib/server/command.c
src/lib/server/cond_tokenize.c
src/lib/server/map_async.c
src/lib/server/tmpl.h
src/lib/server/tmpl_eval.c
src/lib/server/tmpl_tokenize.c
src/lib/sim/base.c
src/lib/unlang/compile.c
src/lib/unlang/tmpl.c
src/lib/unlang/xlat_builtin.c
src/lib/unlang/xlat_eval.c
src/lib/util/dict.h
src/lib/util/dict_fixup.c
src/lib/util/dict_priv.h
src/lib/util/dict_tokenize.c
src/lib/util/dict_unknown.c
src/lib/util/dict_util.c
src/lib/util/dict_validate.c
src/lib/util/pair.c
src/lib/util/struct.c
src/lib/util/types.c
src/lib/util/types.h
src/lib/util/value.c
src/lib/util/value.h
src/modules/rlm_csv/rlm_csv.c
src/modules/rlm_isc_dhcp/rlm_isc_dhcp.c
src/modules/rlm_lua/lua.c
src/modules/rlm_mruby/rlm_mruby.c
src/modules/rlm_python/rlm_python.c
src/protocols/internal/encode.c
src/protocols/radius/base.c
src/protocols/radius/decode.c
src/protocols/radius/encode.c

index 5c64c2e4745900b9235cc925ac5b5e5d5e6c30c0..ded7f6bc0a4336a2c5501b6e10fd5b4a69aa4795 100644 (file)
@@ -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);
index 428aeffcb612ff1de5f93a294f58b9e82638b9ff..c8d250a0abe781b79f99194b30c5030704b2c401 100644 (file)
@@ -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;
                                }
index 9ee54fc8a34380877c1919f39fda49a6b70c22cd..305059d809fb75efb8eb3e8252aa43aae6d44e1b 100644 (file)
@@ -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;
        }
index 923ba0002babe43e46c8cd00b70db4f679d660e7..641f2fe9acfc524c76dfb6eba5737a82f68920ce 100644 (file)
@@ -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;
                        }
index 875c677617122c716617236c18b6345010af3a69..0333bde11f517ca1577a299185e0a5b817e2017e 100644 (file)
@@ -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();
index 26ea204514b1b40495aa87086349a4a9bbb0cd5e..6d7bf0ffa6e87baab3b557e66557642776ccad48 100644 (file)
@@ -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;
index 2399cb481e773905ae300734081b1222ebe12d0b..2f5cd0de51b65f65d6ad14377d1e247bc929ec92 100644 (file)
@@ -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:
index 1d8b11c220fb01d81ee01c678711077dffb3997d..849f4ffc9abda274dbe3268c190b3edf85499284 100644 (file)
@@ -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);
index 4f53e926a34c4940201c9f216919531e82954284..597d45464baee853a6498e3803615e802588cb47 100644 (file)
@@ -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,
index dba88026230f52b76b58070735d51d083acc8aa2..92166fbf98cf1714b1b079e0fd8ee83e905ecf83 100644 (file)
@@ -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;
 
index fd4d0f21f344efd8528edca57e5fd72375e5eb8a..b5906dc6507ae7a1d8e006246a4aeb19b405fa64 100644 (file)
@@ -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, "<INVALID>"));
-               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, "<INVALID>"),
-                                  fr_table_str_by_value(fr_value_box_type_table, type, "<INVALID>"));
-               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, "<INVALID>"),
-                                                            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");
                }
 
index 3a2c7576559e2fab5eee86013824e617e07011fe..5f84a88ff9724ac0d57d34e1869aaadcfa207fdf 100644 (file)
@@ -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;
        }
 }
 
index cea14344f055f0d9db91dafe5afb02f84e38bffa..52d8b36267ed7bdfdf00c494c24c6e7537725a96 100644 (file)
@@ -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, "<INVALID>"));
                        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, "<INVALID>"));
                        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;
index 6358ce1e2d61e5da71c31cf4e55b9c958bef1826..cd2d6bdb6c9bc017757997ff59dd1f3947f49d5f 100644 (file)
@@ -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);
index 95437b636238a3d6d16a6ff4cb6064c7a22ef5f7..05de5e65c30c267278031caec44178b03a34ff47 100644 (file)
@@ -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, "<INVALID>"));
 
-               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:
index 7aa23cdc0d8bbc89b965458df13959c8f3ced841..f6b96fae181acb6ca3b8744f8212b77b7bc48378 100644 (file)
@@ -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;
index f49c3bf668c6e543f1591ebc98de0d55681770f3..b57c294c8b9b60aefba9818df67645c3e397a224 100644 (file)
@@ -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);
index 82bb5c6283d14e504c6123124b7a551b3809015c..33514cc8c6b77aa163c094952ac6042d9403e70a 100644 (file)
@@ -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;
 }
index 1e132e022f129b2adfee1aab5ee4596d00d5c9a2..ee7fe1007490f6f4cb6209168cb274cc006590e1 100644 (file)
@@ -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,
index 2e5a7d3df63ef25c186291e8006ca420edfe2cbc..d7f4914deb7b4f185466fef4ff5f71e4973626be 100644 (file)
@@ -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;
index f4030e3e12984b6ab26bbc8d6d6030c403f2527a..a76f39ae6e538eb5c93807ee9ef0cde257d2dadb 100644 (file)
@@ -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,
index 5b72e6edc9bb886a681a4e16a504bc61f86ef671..8a36b854e78d3797ca6f182849daf534d67ee14a 100644 (file)
@@ -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.
         */
index 7f5630ed72a516902b3de2b0e96d4cbec58eb5d2..d5311b772e9b2e648a217ff4ee0c16464ecb3500 100644 (file)
@@ -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:
index 0277d30d3b9ed66af617335100349501fade86b8..81535166f1db8971901066ab3827d9987bf8940d 100644 (file)
@@ -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, "<INVALID>"));
+                                  fr_table_str_by_value(fr_value_box_type_table, vp->da->type, "<INVALID>"));
                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, "<INVALID>"), 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, "<INVALID>"));
-                       }
-               }
-
                if (da != vp->da) {
                        fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: fr_pair_t "
                                             "dictionary pointer %p \"%s\" (%s) "
index 48574bd180e84bdf4737ade830e831dfa891f70d..1d17bee355d8d9c11daa44110f14983218238483 100644 (file)
@@ -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;
                }
 
index ec092bc65c581bb9907ceb87948071a8b60a5321..fda81d3d595ef0698e9738f45c8b3c6ba1418b87 100644 (file)
@@ -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:
index 07cb450c250a7b8b36d1e4fb02af8e076514f3a5..ab9876d80edb5d84975ba4b4464cfdd63cca08d8 100644 (file)
@@ -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);
index 8cd93734a1c8c7a1780ad472f52020f0cd55776f..67b719df0cfe7aacc0e90a588705157e84b1120b 100644 (file)
@@ -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, "<INVALID>"));
                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, "<INVALID>"),
                                   fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"));
@@ -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, "<INVALID>"));
+                                  fr_table_str_by_value(fr_value_box_type_table, dst_type, "<INVALID>"));
                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:
index 27a91c93b2140750d2d123fcaafbe7c722f161e7..3468a13c08a4831a9ecc7e1c901657c812e6813d 100644 (file)
@@ -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
index fe51b3a753406b6bb1b115ba77e595759c9477f8..a6b188369604d193823e339d81ff226392ae8c89 100644 (file)
@@ -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:
index efc8cd848031ac88c3b2febf5e0a113c28c0d4bb..90fa0c9609615042827cda4a6a7ecd2f32229f29 100644 (file)
@@ -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;
 
index c3543941ebcf5ff5c88579a417ca6f0b3a5a6c5e..b53c7f19239e14ecaaf08e2779ac27f755e2c79a 100644 (file)
@@ -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, "<INVALID>"));
                return -1;
        }
index df4b52d1cfd8147b66bdb82e62dfc6c27ce025bd..712c205f5e9e68a2c33d11c6f0c27463d6fd4b9b 100644 (file)
@@ -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;
                }
index 5c3dd988a76c93ac7f5e714c467f8de402f45f96..e25b6c45d15deca84d0e495e2aad2f9920972e3d 100644 (file)
@@ -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;
        }
index c4b00cb9bcf8d5f1448719950fe559724e40be8f..a0e7d51bef9cbc8ada987363755a5e0e4779b8cf 100644 (file)
@@ -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",
index 9006d679b02ba868efee5d8ff9439eef66049e85..7e915a57e9f1ce54c138c2d36be6be3e05ce2f30 100644 (file)
@@ -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];
        }
 }
 
index 546b8db50788ed0c51cadc32c6ee87f71617bc7e..6992a733bafb227d36a94fa06c0c55c0a71bf0d9 100644 (file)
@@ -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:
index ca3396dbe46e2cbdd5ebcfd40a4007e54737a24a..9a8162de6fe224ebe6159cef555462d907c3364a 100644 (file)
@@ -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__,