summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_open.c
diff options
context:
space:
mode:
authorPaul Jakma <paul.jakma@hpe.com>2015-11-25 18:14:35 +0100
committervivek <vivek@cumulusnetworks.com>2016-06-06 21:09:57 +0200
commit695ef95fd7d5d8e48e2406092a2f52c8c9c784f3 (patch)
tree8914488f7ece0e1770deafb450bf53e2ad8642a7 /bgpd/bgp_open.c
parentMerge branch 'cmaster-next' of ssh://stash.cumulusnetworks.com:7999/quag/quag... (diff)
downloadfrr-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.c30
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;