0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

Hack-fix of IPv6 SADR literal parsing

This should be probably once done better, not by ad-hoc disabling
the attribute symbol table when parsing SADR literals.
This commit is contained in:
Maria Matejka 2024-01-28 23:37:08 +01:00
parent a0041dd236
commit 2e5cf618ef
3 changed files with 52 additions and 13 deletions

View File

@ -893,8 +893,15 @@ cf_swap_soft_scope(struct config *conf)
void void
cf_enter_filters(void) cf_enter_filters(void)
{ {
ASSERT_DIE(!new_config->allow_attributes); ASSERT_DIE(!cf_maybe_enter_filters());
}
int
cf_maybe_enter_filters(void)
{
int o = new_config->allow_attributes;
new_config->allow_attributes = 1; new_config->allow_attributes = 1;
return o;
} }
/** /**
@ -903,8 +910,15 @@ cf_enter_filters(void)
void void
cf_exit_filters(void) cf_exit_filters(void)
{ {
ASSERT_DIE(new_config->allow_attributes); ASSERT_DIE(cf_maybe_exit_filters());
}
int
cf_maybe_exit_filters(void)
{
int o = new_config->allow_attributes;
new_config->allow_attributes = 0; new_config->allow_attributes = 0;
return o;
} }

View File

@ -159,6 +159,8 @@ struct sym_scope {
void cf_enter_filters(void); void cf_enter_filters(void);
void cf_exit_filters(void); void cf_exit_filters(void);
int cf_maybe_enter_filters(void);
int cf_maybe_exit_filters(void);
extern pool *global_root_scope_pool; extern pool *global_root_scope_pool;
extern linpool *global_root_scope_linpool; extern linpool *global_root_scope_linpool;

View File

@ -28,6 +28,8 @@ CF_HDR
CF_DEFINES CF_DEFINES
static _Bool this_sadr_from_hack_active;
static void static void
check_u16(uint val) check_u16(uint val)
{ {
@ -119,7 +121,7 @@ CF_DECLS
%type <i> expr bool pxlen4 %type <i> expr bool pxlen4
%type <time> expr_us time %type <time> expr_us time
%type <settle> settle %type <settle> settle
%type <a> ipa %type <a> ipa net_ip6_slash
%type <net> net_ip4_ net_ip4 net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa %type <net> net_ip4_ net_ip4 net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_mpls_ %type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_ net_ip6_sadr_ net_mpls_
%type <ad> label_stack_start label_stack %type <ad> label_stack_start label_stack
@ -235,12 +237,24 @@ net_ip4_: IP4 pxlen4
n->prefix, n->pxlen, ip4_and(n->prefix, ip4_mkmask(n->pxlen)), n->pxlen); n->prefix, n->pxlen, ip4_and(n->prefix, ip4_mkmask(n->pxlen)), n->pxlen);
}; };
net_ip6_: IP6 '/' NUM net_ip6_slash: IP6 '/'
{ {
if ($3 > IP6_MAX_PREFIX_LENGTH) this_sadr_from_hack_active = cf_maybe_exit_filters();
cf_error("Invalid prefix length %u", $3); $$ = $1;
}
net_fill_ip6(&($$), $1, $3); net_ip6_: net_ip6_slash NUM
{
if (this_sadr_from_hack_active)
{
cf_enter_filters();
this_sadr_from_hack_active = 0;
}
if ($2 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %u", $2);
net_fill_ip6(&($$), $1, $2);
net_addr_ip6 *n = (void *) &($$); net_addr_ip6 *n = (void *) &($$);
if (!net_validate_ip6(n)) if (!net_validate_ip6(n))
@ -248,16 +262,25 @@ net_ip6_: IP6 '/' NUM
n->prefix, n->pxlen, ip6_and(n->prefix, ip6_mkmask(n->pxlen)), n->pxlen); n->prefix, n->pxlen, ip6_and(n->prefix, ip6_mkmask(n->pxlen)), n->pxlen);
}; };
net_ip6_sadr_: IP6 '/' NUM FROM IP6 '/' NUM net_ip6_sadr_: net_ip6_slash NUM FROM IP6 '/' NUM
{ {
if ($3 > IP6_MAX_PREFIX_LENGTH) if (this_sadr_from_hack_active)
cf_error("Invalid prefix length %u", $3); {
cf_enter_filters();
this_sadr_from_hack_active = 0;
}
if ($7 > IP6_MAX_PREFIX_LENGTH) if (($3->class != SYM_KEYWORD) || ($3->keyword->value != FROM))
cf_error("Invalid prefix length %u", $7); cf_error("Expected FROM after %I6/%d", $1, $2);
if ($2 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %u", $2);
if ($6 > IP6_MAX_PREFIX_LENGTH)
cf_error("Invalid prefix length %u", $6);
$$ = cfg_alloc(sizeof(net_addr_ip6_sadr)); $$ = cfg_alloc(sizeof(net_addr_ip6_sadr));
net_fill_ip6_sadr($$, $1, $3, $5, $7); net_fill_ip6_sadr($$, $1, $2, $4, $6);
net_addr_ip6_sadr *n = (void *) $$; net_addr_ip6_sadr *n = (void *) $$;
if (!net_validate_ip6_sadr(n)) if (!net_validate_ip6_sadr(n))