mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 12:37:10 +00:00
bgpd: rewrite attr flag error logging
* bgp_attr.c * attr_flag_str: new message list * bgp_attr_flags_diagnose(): new function, implements previously added error logging in a generic way * bgp_attr_origin(): use bgp_attr_flags_diagnose() * bgp_attr_nexthop(): ditto * bgp_attr_med(): ditto * bgp_attr_local_pref(): ditto * bgp_attr_atomic(): ditto * bgp_attr_originator_id(): ditto * bgp_attr_cluster_list(): ditto * bgp_mp_reach_parse(): ditto * bgp_mp_unreach_parse(): ditto
This commit is contained in:
parent
5c8d16fd85
commit
26f5e782ef
108
bgpd/bgp_attr.c
108
bgpd/bgp_attr.c
@ -62,6 +62,17 @@ static const struct message attr_str [] =
|
|||||||
{ BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" },
|
{ BGP_ATTR_AS_PATHLIMIT, "AS_PATHLIMIT" },
|
||||||
};
|
};
|
||||||
static const int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]);
|
static const int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]);
|
||||||
|
|
||||||
|
static const struct message attr_flag_str[] =
|
||||||
|
{
|
||||||
|
{ BGP_ATTR_FLAG_OPTIONAL, "Optional" },
|
||||||
|
{ BGP_ATTR_FLAG_TRANS, "Transitive" },
|
||||||
|
{ BGP_ATTR_FLAG_PARTIAL, "Partial" },
|
||||||
|
/* bgp_attr_flags_diagnose() relies on this bit being last in this list */
|
||||||
|
{ BGP_ATTR_FLAG_EXTLEN, "Extended Length" },
|
||||||
|
};
|
||||||
|
static const size_t attr_flag_str_max =
|
||||||
|
sizeof (attr_flag_str) / sizeof (attr_flag_str[0]);
|
||||||
|
|
||||||
static struct hash *cluster_hash;
|
static struct hash *cluster_hash;
|
||||||
|
|
||||||
@ -697,6 +708,40 @@ bgp_attr_flush (struct attr *attr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find out what is wrong with the path attribute flag bits and log the error.
|
||||||
|
"Flag bits" here stand for Optional, Transitive and Partial, but not for
|
||||||
|
Extended Length. Checking O/T/P bits at once implies, that the attribute
|
||||||
|
being diagnosed is defined by RFC as either a "well-known" or an "optional,
|
||||||
|
non-transitive" attribute. */
|
||||||
|
static void
|
||||||
|
bgp_attr_flags_diagnose
|
||||||
|
(
|
||||||
|
struct peer * peer,
|
||||||
|
const u_int8_t attr_code,
|
||||||
|
u_int8_t desired_flags, /* how RFC says it must be */
|
||||||
|
u_int8_t real_flags /* on wire */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
u_char seen = 0, i;
|
||||||
|
|
||||||
|
desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
|
||||||
|
real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
|
||||||
|
for (i = 0; i <= 2; i++) /* O,T,P, but not E */
|
||||||
|
if
|
||||||
|
(
|
||||||
|
CHECK_FLAG (desired_flags, attr_flag_str[i].key) !=
|
||||||
|
CHECK_FLAG (real_flags, attr_flag_str[i].key)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
zlog (peer->log, LOG_ERR, "%s attribute must%s be flagged as \"%s\"",
|
||||||
|
LOOKUP (attr_str, attr_code),
|
||||||
|
CHECK_FLAG (desired_flags, attr_flag_str[i].key) ? "" : " not",
|
||||||
|
attr_flag_str[i].str);
|
||||||
|
seen = 1;
|
||||||
|
}
|
||||||
|
assert (seen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get origin attribute of the update message. */
|
/* Get origin attribute of the update message. */
|
||||||
static int
|
static int
|
||||||
bgp_attr_origin (struct peer *peer, bgp_size_t length,
|
bgp_attr_origin (struct peer *peer, bgp_size_t length,
|
||||||
@ -714,12 +759,7 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length,
|
|||||||
attribute (type, length and value). */
|
attribute (type, length and value). */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_ORIGIN, BGP_ATTR_FLAG_TRANS, flag);
|
||||||
zlog (peer->log, LOG_ERR, "ORIGIN attribute must not be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "ORIGIN attribute must be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "ORIGIN 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -917,12 +957,7 @@ bgp_attr_nexthop (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flags check. */
|
/* Flags check. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_NEXT_HOP, BGP_ATTR_FLAG_TRANS, flag);
|
||||||
zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must not be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "NEXT_HOP attribute must be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "NEXT_HOP 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -977,12 +1012,7 @@ bgp_attr_med (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_MULTI_EXIT_DISC, BGP_ATTR_FLAG_OPTIONAL, flag);
|
||||||
zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC attribute must not be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "MULTI_EXIT_DISC 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1018,12 +1048,7 @@ bgp_attr_local_pref (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_LOCAL_PREF, BGP_ATTR_FLAG_TRANS, flag);
|
||||||
zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must not be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "LOCAL_PREF attribute must be flagged as \"transitive\" (%u)", flag);
|
|
||||||
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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1066,12 +1091,7 @@ bgp_attr_atomic (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_TRANS)
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_ATOMIC_AGGREGATE, BGP_ATTR_FLAG_TRANS, flag);
|
||||||
zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must not be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE attribute must be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "ATOMIC_AGGREGATE 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1325,12 +1345,7 @@ bgp_attr_originator_id (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_ORIGINATOR_ID, BGP_ATTR_FLAG_OPTIONAL, flag);
|
||||||
zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "ORIGINATOR_ID attribute must not be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "ORIGINATOR_ID 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1364,12 +1379,7 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_CLUSTER_LIST, BGP_ATTR_FLAG_OPTIONAL, flag);
|
||||||
zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "CLUSTER_LIST attribute must not be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "CLUSTER_LIST 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1412,12 +1422,7 @@ bgp_mp_reach_parse (struct peer *peer, const bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_MP_REACH_NLRI, BGP_ATTR_FLAG_OPTIONAL, flag);
|
||||||
zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "MP_REACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "MP_REACH_NLRI 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1559,12 +1564,7 @@ bgp_mp_unreach_parse (struct peer *peer, const bgp_size_t length,
|
|||||||
/* Flag checks. */
|
/* Flag checks. */
|
||||||
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
if ((flag & ~BGP_ATTR_FLAG_EXTLEN) != BGP_ATTR_FLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL))
|
bgp_attr_flags_diagnose (peer, BGP_ATTR_MP_UNREACH_NLRI, BGP_ATTR_FLAG_OPTIONAL, flag);
|
||||||
zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must be flagged as \"optional\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
|
|
||||||
zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI attribute must not be flagged as \"transitive\" (%u)", flag);
|
|
||||||
if (CHECK_FLAG (flag, BGP_ATTR_FLAG_PARTIAL))
|
|
||||||
zlog (peer->log, LOG_ERR, "MP_UNREACH_NLRI 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);
|
bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user