Skip to content

Commit f467e95

Browse files
authored
Merge pull request #20222 from opensourcerouting/fix/backport_sw_version_capability_10.4
bgpd: Handle new encoding for software version capability (backport)
2 parents 46a97e8 + 773877d commit f467e95

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

bgpd/bgp_open.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,11 +971,22 @@ static int bgp_capability_software_version(struct peer *peer,
971971
struct capability_header *hdr)
972972
{
973973
struct stream *s = BGP_INPUT(peer);
974+
struct stream *dup = stream_dup(s);
974975
char str[BGP_MAX_SOFT_VERSION + 1];
975976
size_t end = stream_get_getp(s) + hdr->length;
976-
uint8_t len;
977+
uint8_t len = hdr->length;
978+
uint8_t cap_value_len_field = stream_getc(dup) + 1;
979+
980+
/* For backward compatibility.
981+
* Older draft versions defined the length field inside
982+
* the capability's value. Newer versions use just the capability's
983+
* length which is hdr->length.
984+
*/
985+
if (cap_value_len_field == len)
986+
len = stream_getc(s);
987+
988+
stream_free(dup);
977989

978-
len = stream_getc(s);
979990
if (stream_get_getp(s) + len > end) {
980991
flog_warn(
981992
EC_BGP_CAPABILITY_INVALID_DATA,

bgpd/bgp_packet.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3693,16 +3693,33 @@ static void bgp_dynamic_capability_software_version(uint8_t *pnt, int action,
36933693
{
36943694
uint8_t *data = pnt + 3;
36953695
uint8_t *end = data + hdr->length;
3696-
uint8_t len = *data;
3696+
uint8_t len = hdr->length;
3697+
uint8_t cap_value_len_field = *data + 1;
36973698
char soft_version[BGP_MAX_SOFT_VERSION + 1] = {};
36983699

36993700
if (action == CAPABILITY_ACTION_SET) {
3700-
if (data + len + 1 > end) {
3701-
zlog_err("%pBP: Received invalid Software Version capability length %d",
3702-
peer, len);
3703-
return;
3701+
/* For backward compatibility.
3702+
* Older draft versions defined the length field inside
3703+
* the capability's value. Newer versions use just the
3704+
* capability's length which is hdr->length.
3705+
*/
3706+
if (cap_value_len_field == len) {
3707+
len = *data;
3708+
3709+
if (data + len + 1 > end) {
3710+
zlog_err("%pBP: Received invalid Software Version capability length %d",
3711+
peer, len);
3712+
return;
3713+
}
3714+
3715+
data++;
3716+
} else {
3717+
if (data + len > end) {
3718+
zlog_err("%pBP: Received invalid Software Version capability length %d",
3719+
peer, len);
3720+
return;
3721+
}
37043722
}
3705-
data++;
37063723

37073724
if (len > BGP_MAX_SOFT_VERSION)
37083725
len = BGP_MAX_SOFT_VERSION;

0 commit comments

Comments
 (0)