mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-27 22:52:26 +00:00
Merge pull request #16097 from opensourcerouting/fix/safety_check_for_extcommunities
bgpd: Make sure we have enough data to handle extended link bandwidth
This commit is contained in:
commit
33e01b663e
@ -1048,13 +1048,17 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt)
|
static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
||||||
|
size_t length)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
as_t as;
|
as_t as = 0;
|
||||||
uint64_t bw;
|
uint64_t bw = 0;
|
||||||
char bps_buf[20] = { 0 };
|
char bps_buf[20] = { 0 };
|
||||||
|
|
||||||
|
if (length < IPV6_ECOMMUNITY_SIZE)
|
||||||
|
goto done;
|
||||||
|
|
||||||
pnt += 2; /* Reserved */
|
pnt += 2; /* Reserved */
|
||||||
pnt = ptr_get_be64(pnt, &bw);
|
pnt = ptr_get_be64(pnt, &bw);
|
||||||
(void)ptr_get_be32(pnt, &as);
|
(void)ptr_get_be32(pnt, &as);
|
||||||
@ -1071,6 +1075,7 @@ static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt)
|
|||||||
else
|
else
|
||||||
snprintfrr(bps_buf, sizeof(bps_buf), "%" PRIu64 " bps", bw * 8);
|
snprintfrr(bps_buf, sizeof(bps_buf), "%" PRIu64 " bps", bw * 8);
|
||||||
|
|
||||||
|
done:
|
||||||
len = snprintfrr(buf, bufsz, "LB:%u:%" PRIu64 " (%s)", as, bw, bps_buf);
|
len = snprintfrr(buf, bufsz, "LB:%u:%" PRIu64 " (%s)", as, bw, bps_buf);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -1143,7 +1148,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
char encbuf[128];
|
char encbuf[128];
|
||||||
|
|
||||||
for (i = 0; i < ecom->size; i++) {
|
for (i = 0; i < ecom->size; i++) {
|
||||||
int unk_ecom = 0;
|
bool unk_ecom = false;
|
||||||
memset(encbuf, 0x00, sizeof(encbuf));
|
memset(encbuf, 0x00, sizeof(encbuf));
|
||||||
|
|
||||||
/* Space between each value. */
|
/* Space between each value. */
|
||||||
@ -1153,6 +1158,18 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
/* Retrieve value field */
|
/* Retrieve value field */
|
||||||
pnt = ecom->val + (i * ecom->unit_size);
|
pnt = ecom->val + (i * ecom->unit_size);
|
||||||
|
|
||||||
|
uint8_t *data = pnt;
|
||||||
|
uint8_t *end = data + ecom->unit_size;
|
||||||
|
size_t len = end - data;
|
||||||
|
|
||||||
|
/* Sanity check for extended communities lenght, to avoid
|
||||||
|
* overrun when dealing with bits, e.g. ptr_get_be64().
|
||||||
|
*/
|
||||||
|
if (len < ecom->unit_size) {
|
||||||
|
unk_ecom = true;
|
||||||
|
goto unknown;
|
||||||
|
}
|
||||||
|
|
||||||
/* High-order octet is the type */
|
/* High-order octet is the type */
|
||||||
type = *pnt++;
|
type = *pnt++;
|
||||||
|
|
||||||
@ -1180,14 +1197,14 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
type == ECOMMUNITY_ENCODE_AS4) {
|
type == ECOMMUNITY_ENCODE_AS4) {
|
||||||
ipv6_ecommunity_lb_str(encbuf,
|
ipv6_ecommunity_lb_str(encbuf,
|
||||||
sizeof(encbuf),
|
sizeof(encbuf),
|
||||||
pnt);
|
pnt, len);
|
||||||
} else if (sub_type == ECOMMUNITY_NODE_TARGET &&
|
} else if (sub_type == ECOMMUNITY_NODE_TARGET &&
|
||||||
type == ECOMMUNITY_ENCODE_IP) {
|
type == ECOMMUNITY_ENCODE_IP) {
|
||||||
ecommunity_node_target_str(
|
ecommunity_node_target_str(
|
||||||
encbuf, sizeof(encbuf), pnt,
|
encbuf, sizeof(encbuf), pnt,
|
||||||
format);
|
format);
|
||||||
} else
|
} else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else {
|
} else {
|
||||||
ecommunity_rt_soo_str(encbuf, sizeof(encbuf),
|
ecommunity_rt_soo_str(encbuf, sizeof(encbuf),
|
||||||
pnt, type, sub_type,
|
pnt, type, sub_type,
|
||||||
@ -1210,7 +1227,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
ecommunity_color_str(encbuf, sizeof(encbuf),
|
ecommunity_color_str(encbuf, sizeof(encbuf),
|
||||||
pnt);
|
pnt);
|
||||||
} else {
|
} else {
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
}
|
}
|
||||||
} else if (type == ECOMMUNITY_ENCODE_EVPN) {
|
} else if (type == ECOMMUNITY_ENCODE_EVPN) {
|
||||||
if (filter == ECOMMUNITY_ROUTE_TARGET)
|
if (filter == ECOMMUNITY_ROUTE_TARGET)
|
||||||
@ -1303,14 +1320,14 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
"DF: (alg: %u, pref: %u)", alg,
|
"DF: (alg: %u, pref: %u)", alg,
|
||||||
pref);
|
pref);
|
||||||
} else
|
} else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) {
|
} else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) {
|
||||||
sub_type = *pnt++;
|
sub_type = *pnt++;
|
||||||
if (sub_type == ECOMMUNITY_REDIRECT_IP_NH) {
|
if (sub_type == ECOMMUNITY_REDIRECT_IP_NH) {
|
||||||
snprintf(encbuf, sizeof(encbuf),
|
snprintf(encbuf, sizeof(encbuf),
|
||||||
"FS:redirect IP 0x%x", *(pnt + 5));
|
"FS:redirect IP 0x%x", *(pnt + 5));
|
||||||
} else
|
} else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP ||
|
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP ||
|
||||||
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 ||
|
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 ||
|
||||||
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_3) {
|
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_3) {
|
||||||
@ -1357,7 +1374,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
snprintf(encbuf, sizeof(encbuf),
|
snprintf(encbuf, sizeof(encbuf),
|
||||||
"FS:redirect VRF %s", buf);
|
"FS:redirect VRF %s", buf);
|
||||||
} else if (type != ECOMMUNITY_ENCODE_TRANS_EXP)
|
} else if (type != ECOMMUNITY_ENCODE_TRANS_EXP)
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
else if (sub_type == ECOMMUNITY_TRAFFIC_ACTION) {
|
else if (sub_type == ECOMMUNITY_TRAFFIC_ACTION) {
|
||||||
char action[64];
|
char action[64];
|
||||||
|
|
||||||
@ -1390,7 +1407,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
snprintf(encbuf, sizeof(encbuf),
|
snprintf(encbuf, sizeof(encbuf),
|
||||||
"FS:marking %u", *(pnt + 5));
|
"FS:marking %u", *(pnt + 5));
|
||||||
} else
|
} else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) {
|
} else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) {
|
||||||
sub_type = *pnt++;
|
sub_type = *pnt++;
|
||||||
if (sub_type == ECOMMUNITY_LINK_BANDWIDTH)
|
if (sub_type == ECOMMUNITY_LINK_BANDWIDTH)
|
||||||
@ -1398,28 +1415,29 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
|||||||
ecom->disable_ieee_floating);
|
ecom->disable_ieee_floating);
|
||||||
else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH)
|
else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH)
|
||||||
ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf),
|
ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf),
|
||||||
pnt);
|
pnt, len);
|
||||||
else
|
else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) {
|
} else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) {
|
||||||
sub_type = *pnt++;
|
sub_type = *pnt++;
|
||||||
if (sub_type == ECOMMUNITY_NODE_TARGET)
|
if (sub_type == ECOMMUNITY_NODE_TARGET)
|
||||||
ecommunity_node_target_str(
|
ecommunity_node_target_str(
|
||||||
encbuf, sizeof(encbuf), pnt, format);
|
encbuf, sizeof(encbuf), pnt, format);
|
||||||
else
|
else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) {
|
} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) {
|
||||||
sub_type = *pnt++;
|
sub_type = *pnt++;
|
||||||
if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE)
|
if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE)
|
||||||
ecommunity_origin_validation_state_str(
|
ecommunity_origin_validation_state_str(
|
||||||
encbuf, sizeof(encbuf), pnt);
|
encbuf, sizeof(encbuf), pnt);
|
||||||
else
|
else
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
} else {
|
} else {
|
||||||
sub_type = *pnt++;
|
sub_type = *pnt++;
|
||||||
unk_ecom = 1;
|
unk_ecom = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unknown:
|
||||||
if (unk_ecom)
|
if (unk_ecom)
|
||||||
snprintf(encbuf, sizeof(encbuf), "UNK:%d, %d", type,
|
snprintf(encbuf, sizeof(encbuf), "UNK:%d, %d", type,
|
||||||
sub_type);
|
sub_type);
|
||||||
|
Loading…
Reference in New Issue
Block a user