]>
Commit | Line | Data |
---|---|---|
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 | ||
11 | CF_HDR | |
12 | ||
13 | #include "proto/aggregator/aggregator.h" | |
14 | ||
15 | CF_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 | ||
21 | CF_DECLS | |
22 | ||
06209c19 | 23 | CF_KEYWORDS(AGGREGATOR, PEER, AGGREGATE, ON, MERGE, BY) |
977b82fb IP |
24 | |
25 | %type <ai> aggr_item aggr_list | |
26 | ||
27 | CF_GRAMMAR | |
28 | ||
29 | proto: aggregator_proto ; | |
30 | ||
31 | aggregator_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 | ||
40 | aggregator_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 | ||
84 | aggregator_proto_opts: /* empty */ | aggregator_proto_opts aggregator_proto_item ';' ; | |
85 | aggregator_proto: aggregator_proto_start proto_name '{' aggregator_proto_opts '}' ; | |
86 | ||
87 | ||
88 | aggr_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 | ||
100 | aggr_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 | ||
132 | CF_CODE | |
133 | ||
134 | CF_END |