bgpd: add missing "partial" flag checks (BZ#676)

ORIGIN handling function used to have "partial" bit check and recent
commits added it for NEXT_HOP, MULTI_EXIT_DISC and ATOMIC_AGGREGATE
cases. This commit adds "partial" check for AS_PATH and LOCAL_PREF
cases, which should leave attributes 1 through 6 inclusive completely
covered with attribute flags checks.

* bgp_attr.c
  * bgp_attr_origin(): use bit-by-bit checks for better diagnostics
  * bgp_attr_aspath(): add flag check
  * bgp_attr_local_pref(): idem

Conflicts:

	bgpd/bgp_attr.c
This commit is contained in:
Denis Ovsienko 2011-09-24 13:20:43 +04:00
parent bc3443ebf0
commit 214bcaa13e

View File

@ -773,14 +773,30 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length,
with the Attribute Type Code, then the Error Subcode is set to with the Attribute Type Code, then the Error Subcode is set to
Attribute Flags Error. The Data field contains the erroneous Attribute Flags Error. The Data field contains the erroneous
attribute (type, length and value). */ attribute (type, length and value). */
if (flag != BGP_ATTR_FLAG_TRANS) if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
{ {
zlog (peer->log, LOG_ERR, zlog (peer->log, LOG_ERR,
"Origin attribute flag isn't transitive %d", flag); "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag);
return bgp_attr_malformed (peer, BGP_ATTR_ORIGIN, flag, return bgp_attr_malformed (peer, BGP_ATTR_ORIGIN, flag,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total); startp, total);
} }
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
{
zlog (peer->log, LOG_ERR,
"ORIGIN attribute must be flagged as \"transitive\" (%u)", flag);
return bgp_attr_malformed (peer, BGP_ATTR_ORIGIN, flag,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
}
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
{
zlog (peer->log, LOG_ERR,
"ORIGIN attribute must not be flagged as \"partial\" (%u)", flag);
return bgp_attr_malformed (peer, BGP_ATTR_ORIGIN, flag,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
}
/* If any recognized attribute has Attribute Length that conflicts /* If any recognized attribute has Attribute Length that conflicts
with the expected length (based on the attribute type code), then with the expected length (based on the attribute type code), then
@ -830,6 +846,15 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length,
total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
/* Flag check. */ /* Flag check. */
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
{
zlog (peer->log, LOG_ERR,
"AS_PATH attribute must not be flagged as \"partial\" (%u)", flag);
return bgp_attr_malformed (peer, BGP_ATTR_ORIGIN, flag,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
}
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL) if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)
|| ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
{ {
@ -1116,6 +1141,16 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length,
startp, total); startp, total);
return -1; return -1;
} }
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
{
zlog (peer->log, LOG_ERR,
"LOCAL_PREF attribute must not be flagged as \"partial\" (%u)", flag);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
startp, total);
return -1;
}
/* If it is contained in an UPDATE message that is received from an /* If it is contained in an UPDATE message that is received from an
external peer, then this attribute MUST be ignored by the external peer, then this attribute MUST be ignored by the