diff options
| author | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-10-29 22:44:45 +0200 |
|---|---|---|
| committer | Donatas Abraitis <donatas@opensourcerouting.org> | 2023-10-31 17:22:00 +0200 |
| commit | c37119df45bbf4ef713bc10475af2ee06e12f3bf (patch) | |
| tree | 56d0bc880f64cfb61425587d47702bb8fb1de665 /bgpd/bgp_attr.c | |
| parent | 6814f2e0138a6ea5e1f83bdd9085d9a77999900b (diff) | |
bgpd: Ignore handling NLRIs if we received MP_UNREACH_NLRI
If we receive MP_UNREACH_NLRI, we should stop handling remaining NLRIs if
no mandatory path attributes received.
In other words, if MP_UNREACH_NLRI received, the remaining NLRIs should be handled
as a new data, but without mandatory attributes, it's a malformed packet.
In normal case, this MUST not happen at all, but to avoid crashing bgpd, we MUST
handle that.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_attr.c')
| -rw-r--r-- | bgpd/bgp_attr.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 1473dc7725..75aa2ac7cc 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -3399,15 +3399,6 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr, !length) return BGP_ATTR_PARSE_WITHDRAW; - /* "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 ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && - CHECK_FLAG(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; @@ -3426,6 +3417,16 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr, && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) type = BGP_ATTR_LOCAL_PREF; + /* 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 (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && + CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) + return type ? BGP_ATTR_PARSE_MISSING_MANDATORY + : BGP_ATTR_PARSE_PROCEED; + /* If any of the well-known mandatory attributes are not present * in an UPDATE message, then "treat-as-withdraw" MUST be used. */ |
