mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 07:37:29 +00:00
Merge pull request #14214 from opensourcerouting/fix/handle_rfc7606_attr_len_remaining_data
bgpd: Treat-as-withdraw attribute if remaining data is not enough
This commit is contained in:
commit
020d8488cf
@ -3461,8 +3461,24 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
|
|||||||
|
|
||||||
/* Get attributes to the end of attribute length. */
|
/* Get attributes to the end of attribute length. */
|
||||||
while (BGP_INPUT_PNT(peer) < endp) {
|
while (BGP_INPUT_PNT(peer) < endp) {
|
||||||
|
startp = BGP_INPUT_PNT(peer);
|
||||||
|
|
||||||
|
/* Fewer than three octets remain (or fewer than four
|
||||||
|
* octets, if the Attribute Flags field has the Extended
|
||||||
|
* Length bit set) when beginning to parse the attribute.
|
||||||
|
* That is, this case exists if there remains unconsumed
|
||||||
|
* data in the path attributes but yet insufficient data
|
||||||
|
* to encode a single minimum-sized path attribute.
|
||||||
|
*
|
||||||
|
* An error condition exists and the "treat-as-withdraw"
|
||||||
|
* approach MUST be used (unless some other, more severe
|
||||||
|
* error is encountered dictating a stronger approach),
|
||||||
|
* and the Total Attribute Length MUST be relied upon to
|
||||||
|
* enable the beginning of the NLRI field to be located.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Check remaining length check.*/
|
/* Check remaining length check.*/
|
||||||
if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
|
if ((endp - startp) < BGP_ATTR_MIN_LEN) {
|
||||||
/* XXX warning: long int format, int arg (arg 5) */
|
/* XXX warning: long int format, int arg (arg 5) */
|
||||||
flog_warn(
|
flog_warn(
|
||||||
EC_BGP_ATTRIBUTE_TOO_SMALL,
|
EC_BGP_ATTRIBUTE_TOO_SMALL,
|
||||||
@ -3471,17 +3487,22 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
|
|||||||
(unsigned long)(endp
|
(unsigned long)(endp
|
||||||
- stream_pnt(BGP_INPUT(peer))));
|
- stream_pnt(BGP_INPUT(peer))));
|
||||||
|
|
||||||
|
if (peer->sort != BGP_PEER_EBGP) {
|
||||||
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
|
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
|
||||||
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
|
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
|
||||||
ret = BGP_ATTR_PARSE_ERROR;
|
ret = BGP_ATTR_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
ret = BGP_ATTR_PARSE_WITHDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch attribute flag and type. */
|
/* Fetch attribute flag and type.
|
||||||
startp = BGP_INPUT_PNT(peer);
|
* The lower-order four bits of the Attribute Flags octet are
|
||||||
/* "The lower-order four bits of the Attribute Flags octet are
|
* unused. They MUST be zero when sent and MUST be ignored when
|
||||||
unused. They MUST be zero when sent and MUST be ignored when
|
* received.
|
||||||
received." */
|
*/
|
||||||
flag = 0xF0 & stream_getc(BGP_INPUT(peer));
|
flag = 0xF0 & stream_getc(BGP_INPUT(peer));
|
||||||
type = stream_getc(BGP_INPUT(peer));
|
type = stream_getc(BGP_INPUT(peer));
|
||||||
|
|
||||||
@ -3495,9 +3516,14 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
|
|||||||
(unsigned long)(endp
|
(unsigned long)(endp
|
||||||
- stream_pnt(BGP_INPUT(peer))));
|
- stream_pnt(BGP_INPUT(peer))));
|
||||||
|
|
||||||
|
if (peer->sort != BGP_PEER_EBGP) {
|
||||||
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
|
bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
|
||||||
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
|
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
|
||||||
ret = BGP_ATTR_PARSE_ERROR;
|
ret = BGP_ATTR_PARSE_ERROR;
|
||||||
|
} else {
|
||||||
|
ret = BGP_ATTR_PARSE_WITHDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user