]> git.ipfire.org Git - thirdparty/bird.git/blob - proto/radv/config.Y
Merge tag 'v1.6.2' into int-new
[thirdparty/bird.git] / proto / radv / config.Y
1 /*
2 * BIRD -- Router Advertisement Configuration
3 *
4 *
5 * Can be freely distributed and used under the terms of the GNU GPL.
6 */
7
8 CF_HDR
9
10 #include "proto/radv/radv.h"
11
12 CF_DEFINES
13
14 #define RADV_CFG ((struct radv_config *) this_proto)
15 #define RADV_IFACE ((struct radv_iface_config *) this_ipatt)
16 #define RADV_PREFIX this_radv_prefix
17 #define RADV_RDNSS (&this_radv_rdnss)
18 #define RADV_DNSSL (&this_radv_dnssl)
19
20 static struct radv_prefix_config *this_radv_prefix;
21 static struct radv_rdnss_config this_radv_rdnss;
22 static struct radv_dnssl_config this_radv_dnssl;
23 static list radv_dns_list; /* Used by radv_rdnss and radv_dnssl */
24 static u8 radv_mult_val; /* Used by radv_mult for second return value */
25
26
27 CF_DECLS
28
29 CF_KEYWORDS(RADV, PREFIX, INTERFACE, MIN, MAX, RA, DELAY, INTERVAL,
30 MANAGED, OTHER, CONFIG, LINK, MTU, REACHABLE, TIME, RETRANS,
31 TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, MULT,
32 LIFETIME, SKIP, ONLINK, AUTONOMOUS, RDNSS, DNSSL, NS, DOMAIN,
33 LOCAL, TRIGGER, SENSITIVE, PREFERENCE, LOW, MEDIUM, HIGH)
34
35 %type<i> radv_mult radv_sensitive radv_preference
36
37 CF_GRAMMAR
38
39 CF_ADDTO(proto, radv_proto)
40
41 radv_proto_start: proto_start RADV
42 {
43 this_proto = proto_config_new(&proto_radv, $1);
44
45 init_list(&RADV_CFG->patt_list);
46 init_list(&RADV_CFG->pref_list);
47 init_list(&RADV_CFG->rdnss_list);
48 init_list(&RADV_CFG->dnssl_list);
49 };
50
51 radv_proto_item:
52 proto_item
53 | proto_channel
54 | INTERFACE radv_iface
55 | PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); }
56 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); }
57 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); }
58 | TRIGGER net_ip6 { RADV_CFG->trigger = $2; }
59 ;
60
61 radv_proto_opts:
62 /* empty */
63 | radv_proto_opts radv_proto_item ';'
64 ;
65
66 radv_proto:
67 radv_proto_start proto_name '{' radv_proto_opts '}';
68
69
70 radv_iface_start:
71 {
72 this_ipatt = cfg_allocz(sizeof(struct radv_iface_config));
73 add_tail(&RADV_CFG->patt_list, NODE this_ipatt);
74 init_list(&this_ipatt->ipn_list);
75 init_list(&RADV_IFACE->pref_list);
76 init_list(&RADV_IFACE->rdnss_list);
77 init_list(&RADV_IFACE->dnssl_list);
78
79 RADV_IFACE->min_ra_int = -1; /* undefined */
80 RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT;
81 RADV_IFACE->min_delay = DEFAULT_MIN_DELAY;
82 RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT;
83 RADV_IFACE->default_lifetime = -1;
84 RADV_IFACE->default_lifetime_sensitive = 1;
85 RADV_IFACE->default_preference = RA_PREF_MEDIUM;
86 };
87
88 radv_iface_item:
89 MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); }
90 | 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"); }
91 | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); }
92 | MANAGED bool { RADV_IFACE->managed = $2; }
93 | OTHER CONFIG bool { RADV_IFACE->other_config = $3; }
94 | LINK MTU expr { RADV_IFACE->link_mtu = $3; if ($3 < 0) cf_error("Link MTU must be 0 or positive"); }
95 | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if (($3 < 0) || ($3 > 3600000)) cf_error("Reachable time must be in range 0-3600000"); }
96 | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; if ($3 < 0) cf_error("Retrans timer must be 0 or positive"); }
97 | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if (($4 < 0) || ($4 > 255)) cf_error("Current hop limit must be in range 0-255"); }
98 | DEFAULT LIFETIME expr radv_sensitive {
99 RADV_IFACE->default_lifetime = $3;
100 if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000");
101 if ($4 != -1) RADV_IFACE->default_lifetime_sensitive = $4;
102 }
103 | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
104 | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
105 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); }
106 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); }
107 | RDNSS LOCAL bool { RADV_IFACE->rdnss_local = $3; }
108 | DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; }
109 ;
110
111 radv_preference:
112 LOW { $$ = RA_PREF_LOW; }
113 | MEDIUM { $$ = RA_PREF_MEDIUM; }
114 | HIGH { $$ = RA_PREF_HIGH; }
115
116 radv_iface_finish:
117 {
118 struct radv_iface_config *ic = RADV_IFACE;
119
120 if (ic->min_ra_int == (u32) -1)
121 ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3);
122
123 if (ic->default_lifetime == (u32) -1)
124 ic->default_lifetime = 3 * ic->max_ra_int;
125
126 if ((ic->min_ra_int > 3) &&
127 (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
128 cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int);
129
130 if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
131 cf_error("Default lifetime must be either 0 or at least Max RA interval");
132 };
133
134
135 radv_iface_opts:
136 /* empty */
137 | radv_iface_opts radv_iface_item ';'
138 ;
139
140 radv_iface_opt_list:
141 /* empty */
142 | '{' radv_iface_opts '}'
143 ;
144
145 radv_iface:
146 radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish;
147
148
149 radv_prefix_start: net_ip6
150 {
151 this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
152 RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1);
153
154 RADV_PREFIX->onlink = 1;
155 RADV_PREFIX->autonomous = 1;
156 RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME;
157 RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME;
158 };
159
160 radv_prefix_item:
161 SKIP bool { RADV_PREFIX->skip = $2; }
162 | ONLINK bool { RADV_PREFIX->onlink = $2; }
163 | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
164 | VALID LIFETIME expr radv_sensitive {
165 RADV_PREFIX->valid_lifetime = $3;
166 if ($3 < 0) cf_error("Valid lifetime must be 0 or positive");
167 if ($4 != -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
168 }
169 | PREFERRED LIFETIME expr radv_sensitive {
170 RADV_PREFIX->preferred_lifetime = $3;
171 if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive");
172 if ($4 != -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
173 }
174 ;
175
176 radv_prefix_finish:
177 {
178 if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime)
179 cf_error("Preferred lifetime must be at most Valid lifetime");
180
181 if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive)
182 cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too");
183 };
184
185 radv_prefix_opts:
186 /* empty */
187 | radv_prefix_opts radv_prefix_item ';'
188 ;
189
190 radv_prefix_opt_list:
191 /* empty */
192 | '{' radv_prefix_opts '}'
193 ;
194
195 radv_prefix:
196 radv_prefix_start radv_prefix_opt_list radv_prefix_finish;
197
198
199
200 radv_rdnss_node: ipa
201 {
202 struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config));
203 add_tail(&radv_dns_list, NODE cf);
204
205 cf->server = $1;
206 cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
207 };
208
209 radv_rdnss_start:
210 {
211 RADV_RDNSS->lifetime = 0;
212 RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
213 };
214
215 radv_rdnss_item:
216 | NS radv_rdnss_node
217 | LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; }
218 ;
219
220 radv_rdnss_finish:
221 {
222 if (EMPTY_LIST(radv_dns_list))
223 cf_error("No nameserver in RDNSS section");
224
225 struct radv_rdnss_config *cf;
226 WALK_LIST(cf, radv_dns_list)
227 {
228 cf->lifetime = RADV_RDNSS->lifetime;
229 cf->lifetime_mult = RADV_RDNSS->lifetime_mult;
230 }
231 };
232
233 radv_rdnss_opts:
234 /* empty */
235 | radv_rdnss_opts radv_rdnss_item ';'
236 ;
237
238 radv_rdnss:
239 radv_rdnss_node
240 | '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish
241 ;
242
243
244 radv_dnssl_node: TEXT
245 {
246 struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config));
247 add_tail(&radv_dns_list, NODE cf);
248
249 cf->domain = $1;
250 cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
251
252 if (radv_process_domain(cf) < 0)
253 cf_error("Invalid domain dame");
254 };
255
256 radv_dnssl_start:
257 {
258 RADV_DNSSL->lifetime = 0;
259 RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
260 };
261
262 radv_dnssl_item:
263 | DOMAIN radv_dnssl_node
264 | LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; }
265 ;
266
267 radv_dnssl_finish:
268 {
269 if (EMPTY_LIST(radv_dns_list))
270 cf_error("No domain in DNSSL section");
271
272 struct radv_dnssl_config *cf;
273 WALK_LIST(cf, radv_dns_list)
274 {
275 cf->lifetime = RADV_DNSSL->lifetime;
276 cf->lifetime_mult = RADV_DNSSL->lifetime_mult;
277 }
278 };
279
280 radv_dnssl_opts:
281 /* empty */
282 | radv_dnssl_opts radv_dnssl_item ';'
283 ;
284
285 radv_dnssl:
286 radv_dnssl_node
287 | '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish
288 ;
289
290
291 radv_mult:
292 expr { $$ = $1; radv_mult_val = 0; }
293 | MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); }
294 ;
295
296 radv_sensitive:
297 /* empty */ { $$ = -1; }
298 | SENSITIVE bool { $$ = $2; }
299 ;
300
301 CF_CODE
302
303 CF_END