From: Alan T. DeKok Date: Wed, 15 Mar 2023 18:27:55 +0000 (-0400) Subject: define, encode, and decode additional data after a BFD packet. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae4db302839fb73feeff99f17343a276130516b7;p=thirdparty%2Ffreeradius-server.git define, encode, and decode additional data after a BFD packet. --- diff --git a/share/dictionary/bfd/dictionary.freeradius.internal b/share/dictionary/bfd/dictionary.freeradius.internal index 268fda12f1a..a1326e5d4c5 100644 --- a/share/dictionary/bfd/dictionary.freeradius.internal +++ b/share/dictionary/bfd/dictionary.freeradius.internal @@ -25,7 +25,6 @@ VALUE Packet-Type Init 2 VALUE Packet-Type Up 3 # -# This is our version of our current link state, which is copied -# to the request packet. +# Additional data which gets added to the end of the BFD packet. # -DEFINE Link-State uint32 enum=Packet-Type +DEFINE Additional-Data group diff --git a/src/listen/bfd/proto_bfd.c b/src/listen/bfd/proto_bfd.c index 7bf264d2d2c..6de6be3723f 100644 --- a/src/listen/bfd/proto_bfd.c +++ b/src/listen/bfd/proto_bfd.c @@ -68,12 +68,10 @@ static fr_dict_attr_t const *attr_packet_type; static fr_dict_attr_t const *attr_bfd_packet; static fr_dict_attr_t const *attr_my_discriminator; static fr_dict_attr_t const *attr_your_discriminator; -static fr_dict_attr_t const *attr_link_state; extern fr_dict_attr_autoload_t proto_bfd_dict_attr[]; fr_dict_attr_autoload_t proto_bfd_dict_attr[] = { { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_bfd}, - { .out = &attr_link_state, .name = "Link-State", .type = FR_TYPE_UINT32, .dict = &dict_bfd}, { .out = &attr_bfd_packet, .name = "Packet", .type = FR_TYPE_STRUCT, .dict = &dict_bfd}, { .out = &attr_my_discriminator, .name = "Packet.my-discriminator", .type = FR_TYPE_UINT32, .dict = &dict_bfd}, diff --git a/src/protocols/bfd/attrs.h b/src/protocols/bfd/attrs.h index 46dd09e0147..fb9f9622bf1 100644 --- a/src/protocols/bfd/attrs.h +++ b/src/protocols/bfd/attrs.h @@ -32,3 +32,4 @@ extern HIDDEN fr_dict_t const *dict_bfd; extern HIDDEN fr_dict_attr_t const *attr_packet_type; extern HIDDEN fr_dict_attr_t const *attr_bfd_packet; +extern HIDDEN fr_dict_attr_t const *attr_bfd_additional_data; diff --git a/src/protocols/bfd/base.c b/src/protocols/bfd/base.c index 9b76cd14436..d3b38cbefbf 100644 --- a/src/protocols/bfd/base.c +++ b/src/protocols/bfd/base.c @@ -49,11 +49,13 @@ fr_dict_autoload_t libfreeradius_bfd_dict[] = { fr_dict_attr_t const *attr_packet_type; fr_dict_attr_t const *attr_bfd_packet; +fr_dict_attr_t const *attr_bfd_additional_data; extern fr_dict_attr_autoload_t libfreeradius_bfd_dict_attr[]; fr_dict_attr_autoload_t libfreeradius_bfd_dict_attr[] = { { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_bfd }, { .out = &attr_bfd_packet, .name = "Packet", .type = FR_TYPE_STRUCT, .dict = &dict_bfd }, + { .out = &attr_bfd_additional_data, .name = "Additional-Data", .type = FR_TYPE_GROUP, .dict = &dict_bfd }, { NULL } }; diff --git a/src/protocols/bfd/decode.c b/src/protocols/bfd/decode.c index 6d904f8e5d2..44a26e5330c 100644 --- a/src/protocols/bfd/decode.c +++ b/src/protocols/bfd/decode.c @@ -26,7 +26,7 @@ RCSID("$Id$") #include #include -#include +#include #include "attrs.h" @@ -67,13 +67,35 @@ ssize_t fr_bfd_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, { ssize_t slen; fr_bfd_ctx_t packet_ctx; + bfd_packet_t const *bfd; + fr_pair_t *vp; + fr_dbuff_t dbuff; packet_ctx.secret = secret; - slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, packet_len, true, + bfd = (bfd_packet_t const *) packet; + + slen = fr_struct_from_network(ctx, out, attr_bfd_packet, packet, bfd->length, true, &packet_ctx, decode_value, NULL); if (slen < 0) return slen; + if (bfd->length == packet_len) return packet_len; + + /* + * Try to decode additional data. + */ + vp = fr_pair_afrom_da(ctx, attr_bfd_additional_data); + if (!vp) return packet_len; + + fr_dbuff_init(&dbuff, packet + slen, packet_len - slen); + + if ((fr_internal_decode_list_dbuff(vp, &vp->vp_group, fr_dict_root(dict_bfd), &dbuff, NULL) < 0) || + (fr_pair_list_num_elements(&vp->vp_group) == 0)) { + TALLOC_FREE(vp); + } else { + fr_pair_append(out, vp); + } + return slen; } diff --git a/src/protocols/bfd/encode.c b/src/protocols/bfd/encode.c index 44589f67374..5494d908c3d 100644 --- a/src/protocols/bfd/encode.c +++ b/src/protocols/bfd/encode.c @@ -25,9 +25,10 @@ RCSID("$Id$") #include -#include #include #include +#include + #include "attrs.h" /** Encodes the data portion of an attribute @@ -186,7 +187,9 @@ static int encode_test_ctx(void **out, TALLOC_CTX *ctx) static ssize_t fr_bfd_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, void *proto_ctx) { fr_bfd_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_bfd_ctx_t); - ssize_t slen; + ssize_t slen, alen; + fr_pair_t *vp; + fr_dbuff_t dbuff; /* * @todo - pass in test_ctx to this function, so that we @@ -195,7 +198,14 @@ static ssize_t fr_bfd_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, slen = fr_bfd_encode(data, data_len, NULL, test_ctx->secret, talloc_array_length(test_ctx->secret) - 1, vps); if (slen <= 0) return slen; - return slen; + vp = fr_pair_find_by_da(vps, NULL, attr_bfd_additional_data); + if (!vp) return slen; + + fr_dbuff_init(&dbuff, data + slen, data_len - slen); + alen = fr_internal_encode_list(&dbuff, &vp->vp_group, NULL); + if (alen <= 0) return slen; + + return slen + alen; } /* diff --git a/src/tests/unit/protocols/bfd/base.txt b/src/tests/unit/protocols/bfd/base.txt index ce015719024..2e17177f49d 100644 --- a/src/tests/unit/protocols/bfd/base.txt +++ b/src/tests/unit/protocols/bfd/base.txt @@ -15,5 +15,17 @@ match 20 c0 03 18 de ad be ef 21 12 68 09 00 00 00 1f 00 00 00 7f 00 00 00 ff decode-proto - match Packet-Type = Up, Packet = { version = 1, diagnostic = none, state = up, poll = no, final = no, control-plane-independent = no, auth-present = no, demand = no, multipoint = no, detect-multi = 3, length = 24, my-discriminator = 3735928559, your-discriminator = 554854409, desired-min-tx-interval = 31, required-min-tx-interval = 127, required-min-echo-interval = 255 } + +# +# And with additional data. +# +# The BFD packet is exactly the same, but we also have a 3 octet string "foo", which is encoded via the internal dictionary, after the packet. +# +encode-proto Packet = { version = 1, diagnostic = none, state = up, poll = false, final = false, control-plane-independent = false, auth-present = false, demand = false, multipoint = false, detect-multi = 3, my-discriminator = 0xdeadbeef, your-discriminator = 0x21126809, desired-min-tx-interval = 31us, required-min-tx-interval = 127us, required-min-echo-interval = 255us }, Additional-Data = { Tmp-String-0 = "foo" } +match 20 c0 03 18 de ad be ef 21 12 68 09 00 00 00 1f 00 00 00 7f 00 00 00 ff 21 40 06 ae 03 66 6f 6f + +decode-proto - +match Packet-Type = Up, Packet = { version = 1, diagnostic = none, state = up, poll = no, final = no, control-plane-independent = no, auth-present = no, demand = no, multipoint = no, detect-multi = 3, length = 24, my-discriminator = 3735928559, your-discriminator = 554854409, desired-min-tx-interval = 31, required-min-tx-interval = 127, required-min-echo-interval = 255 }, Additional-Data = { Tmp-String-0 = "foo" } + count -match 7 +match 11