]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
coalesce VENDOR attributes at the same level
authorAlan T. DeKok <aland@freeradius.org>
Wed, 6 Sep 2023 14:09:36 +0000 (10:09 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 6 Sep 2023 14:09:36 +0000 (10:09 -0400)
src/protocols/dhcpv4/decode.c
src/protocols/dhcpv4/encode.c
src/tests/unit/protocols/dhcpv4/vendor.txt

index da4ebb5143e9c25943be1f7511ebb2695a21bd64..c644045a2ee2febb0e288a18a5265b552075d3f3 100644 (file)
@@ -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;
index e1e10fbfff1c60ca530064d51d0eedd8a6fbd6f5..980d160fbc1c9e2caf616bcfe24dd8e4d68fdaae 100644 (file)
@@ -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);
 
index 63396f0c655fedbe7ad9088957248fe48e4185d8..fffa47b5a61d8e8863f34925c7f5b9379afdcf16 100644 (file)
@@ -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