0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00

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.
This commit is contained in:
Ondrej Zajicek 2023-05-19 01:02:57 +02:00 committed by Igor Putovny
parent 104fc34f94
commit d7163f6427

View File

@ -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; 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 void
bgp_prepare_capabilities(struct bgp_conn *conn) bgp_prepare_capabilities(struct bgp_conn *conn)
@ -227,13 +234,13 @@ bgp_prepare_capabilities(struct bgp_conn *conn)
if (!p->cf->capabilities) if (!p->cf->capabilities)
{ {
/* Just prepare empty local_caps */ /* 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; return;
} }
/* Prepare bgp_caps structure */ /* Prepare bgp_caps structure */
int n = list_length(&p->p.channels); 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; conn->local_caps = caps;
caps->as4_support = p->cf->enable_as4; caps->as4_support = p->cf->enable_as4;
@ -464,10 +471,7 @@ bgp_read_capabilities(struct bgp_conn *conn, byte *pos, int len)
u32 af; u32 af;
if (!conn->remote_caps) if (!conn->remote_caps)
{ caps = bgp_alloc_capabilities(p, 1);
caps = mb_allocz(p->p.pool, sizeof(struct bgp_caps) + sizeof(struct bgp_af_caps));
caps->role = BGP_ROLE_UNDEFINED;
}
else else
{ {
caps = conn->remote_caps; 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 */ /* Prepare empty caps if no capability option was announced */
if (!conn->remote_caps) 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; return 0;