From: Alan T. DeKok Date: Wed, 6 Sep 2023 14:09:36 +0000 (-0400) Subject: coalesce VENDOR attributes at the same level X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b9cbbe3d8b3c8745b2654dd9b1f400df555c27d;p=thirdparty%2Ffreeradius-server.git coalesce VENDOR attributes at the same level --- diff --git a/src/protocols/dhcpv4/decode.c b/src/protocols/dhcpv4/decode.c index da4ebb5143e..c644045a2ee 100644 --- a/src/protocols/dhcpv4/decode.c +++ b/src/protocols/dhcpv4/decode.c @@ -349,6 +349,7 @@ static ssize_t decode_vsa(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t c ssize_t len; uint8_t option_len; uint32_t pen; + fr_pair_t *vp; fr_dict_attr_t const *vendor; uint8_t const *end = data + data_len; uint8_t const *p = data; @@ -403,8 +404,16 @@ next: } p++; + vp = fr_pair_find_by_da(out, NULL, vendor); + if (!vp) { + vp = fr_pair_afrom_da(ctx, vendor); + if (!vp) return PAIR_DECODE_FATAL_ERROR; + + fr_pair_append(out, vp); + } + /* coverity[tainted_data] */ - len = fr_pair_tlvs_from_network(ctx, out, vendor, p, option_len, decode_ctx, decode_option, verify_tlvs, true); + len = fr_pair_tlvs_from_network(vp, &vp->vp_group, vendor, p, option_len, decode_ctx, decode_option, verify_tlvs, false); if (len <= 0) return len; p += len; diff --git a/src/protocols/dhcpv4/encode.c b/src/protocols/dhcpv4/encode.c index e1e10fbfff1..980d160fbc1 100644 --- a/src/protocols/dhcpv4/encode.c +++ b/src/protocols/dhcpv4/encode.c @@ -661,13 +661,32 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff, } /* - * We go here via a flat attribute, so the da_stack has a - * vendor next, followed by the vendor attributes. + * We are at the VSA. The next entry in the stack is the vendor. The entry after that is the vendor data. */ if (da_stack->da[depth + 1]) { - fr_assert(da_stack->da[depth + 2] != NULL); + ssize_t len; + fr_dcursor_t vsa_cursor; + + if (da_stack->da[depth + 2]) { + return encode_vsio_data(dbuff, da_stack, depth + 2, cursor, encode_ctx); + } + + vp = fr_dcursor_current(cursor); + fr_assert(vp->vp_type == FR_TYPE_VENDOR); + + /* + * Copied from below. + */ + fr_pair_dcursor_init(&vsa_cursor, &vp->vp_group); + work_dbuff = FR_DBUFF(dbuff); + + while ((vp = fr_dcursor_current(&vsa_cursor)) != NULL) { + fr_proto_da_stack_build(da_stack, vp->da); + len = encode_vsio_data(&work_dbuff, da_stack, depth + 2, &vsa_cursor, encode_ctx); + if (len <= 0) return len; + } - return encode_vsio_data(dbuff, da_stack, depth + 2, cursor, encode_ctx); + goto done; } vp = fr_dcursor_current(cursor); @@ -687,7 +706,7 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff, fr_pair_dcursor_init(&vsa_cursor, &vp->vp_group); - if ((vp = fr_dcursor_current(&vsa_cursor)) != NULL) { + while ((vp = fr_dcursor_current(&vsa_cursor)) != NULL) { /* * RFC 3925 Section 4 says: * @@ -711,6 +730,7 @@ static ssize_t encode_vsio(fr_dbuff_t *dbuff, /* * Skip over the attribute we just encoded. */ +done: vp = fr_dcursor_next(cursor); fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); diff --git a/src/tests/unit/protocols/dhcpv4/vendor.txt b/src/tests/unit/protocols/dhcpv4/vendor.txt index 63396f0c655..fffa47b5a61 100644 --- a/src/tests/unit/protocols/dhcpv4/vendor.txt +++ b/src/tests/unit/protocols/dhcpv4/vendor.txt @@ -12,7 +12,10 @@ decode-pair - match V-I-Vendor-Specific.Cisco = { Indirect-Image-Filename = "aa.txt" } decode-pair 7d 1a 00 00 00 09 08 05 06 61 61 2e 74 78 74 00 00 00 09 08 05 06 62 62 2e 74 78 74 -match V-I-Vendor-Specific.Cisco = { Indirect-Image-Filename = "aa.txt" }, V-I-Vendor-Specific.Cisco = { Indirect-Image-Filename = "bb.txt" } +match V-I-Vendor-Specific.Cisco = { Indirect-Image-Filename = "aa.txt", Indirect-Image-Filename = "bb.txt" } + +encode-pair - +match 7d 15 00 00 00 09 10 05 06 61 61 2e 74 78 74 05 06 62 62 2e 74 78 74 encode-pair V-I-Vendor-Specific.Cisco.Indirect-Image-Filename = "aa.txt", V-I-Vendor-Specific.Cisco.Indirect-Image-Filename = "bb.txt" match 7d 15 00 00 00 09 10 05 06 61 61 2e 74 78 74 05 06 62 62 2e 74 78 74 @@ -27,4 +30,4 @@ decode-pair 7d 0d 00 00 00 09 09 05 06 61 61 2e 74 78 74 match raw.V-I-Vendor-Specific.Cisco = 0x09050661612e747874 count -match 15 +match 17