summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-05-19 01:02:57 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-05-19 01:02:57 +0200
commitf8ba82804faba5cc1520d4545330502e29b9e920 (patch)
treea18c0c2309eaf4236c4ad2baf6a3f10084bdc118
parentb0e97617d98ed02235de37b7e498d81f01330b50 (diff)
BGP: Fix role check when no capability option is present
When an OPEN message without capability options was parsed, the remote role field was not initialized with the proper (non-zero) default value, so it was interpreted as if 'provider' was announced. Thanks to Mikhail Grishin for the bugreport.
-rw-r--r--proto/bgp/packets.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index b9537169..6e6e41ca 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -215,6 +215,13 @@ bgp_af_caps_cmp(const void *X, const void *Y)
return (x->afi < y->afi) ? -1 : (x->afi > y->afi) ? 1 : 0;
}
+struct bgp_caps *
+bgp_alloc_capabilities(struct bgp_proto *p, int n)
+{
+ struct bgp_caps *caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + n * sizeof(struct bgp_af_caps));
+ caps->role = BGP_ROLE_UNDEFINED;
+ return caps;
+}
void
bgp_prepare_capabilities(struct bgp_conn *conn)
@@ -227,13 +234,13 @@ bgp_prepare_capabilities(struct bgp_conn *conn)
if (!p->cf->capabilities)
{
/* Just prepare empty local_caps */
- conn->local_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
+ conn->local_caps = bgp_alloc_capabilities(p, 0);
return;
}
/* Prepare bgp_caps structure */
int n = list_length(&p->p.channels);
- caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + n * sizeof(struct bgp_af_caps));
+ caps = bgp_alloc_capabilities(p, n);
conn->local_caps = caps;
caps->as4_support = p->cf->enable_as4;
@@ -464,10 +471,7 @@ bgp_read_capabilities(struct bgp_conn *conn, byte *pos, int len)
u32 af;
if (!conn->remote_caps)
- {
- caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + sizeof(struct bgp_af_caps));
- caps->role = BGP_ROLE_UNDEFINED;
- }
+ caps = bgp_alloc_capabilities(p, 1);
else
{
caps = conn->remote_caps;
@@ -763,7 +767,7 @@ bgp_read_options(struct bgp_conn *conn, byte *pos, uint len, uint rest)
/* Prepare empty caps if no capability option was announced */
if (!conn->remote_caps)
- conn->remote_caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps));
+ conn->remote_caps = bgp_alloc_capabilities(p, 0);
return 0;