]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/aggregator/config.Y
Aggregator: Fix build with limited set of protocols
[thirdparty/bird.git] / proto / aggregator / config.Y
CommitLineData
977b82fb
IP
1/*
2 * BIRD -- Aggregator configuration
3 *
4 * (c) 2023 Igor Putovny <igor.putovny@nic.cz>
5 * (c) 2023 Maria Matejka <mq@ucw.cz>
6 * (c) 2023 CZ.NIC z.s.p.o.
7 *
8 * Can be freely distributed and used under the terms of the GNU GPL.
9 */
10
11CF_HDR
12
13#include "proto/aggregator/aggregator.h"
14
15CF_DEFINES
16
17#define AGGREGATOR_CFG ((struct aggregator_config *) this_proto)
18#define AGGR_ITEM_ALLOC ((struct aggr_item_node *) cfg_allocz(sizeof(struct aggr_item_node)))
19
20
21CF_DECLS
22
06209c19 23CF_KEYWORDS(AGGREGATOR, PEER, AGGREGATE, ON, MERGE, BY)
977b82fb
IP
24
25%type <ai> aggr_item aggr_list
26
27CF_GRAMMAR
28
29proto: aggregator_proto ;
30
31aggregator_proto_start: proto_start AGGREGATOR
32{
33 this_proto = proto_config_new(&proto_aggregator, $1);
34 this_channel = AGGREGATOR_CFG->src = channel_config_new(NULL, "source", 0, this_proto);
35 AGGREGATOR_CFG->dst = channel_config_new(NULL, "destination", 0, this_proto);
36
37 AGGREGATOR_CFG->src->ra_mode = AGGREGATOR_CFG->dst->ra_mode = RA_ANY;
38};
39
40aggregator_proto_item:
41 proto_item
42 | channel_item_
43 | PEER TABLE rtable { AGGREGATOR_CFG->dst->table = $3; }
44 | AGGREGATE ON aggr_list {
45 if (AGGREGATOR_CFG->aggr_on)
46 cf_error("Only one aggregate on clause allowed");
47
48 _Bool net_present = 0;
49 int count = 0;
50
51 for (const struct aggr_item_node *item = $3; item; item = item->next) {
52// log(L_WARN "type %d sacode %d", item->i.type, item->i.sa.sa_code);
53 if (item->i.type == AGGR_ITEM_STATIC_ATTR && item->i.sa.sa_code == SA_NET)
54 net_present = 1;
55
56 count++;
57 }
58
59 if (!net_present)
60 cf_error("'NET' must be present");
61
62 AGGREGATOR_CFG->aggr_on = cfg_alloc(sizeof(struct aggr_item) * count);
63
64 int pos = 0;
65 for (const struct aggr_item_node *item = $3; item; item = item->next) {
66 if (item->i.type == AGGR_ITEM_DYNAMIC_ATTR)
67 AGGREGATOR_CFG->aggr_on_da_count++;
68
69 AGGREGATOR_CFG->aggr_on[pos++] = item->i;
70 }
71
72 AGGREGATOR_CFG->aggr_on_count = pos;
73 }
74 | MERGE BY {
75 cf_push_block_scope(new_config);
76 cf_create_symbol(new_config, "routes", SYM_VARIABLE | T_ROUTES_BLOCK, offset, f_new_var(sym_->scope));
77 } function_body {
78 cf_pop_block_scope(new_config);
79 $4->args++;
80 AGGREGATOR_CFG->merge_by = $4;
81 }
82;
83
84aggregator_proto_opts: /* empty */ | aggregator_proto_opts aggregator_proto_item ';' ;
85aggregator_proto: aggregator_proto_start proto_name '{' aggregator_proto_opts '}' ;
86
87
88aggr_list:
89 aggr_item
90 | aggr_list ',' aggr_item {
91 if ($3 == NULL) {
92 $$ = $1;
93 } else {
94 $$ = $3;
95 $$->next = $1;
96 }
97 }
98 ;
99
100aggr_item:
101 '(' term ')' {
102 $$ = AGGR_ITEM_ALLOC;
103 $$->i.type = AGGR_ITEM_TERM;
104 $$->i.line = f_linearize($2, 1);
105 }
106 | CF_SYM_KNOWN {
107 switch ($1->class) {
108 case SYM_ATTRIBUTE:
109 $$ = AGGR_ITEM_ALLOC;
110 $$->i.type = AGGR_ITEM_DYNAMIC_ATTR;
111 $$->i.da = *$1->attribute;
112 break;
113 case SYM_CONSTANT_RANGE:
114 $$ = NULL;
115 break;
116 default:
117 cf_error("Can't aggregate on symbol type %s.", cf_symbol_class_name($1));
118 }
119 }
120 | dynamic_attr {
121 $$ = AGGR_ITEM_ALLOC;
122 $$->i.type = AGGR_ITEM_DYNAMIC_ATTR;
123 $$->i.da = $1;
124 }
125 | static_attr {
126 $$ = AGGR_ITEM_ALLOC;
127 $$->i.type = AGGR_ITEM_STATIC_ATTR;
128 $$->i.sa = $1;
129 }
130 ;
131
132CF_CODE
133
134CF_END