]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/radv/config.Y
Conf: Allow keywords to be redefined by user symbols
[thirdparty/bird.git] / proto / radv / config.Y
CommitLineData
93e868c7
OZ
1/*
2 * BIRD -- Router Advertisement Configuration
3 *
70a4320b
OZ
4 * (c) 2011--2019 Ondrej Zajicek <santiago@crfreenet.org>
5 * (c) 2011--2019 CZ.NIC z.s.p.o.
93e868c7
OZ
6 *
7 * Can be freely distributed and used under the terms of the GNU GPL.
8 */
9
10CF_HDR
11
12#include "proto/radv/radv.h"
13
14CF_DEFINES
15
16#define RADV_CFG ((struct radv_config *) this_proto)
17#define RADV_IFACE ((struct radv_iface_config *) this_ipatt)
18#define RADV_PREFIX this_radv_prefix
fc06fb62
OZ
19#define RADV_RDNSS (&this_radv_rdnss)
20#define RADV_DNSSL (&this_radv_dnssl)
93e868c7
OZ
21
22static struct radv_prefix_config *this_radv_prefix;
fc06fb62
OZ
23static struct radv_rdnss_config this_radv_rdnss;
24static struct radv_dnssl_config this_radv_dnssl;
25static list radv_dns_list; /* Used by radv_rdnss and radv_dnssl */
26static u8 radv_mult_val; /* Used by radv_mult for second return value */
27
9c81250c 28static inline void
fea04d7c 29radv_add_to_custom_list(list *l, int type, const struct bytestring *payload)
9c81250c
AZ
30{
31 if (type < 0 || type > 255) cf_error("RA cusom type must be in range 0-255");
32 struct radv_custom_config *cf = cfg_allocz(sizeof(struct radv_custom_config));
33 add_tail(l, NODE cf);
34 cf->type = type;
35 cf->payload = payload;
36}
93e868c7
OZ
37
38CF_DECLS
39
70a4320b
OZ
40CF_KEYWORDS(RADV, PREFIX, INTERFACE, MIN, MAX, RA, DELAY, INTERVAL, SOLICITED,
41 UNICAST, MANAGED, OTHER, CONFIG, LINGER, LINK, MTU, REACHABLE, TIME,
42 RETRANS, TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, MULT,
43 LIFETIME, SKIP, ONLINK, AUTONOMOUS, RDNSS, DNSSL, NS, DOMAIN, LOCAL,
44 TRIGGER, SENSITIVE, PREFERENCE, LOW, MEDIUM, HIGH, PROPAGATE, ROUTE,
ccfa48a2 45 ROUTES, RA_PREFERENCE, RA_LIFETIME, CUSTOM, OPTION, TYPE, VALUE)
2a95e633
MV
46
47CF_ENUM(T_ENUM_RA_PREFERENCE, RA_PREF_, LOW, MEDIUM, HIGH)
93e868c7 48
75148289 49%type<i> radv_mult radv_sensitive radv_preference
93e868c7
OZ
50
51CF_GRAMMAR
52
f851f0d7 53proto: radv_proto ;
93e868c7
OZ
54
55radv_proto_start: proto_start RADV
56{
2bbc3083 57 this_proto = proto_config_new(&proto_radv, $1);
f761be6b 58 this_proto->net_type = NET_IP6;
f4a60a9b 59
93e868c7
OZ
60 init_list(&RADV_CFG->patt_list);
61 init_list(&RADV_CFG->pref_list);
fc06fb62
OZ
62 init_list(&RADV_CFG->rdnss_list);
63 init_list(&RADV_CFG->dnssl_list);
9c81250c 64 init_list(&RADV_CFG->custom_list);
93e868c7
OZ
65};
66
67radv_proto_item:
68 proto_item
f4a60a9b 69 | proto_channel
93e868c7 70 | INTERFACE radv_iface
fc06fb62
OZ
71 | PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); }
72 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); }
73 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); }
f411a19b 74 | CUSTOM OPTION TYPE expr VALUE bytestring { radv_add_to_custom_list(&RADV_CFG->custom_list, $4, $6); }
f4a60a9b 75 | TRIGGER net_ip6 { RADV_CFG->trigger = $2; }
2a95e633 76 | PROPAGATE ROUTES bool { RADV_CFG->propagate_routes = $3; }
93e868c7
OZ
77 ;
78
79radv_proto_opts:
80 /* empty */
81 | radv_proto_opts radv_proto_item ';'
82 ;
83
84radv_proto:
fc06fb62 85 radv_proto_start proto_name '{' radv_proto_opts '}';
93e868c7
OZ
86
87
88radv_iface_start:
89{
90 this_ipatt = cfg_allocz(sizeof(struct radv_iface_config));
91 add_tail(&RADV_CFG->patt_list, NODE this_ipatt);
92 init_list(&this_ipatt->ipn_list);
93 init_list(&RADV_IFACE->pref_list);
fc06fb62
OZ
94 init_list(&RADV_IFACE->rdnss_list);
95 init_list(&RADV_IFACE->dnssl_list);
9c81250c 96 init_list(&RADV_IFACE->custom_list);
93e868c7 97
830ba75e 98 RADV_IFACE->min_ra_int = (u32) -1; /* undefined */
93e868c7
OZ
99 RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT;
100 RADV_IFACE->min_delay = DEFAULT_MIN_DELAY;
830ba75e
OZ
101 RADV_IFACE->prefix_linger_time = (u32) -1;
102 RADV_IFACE->route_linger_time = (u32) -1;
93e868c7 103 RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT;
830ba75e 104 RADV_IFACE->default_lifetime = (u32) -1;
36da2857 105 RADV_IFACE->default_lifetime_sensitive = 1;
75148289 106 RADV_IFACE->default_preference = RA_PREF_MEDIUM;
830ba75e 107 RADV_IFACE->route_lifetime = (u32) -1;
7c0bab3a
OZ
108 RADV_IFACE->route_lifetime_sensitive = 0;
109 RADV_IFACE->route_preference = RA_PREF_MEDIUM;
93e868c7
OZ
110};
111
112radv_iface_item:
113 MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); }
114 | MAX RA INTERVAL expr { RADV_IFACE->max_ra_int = $4; if (($4 < 4) || ($4 > 1800)) cf_error("Max RA interval must be in range 4-1800"); }
115 | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); }
70a4320b 116 | SOLICITED RA UNICAST bool { RADV_IFACE->solicited_ra_unicast = $4; }
93e868c7
OZ
117 | MANAGED bool { RADV_IFACE->managed = $2; }
118 | OTHER CONFIG bool { RADV_IFACE->other_config = $3; }
6aaaa635
OZ
119 | LINK MTU expr { RADV_IFACE->link_mtu = $3; }
120 | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if ($3 > 3600000) cf_error("Reachable time must be in range 0-3600000"); }
121 | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; }
122 | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if ($4 > 255) cf_error("Current hop limit must be in range 0-255"); }
36da2857
OZ
123 | DEFAULT LIFETIME expr radv_sensitive {
124 RADV_IFACE->default_lifetime = $3;
6aaaa635
OZ
125 if ($3 > 9000) cf_error("Default lifetime must be in range 0-9000");
126 if ($4 != (uint) -1) RADV_IFACE->default_lifetime_sensitive = $4;
36da2857 127 }
7c0bab3a
OZ
128 | ROUTE LIFETIME expr radv_sensitive {
129 RADV_IFACE->route_lifetime = $3;
830ba75e 130 if ($4 != (uint) -1) RADV_IFACE->route_lifetime_sensitive = $4;
7c0bab3a 131 }
75148289 132 | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
7c0bab3a
OZ
133 | ROUTE PREFERENCE radv_preference { RADV_IFACE->route_preference = $3; }
134 | PREFIX LINGER TIME expr { RADV_IFACE->prefix_linger_time = $4; }
135 | ROUTE LINGER TIME expr { RADV_IFACE->route_linger_time = $4; }
93e868c7 136 | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
fc06fb62
OZ
137 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); }
138 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); }
f411a19b 139 | CUSTOM OPTION TYPE expr VALUE bytestring { radv_add_to_custom_list(&RADV_IFACE->custom_list, $4, $6); }
fc06fb62
OZ
140 | RDNSS LOCAL bool { RADV_IFACE->rdnss_local = $3; }
141 | DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; }
ccfa48a2 142 | CUSTOM OPTION LOCAL bool { RADV_IFACE->custom_local = $4; }
93e868c7
OZ
143 ;
144
75148289
OZ
145radv_preference:
146 LOW { $$ = RA_PREF_LOW; }
147 | MEDIUM { $$ = RA_PREF_MEDIUM; }
148 | HIGH { $$ = RA_PREF_HIGH; }
149
93e868c7
OZ
150radv_iface_finish:
151{
152 struct radv_iface_config *ic = RADV_IFACE;
153
154 if (ic->min_ra_int == (u32) -1)
41f8bf57 155 ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3);
93e868c7
OZ
156
157 if (ic->default_lifetime == (u32) -1)
158 ic->default_lifetime = 3 * ic->max_ra_int;
159
7c0bab3a
OZ
160 if (ic->route_lifetime == (u32) -1)
161 ic->route_lifetime = 3 * ic->max_ra_int;
162
163 if (ic->prefix_linger_time == (u32) -1)
164 ic->prefix_linger_time = 3 * ic->max_ra_int;
165
166 if (ic->route_linger_time == (u32) -1)
167 ic->route_linger_time = 3 * ic->max_ra_int;
168
93e868c7
OZ
169 if ((ic->min_ra_int > 3) &&
170 (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
6aaaa635 171 cf_error("Min RA interval must be at most 3/4 * Max RA interval");
93e868c7
OZ
172
173 if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
174 cf_error("Default lifetime must be either 0 or at least Max RA interval");
7c0bab3a
OZ
175
176 if ((ic->route_lifetime > 0) && (ic->route_lifetime < ic->max_ra_int))
177 cf_error("Route lifetime must be either 0 or at least Max RA interval");
178
179 if ((ic->prefix_linger_time > 0) && (ic->prefix_linger_time < ic->max_ra_int))
180 cf_error("Prefix linger time must be either 0 or at least Max RA interval");
181
182 if ((ic->route_linger_time > 0) && (ic->route_linger_time < ic->max_ra_int))
183 cf_error("Route linger time must be either 0 or at least Max RA interval");
184
185 RADV_CFG->max_linger_time = MAX_(RADV_CFG->max_linger_time, ic->route_linger_time);
93e868c7
OZ
186};
187
188
189radv_iface_opts:
190 /* empty */
191 | radv_iface_opts radv_iface_item ';'
192 ;
193
194radv_iface_opt_list:
195 /* empty */
196 | '{' radv_iface_opts '}'
197 ;
198
199radv_iface:
d7c06285 200 radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish;
93e868c7
OZ
201
202
d44e686e 203radv_prefix_start: net_ip6
93e868c7
OZ
204{
205 this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
04632fd7 206 RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1);
93e868c7
OZ
207
208 RADV_PREFIX->onlink = 1;
209 RADV_PREFIX->autonomous = 1;
210 RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME;
211 RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME;
212};
213
214radv_prefix_item:
215 SKIP bool { RADV_PREFIX->skip = $2; }
216 | ONLINK bool { RADV_PREFIX->onlink = $2; }
217 | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
36da2857
OZ
218 | VALID LIFETIME expr radv_sensitive {
219 RADV_PREFIX->valid_lifetime = $3;
6aaaa635 220 if ($4 != (uint) -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
36da2857
OZ
221 }
222 | PREFERRED LIFETIME expr radv_sensitive {
223 RADV_PREFIX->preferred_lifetime = $3;
6aaaa635 224 if ($4 != (uint) -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
36da2857 225 }
93e868c7
OZ
226 ;
227
228radv_prefix_finish:
229{
230 if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime)
231 cf_error("Preferred lifetime must be at most Valid lifetime");
36da2857
OZ
232
233 if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive)
234 cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too");
93e868c7
OZ
235};
236
237radv_prefix_opts:
238 /* empty */
239 | radv_prefix_opts radv_prefix_item ';'
240 ;
241
242radv_prefix_opt_list:
243 /* empty */
244 | '{' radv_prefix_opts '}'
245 ;
246
247radv_prefix:
248 radv_prefix_start radv_prefix_opt_list radv_prefix_finish;
249
250
fc06fb62
OZ
251
252radv_rdnss_node: ipa
253{
254 struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config));
255 add_tail(&radv_dns_list, NODE cf);
256
257 cf->server = $1;
258 cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
259};
260
261radv_rdnss_start:
262{
263 RADV_RDNSS->lifetime = 0;
264 RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
265};
266
267radv_rdnss_item:
268 | NS radv_rdnss_node
269 | LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; }
270 ;
271
272radv_rdnss_finish:
273{
274 if (EMPTY_LIST(radv_dns_list))
275 cf_error("No nameserver in RDNSS section");
276
277 struct radv_rdnss_config *cf;
278 WALK_LIST(cf, radv_dns_list)
279 {
280 cf->lifetime = RADV_RDNSS->lifetime;
281 cf->lifetime_mult = RADV_RDNSS->lifetime_mult;
282 }
283};
284
285radv_rdnss_opts:
286 /* empty */
287 | radv_rdnss_opts radv_rdnss_item ';'
288 ;
289
290radv_rdnss:
291 radv_rdnss_node
292 | '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish
293 ;
294
295
296radv_dnssl_node: TEXT
297{
298 struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config));
299 add_tail(&radv_dns_list, NODE cf);
300
301 cf->domain = $1;
302 cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
303
304 if (radv_process_domain(cf) < 0)
305 cf_error("Invalid domain dame");
306};
307
308radv_dnssl_start:
309{
310 RADV_DNSSL->lifetime = 0;
311 RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
312};
313
314radv_dnssl_item:
315 | DOMAIN radv_dnssl_node
316 | LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; }
317 ;
318
319radv_dnssl_finish:
320{
321 if (EMPTY_LIST(radv_dns_list))
322 cf_error("No domain in DNSSL section");
323
324 struct radv_dnssl_config *cf;
325 WALK_LIST(cf, radv_dns_list)
326 {
327 cf->lifetime = RADV_DNSSL->lifetime;
328 cf->lifetime_mult = RADV_DNSSL->lifetime_mult;
329 }
330};
331
332radv_dnssl_opts:
333 /* empty */
334 | radv_dnssl_opts radv_dnssl_item ';'
335 ;
336
337radv_dnssl:
338 radv_dnssl_node
339 | '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish
340 ;
341
342
343radv_mult:
344 expr { $$ = $1; radv_mult_val = 0; }
345 | MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); }
346 ;
347
36da2857 348radv_sensitive:
830ba75e 349 /* empty */ { $$ = (uint) -1; }
155134f3 350 | SENSITIVE bool { $$ = $2; }
36da2857
OZ
351 ;
352
f851f0d7
JMM
353dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ;
354dynamic_attr: RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); } ;
2a95e633 355
93e868c7
OZ
356CF_CODE
357
358CF_END