diff options
author | Paul Jakma <paul.jakma@hpe.com> | 2015-11-25 17:14:35 +0000 |
---|---|---|
committer | Paul Jakma <paul.jakma@hpe.com> | 2016-02-10 15:06:17 +0000 |
commit | 4078f2eb7a3a94ddb30cfd8b76b054e790aab524 (patch) | |
tree | 3b9d32198d677be63a3587ad6f9ea06506437192 | |
parent | 68ec424eb8557f86d08fcb7ab3c5366cbf3eca0e (diff) | |
download | quagga-4078f2eb7a3a94ddb30cfd8b76b054e790aab524.tar.bz2 quagga-4078f2eb7a3a94ddb30cfd8b76b054e790aab524.tar.xz |
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>
-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 72738828..ff2ae08d 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -442,6 +442,23 @@ static const size_t cap_minsizes[] = [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry), }; +/* 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 @@ -515,6 +532,19 @@ bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability, BGP_NOTIFY_OPEN_UNSPECIFIC); 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; |