mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 12:41:21 +00:00
bgpd: Treat empty reachable NLRI as a EOR
This issue was discovered on a live session with an extremely old cisco 7206VXR router running 12.2(33)SRE4. The sending router is sending us an empty NLRI that is MP_REACH. From RFC exploration(thanks Russ!) it appears that this was considered a 'valid' way to send EOR. Following discussion decided that we should treat this situation as a EOR marker instead of bringing down the session. Applying this fix on the FRR router seeing this issue allows it to continue it's peering relationship with the ASR. Since this is a point fix I do not see a high likelihood of further fallout. Fixes: #1258 Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
6d774763d6
commit
9b9df9892d
@ -1709,11 +1709,20 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
|
|||||||
|
|
||||||
/* must have nrli_len, what is left of the attribute */
|
/* must have nrli_len, what is left of the attribute */
|
||||||
nlri_len = LEN_LEFT;
|
nlri_len = LEN_LEFT;
|
||||||
if ((!nlri_len) || (nlri_len > STREAM_READABLE(s))) {
|
if (nlri_len > STREAM_READABLE(s)) {
|
||||||
zlog_info("%s: (%s) Failed to read NLRI", __func__, peer->host);
|
zlog_info("%s: (%s) Failed to read NLRI", __func__, peer->host);
|
||||||
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
|
return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nlri_len) {
|
||||||
|
zlog_info("%s: (%s) No Reachability, Treating as a EOR marker",
|
||||||
|
__func__, peer->host);
|
||||||
|
|
||||||
|
mp_update->afi = afi;
|
||||||
|
mp_update->safi = safi;
|
||||||
|
return BGP_ATTR_PARSE_EOR;
|
||||||
|
}
|
||||||
|
|
||||||
mp_update->afi = afi;
|
mp_update->afi = afi;
|
||||||
mp_update->safi = safi;
|
mp_update->safi = safi;
|
||||||
mp_update->nlri = stream_pnt(s);
|
mp_update->nlri = stream_pnt(s);
|
||||||
@ -2378,6 +2387,12 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
|
|||||||
ret = BGP_ATTR_PARSE_ERROR;
|
ret = BGP_ATTR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == BGP_ATTR_PARSE_EOR) {
|
||||||
|
if (as4_path)
|
||||||
|
aspath_unintern(&as4_path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* If hard error occured immediately return to the caller. */
|
/* If hard error occured immediately return to the caller. */
|
||||||
if (ret == BGP_ATTR_PARSE_ERROR) {
|
if (ret == BGP_ATTR_PARSE_ERROR) {
|
||||||
zlog_warn("%s: Attribute %s, parse error", peer->host,
|
zlog_warn("%s: Attribute %s, parse error", peer->host,
|
||||||
|
@ -227,6 +227,7 @@ typedef enum {
|
|||||||
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
|
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
|
||||||
*/
|
*/
|
||||||
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
|
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
|
||||||
|
BGP_ATTR_PARSE_EOR = -4,
|
||||||
} bgp_attr_parse_ret_t;
|
} bgp_attr_parse_ret_t;
|
||||||
|
|
||||||
struct bpacket_attr_vec_arr;
|
struct bpacket_attr_vec_arr;
|
||||||
|
@ -1553,7 +1553,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
|
|||||||
* Non-MP IPv4/Unicast EoR is a completely empty UPDATE
|
* Non-MP IPv4/Unicast EoR is a completely empty UPDATE
|
||||||
* and MP EoR should have only an empty MP_UNREACH
|
* and MP EoR should have only an empty MP_UNREACH
|
||||||
*/
|
*/
|
||||||
if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) {
|
if ((!update_len && !withdraw_len &&
|
||||||
|
nlris[NLRI_MP_UPDATE].length == 0) ||
|
||||||
|
(attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
|
||||||
afi_t afi = 0;
|
afi_t afi = 0;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
@ -1568,6 +1570,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
|
|||||||
&& nlris[NLRI_MP_WITHDRAW].length == 0) {
|
&& nlris[NLRI_MP_WITHDRAW].length == 0) {
|
||||||
afi = nlris[NLRI_MP_WITHDRAW].afi;
|
afi = nlris[NLRI_MP_WITHDRAW].afi;
|
||||||
safi = nlris[NLRI_MP_WITHDRAW].safi;
|
safi = nlris[NLRI_MP_WITHDRAW].safi;
|
||||||
|
} else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
|
||||||
|
afi = nlris[NLRI_MP_UPDATE].afi;
|
||||||
|
safi = nlris[NLRI_MP_UPDATE].safi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afi && peer->afc[afi][safi]) {
|
if (afi && peer->afc[afi][safi]) {
|
||||||
|
Loading…
Reference in New Issue
Block a user