diff options
author | Paul Jakma <paul.jakma@hpe.com> | 2015-11-25 18:14:35 +0100 |
---|---|---|
committer | vivek <vivek@cumulusnetworks.com> | 2016-06-06 21:09:57 +0200 |
commit | 695ef95fd7d5d8e48e2406092a2f52c8c9c784f3 (patch) | |
tree | 8914488f7ece0e1770deafb450bf53e2ad8642a7 /bgpd/bgp_open.c | |
parent | Merge branch 'cmaster-next' of ssh://stash.cumulusnetworks.com:7999/quag/quag... (diff) | |
download | frr-695ef95fd7d5d8e48e2406092a2f52c8c9c784f3.tar.xz frr-695ef95fd7d5d8e48e2406092a2f52c8c9c784f3.zip |
bgpd: Check capability falls on right multiple of size, where possible.
* bgp_open.c: (cap_modsizes) Table of multiple a capability's data size
should fall on, if applicable.
(bgp_capability_parse) Check the header lengthcap_modsizes should fall on.
Inspiration from Cumulus bgpd-capability-cleanup.patch patch, with a
slightly different approach.
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
(cherry picked from commit 4078f2eb7a3a94ddb30cfd8b76b054e790aab524)
Diffstat (limited to 'bgpd/bgp_open.c')
-rw-r--r-- | bgpd/bgp_open.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 06cf8a17b..8d2491b96 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -713,6 +713,23 @@ static const size_t cap_minsizes[] = [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN, }; +/* value the capability must be a multiple of. + * 0-data capabilities won't be checked against this. + * Other capabilities whose data doesn't fall on convenient boundaries for this + * table should be set to 1. + */ +static const size_t cap_modsizes[] = +{ + [CAPABILITY_CODE_MP] = 4, + [CAPABILITY_CODE_REFRESH] = 1, + [CAPABILITY_CODE_ORF] = 1, + [CAPABILITY_CODE_RESTART] = 1, + [CAPABILITY_CODE_AS4] = 4, + [CAPABILITY_CODE_DYNAMIC] = 1, + [CAPABILITY_CODE_REFRESH_OLD] = 1, + [CAPABILITY_CODE_ORF_OLD] = 1, +}; + /** * Parse given capability. * XXX: This is reading into a stream, but not using stream API @@ -790,6 +807,19 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability, bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, BGP_NOTIFY_OPEN_MALFORMED_ATTR); return -1; } + if (caphdr.length + && caphdr.length % cap_modsizes[caphdr.code] != 0) + { + zlog_info ("%s %s Capability length error: got %u," + " expected a multiple of %u", + peer->host, + LOOKUP (capcode_str, caphdr.code), + caphdr.length, + (unsigned) cap_modsizes[caphdr.code]); + bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_UNSPECIFIC); + return -1; + } /* we deliberately ignore unknown codes, see below */ default: break; |