From 67495ddb2e5b1ed267966dcae938c4a30081a75d Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Tue, 21 Oct 2014 16:59:01 +0100 Subject: [PATCH] bgpd: Fixes for recent well-known-attr check patch. * bgp_attr.c: Recent patch to tighten well-known attr checks and apply that to all AFIs has some breakage with MP-extensions and GR, which needs to be fixed. (bgp_attr_check) Graceful Restart EoR can be an empty UPDATE for IPv4/uni. MP-Ext allow UPDATE with just MP_UNREACH_NLRI. Check for these and return proceed. NEXT_HOP becomes optional, if MP_REACH_NLRI is present and there's no v4 NLTI, update NEXT_HOP check accordingly. Print the missing attr in string form in the log message. (bgp_attr_parse) AS_PATH need not be there, so bgp_attr_munge_as4_attrs call needs to be conditional on that. (cherry picked from commit aed1b556cf2f55680ae09d7ad1a1f22729dea8c5) Conflicts: bgpd/bgp_attr.c --- bgpd/bgp_attr.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 646d16200f..a151ae3cf9 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1821,6 +1821,19 @@ bgp_attr_check (struct peer *peer, struct attr *attr, bgp_size_t nlri_len) { u_char type = 0; + /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an + * empty UPDATE. */ + if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag) + return BGP_ATTR_PARSE_PROCEED; + + /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required + to carry any other path attributes.", though if MP_REACH_NLRI or NLRI + are present, it should. Check for any other attribute being present + instead. + */ + if (attr->flag == ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI)) + return BGP_ATTR_PARSE_PROCEED; + if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN))) type = BGP_ATTR_ORIGIN; @@ -2113,10 +2126,14 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, * So, to be defensive, we are not relying on any order and read * all attributes first, including these 32bit ones, and now, * afterwards, we look what and if something is to be done for as4. + * + * It is possible to not have AS_PATH, e.g. GR EoR and sole + * MP_UNREACH_NLRI. */ /* actually... this doesn't ever return failure currently, but * better safe than sorry */ - if (bgp_attr_munge_as4_attrs (peer, attr, as4_path, + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH)) + && bgp_attr_munge_as4_attrs (peer, attr, as4_path, as4_aggregator, &as4_aggregator_addr)) { bgp_notify_send (peer, -- 2.39.5