summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c55
1 files changed, 39 insertions, 16 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index b27267c0..b20386e5 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -695,7 +695,8 @@ bgp_attr_aspathlimit (struct peer *peer, bgp_size_t length,
total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
- if (flag != (BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL))
+ if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
+ || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL))
{
zlog (peer->log, LOG_ERR,
"AS-Pathlimit attribute flag isn't transitive %d", flag);
@@ -804,7 +805,7 @@ bgp_attr_aspath (struct peer *peer, bgp_size_t length,
|| ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
{
zlog (peer->log, LOG_ERR,
- "Origin attribute flag isn't transitive %d", flag);
+ "As-Path attribute flag isn't transitive %d", flag);
bgp_notify_send_with_data (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
@@ -1258,7 +1259,7 @@ bgp_attr_cluster_list (struct peer *peer, bgp_size_t length,
}
/* Multiprotocol reachability information parse. */
-static int
+int
bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
struct bgp_nlri *mp_update)
{
@@ -1276,8 +1277,13 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
/* safe to read statically sized header? */
#define BGP_MP_REACH_MIN_SIZE 5
+#define LEN_LEFT (length - (stream_get_getp(s) - start))
if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE))
- return -1;
+ {
+ zlog_info ("%s: %s sent invalid length, %lu",
+ __func__, peer->host, (unsigned long)length);
+ return -1;
+ }
/* Load AFI, SAFI. */
afi = stream_getw (s);
@@ -1286,8 +1292,12 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
/* Get nexthop length. */
attre->mp_nexthop_len = stream_getc (s);
- if (STREAM_READABLE(s) < attre->mp_nexthop_len)
- return -1;
+ if (LEN_LEFT < attre->mp_nexthop_len)
+ {
+ zlog_info ("%s: %s, MP nexthop length, %u, goes past end of attribute",
+ __func__, peer->host, attre->mp_nexthop_len);
+ return -1;
+ }
/* Nexthop length check. */
switch (attre->mp_nexthop_len)
@@ -1329,13 +1339,17 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
break;
#endif /* HAVE_IPV6 */
default:
- zlog_info ("Wrong multiprotocol next hop length: %d",
- attre->mp_nexthop_len);
+ zlog_info ("%s: (%s) Wrong multiprotocol next hop length: %d",
+ __func__, peer->host, attre->mp_nexthop_len);
return -1;
}
- if (!STREAM_READABLE(s))
- return -1;
+ if (!LEN_LEFT)
+ {
+ zlog_info ("%s: (%s) Failed to read SNPA and NLRI(s)",
+ __func__, peer->host);
+ return -1;
+ }
{
u_char val;
@@ -1345,15 +1359,23 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
}
/* must have nrli_len, what is left of the attribute */
- nlri_len = length - (stream_get_getp(s) - start);
+ nlri_len = LEN_LEFT;
if ((!nlri_len) || (nlri_len > STREAM_READABLE(s)))
- return -1;
+ {
+ zlog_info ("%s: (%s) Failed to read NLRI",
+ __func__, peer->host);
+ return -1;
+ }
if (safi != BGP_SAFI_VPNV4)
{
ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len);
- if (ret < 0)
- return -1;
+ if (ret < 0)
+ {
+ zlog_info ("%s: (%s) NLRI doesn't pass sanity check",
+ __func__, peer->host);
+ return -1;
+ }
}
mp_update->afi = afi;
@@ -1364,10 +1386,11 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
stream_forward_getp (s, nlri_len);
return 0;
+#undef LEN_LEFT
}
/* Multiprotocol unreachable parse */
-static int
+int
bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length,
struct bgp_nlri *mp_withdraw)
{
@@ -1548,7 +1571,7 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
&& ((endp - startp) < (BGP_ATTR_MIN_LEN + 1)))
{
zlog (peer->log, LOG_WARNING,
- "%s Extended length set, but just %tu bytes of attr header",
+ "%s Extended length set, but just %lu bytes of attr header",
peer->host,
endp - STREAM_PNT (BGP_INPUT (peer)));