iof-bird-daemon / proto / radv / config.Y @ 04632fd7
History | View | Annotate | Download (8.68 KB)
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 |
init_list(&RADV_CFG->patt_list); |
45 |
init_list(&RADV_CFG->pref_list); |
46 |
init_list(&RADV_CFG->rdnss_list); |
47 |
init_list(&RADV_CFG->dnssl_list); |
48 |
}; |
49 |
|
50 |
radv_proto_item: |
51 |
proto_item |
52 |
| INTERFACE radv_iface |
53 |
| PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); } |
54 |
| RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); } |
55 |
| DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); } |
56 |
| TRIGGER net_any { |
57 |
RADV_CFG->trigger = $2; |
58 |
RADV_CFG->trigger_valid = 1; |
59 |
} |
60 |
; |
61 |
|
62 |
radv_proto_opts: |
63 |
/* empty */ |
64 |
| radv_proto_opts radv_proto_item ';' |
65 |
; |
66 |
|
67 |
radv_proto: |
68 |
radv_proto_start proto_name '{' radv_proto_opts '}'; |
69 |
|
70 |
|
71 |
radv_iface_start: |
72 |
{ |
73 |
this_ipatt = cfg_allocz(sizeof(struct radv_iface_config)); |
74 |
add_tail(&RADV_CFG->patt_list, NODE this_ipatt); |
75 |
init_list(&this_ipatt->ipn_list); |
76 |
init_list(&RADV_IFACE->pref_list); |
77 |
init_list(&RADV_IFACE->rdnss_list); |
78 |
init_list(&RADV_IFACE->dnssl_list); |
79 |
|
80 |
RADV_IFACE->min_ra_int = -1; /* undefined */ |
81 |
RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT; |
82 |
RADV_IFACE->min_delay = DEFAULT_MIN_DELAY; |
83 |
RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT; |
84 |
RADV_IFACE->default_lifetime = -1; |
85 |
RADV_IFACE->default_lifetime_sensitive = 1; |
86 |
RADV_IFACE->default_preference = RA_PREF_MEDIUM; |
87 |
}; |
88 |
|
89 |
radv_iface_item: |
90 |
MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); } |
91 |
| 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"); } |
92 |
| MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); } |
93 |
| MANAGED bool { RADV_IFACE->managed = $2; } |
94 |
| OTHER CONFIG bool { RADV_IFACE->other_config = $3; } |
95 |
| LINK MTU expr { RADV_IFACE->link_mtu = $3; if ($3 < 0) cf_error("Link MTU must be 0 or positive"); } |
96 |
| REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if (($3 < 0) || ($3 > 3600000)) cf_error("Reachable time must be in range 0-3600000"); } |
97 |
| RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; if ($3 < 0) cf_error("Retrans timer must be 0 or positive"); } |
98 |
| 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"); } |
99 |
| DEFAULT LIFETIME expr radv_sensitive { |
100 |
RADV_IFACE->default_lifetime = $3; |
101 |
if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000"); |
102 |
if ($4 != -1) RADV_IFACE->default_lifetime_sensitive = $4; |
103 |
} |
104 |
| DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; } |
105 |
| PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); } |
106 |
| RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); } |
107 |
| DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); } |
108 |
| RDNSS LOCAL bool { RADV_IFACE->rdnss_local = $3; } |
109 |
| DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; } |
110 |
; |
111 |
|
112 |
radv_preference: |
113 |
LOW { $$ = RA_PREF_LOW; } |
114 |
| MEDIUM { $$ = RA_PREF_MEDIUM; } |
115 |
| HIGH { $$ = RA_PREF_HIGH; } |
116 |
|
117 |
radv_iface_finish: |
118 |
{ |
119 |
struct radv_iface_config *ic = RADV_IFACE; |
120 |
|
121 |
if (ic->min_ra_int == (u32) -1) |
122 |
ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3); |
123 |
|
124 |
if (ic->default_lifetime == (u32) -1) |
125 |
ic->default_lifetime = 3 * ic->max_ra_int; |
126 |
|
127 |
if ((ic->min_ra_int > 3) && |
128 |
(ic->min_ra_int > (ic->max_ra_int * 3 / 4))) |
129 |
cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int); |
130 |
|
131 |
if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int)) |
132 |
cf_error("Default lifetime must be either 0 or at least Max RA interval"); |
133 |
}; |
134 |
|
135 |
|
136 |
radv_iface_opts: |
137 |
/* empty */ |
138 |
| radv_iface_opts radv_iface_item ';' |
139 |
; |
140 |
|
141 |
radv_iface_opt_list: |
142 |
/* empty */ |
143 |
| '{' radv_iface_opts '}' |
144 |
; |
145 |
|
146 |
radv_iface: |
147 |
radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish; |
148 |
|
149 |
|
150 |
radv_prefix_start: net_ip6 |
151 |
{ |
152 |
this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config)); |
153 |
RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1); |
154 |
|
155 |
RADV_PREFIX->onlink = 1; |
156 |
RADV_PREFIX->autonomous = 1; |
157 |
RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME; |
158 |
RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME; |
159 |
}; |
160 |
|
161 |
radv_prefix_item: |
162 |
SKIP bool { RADV_PREFIX->skip = $2; } |
163 |
| ONLINK bool { RADV_PREFIX->onlink = $2; } |
164 |
| AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; } |
165 |
| VALID LIFETIME expr radv_sensitive { |
166 |
RADV_PREFIX->valid_lifetime = $3; |
167 |
if ($3 < 0) cf_error("Valid lifetime must be 0 or positive"); |
168 |
if ($4 != -1) RADV_PREFIX->valid_lifetime_sensitive = $4; |
169 |
} |
170 |
| PREFERRED LIFETIME expr radv_sensitive { |
171 |
RADV_PREFIX->preferred_lifetime = $3; |
172 |
if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive"); |
173 |
if ($4 != -1) RADV_PREFIX->preferred_lifetime_sensitive = $4; |
174 |
} |
175 |
; |
176 |
|
177 |
radv_prefix_finish: |
178 |
{ |
179 |
if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime) |
180 |
cf_error("Preferred lifetime must be at most Valid lifetime"); |
181 |
|
182 |
if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive) |
183 |
cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too"); |
184 |
}; |
185 |
|
186 |
radv_prefix_opts: |
187 |
/* empty */ |
188 |
| radv_prefix_opts radv_prefix_item ';' |
189 |
; |
190 |
|
191 |
radv_prefix_opt_list: |
192 |
/* empty */ |
193 |
| '{' radv_prefix_opts '}' |
194 |
; |
195 |
|
196 |
radv_prefix: |
197 |
radv_prefix_start radv_prefix_opt_list radv_prefix_finish; |
198 |
|
199 |
|
200 |
|
201 |
radv_rdnss_node: ipa |
202 |
{ |
203 |
struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config)); |
204 |
add_tail(&radv_dns_list, NODE cf); |
205 |
|
206 |
cf->server = $1; |
207 |
cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; |
208 |
}; |
209 |
|
210 |
radv_rdnss_start: |
211 |
{ |
212 |
RADV_RDNSS->lifetime = 0; |
213 |
RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; |
214 |
}; |
215 |
|
216 |
radv_rdnss_item: |
217 |
| NS radv_rdnss_node |
218 |
| LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; } |
219 |
; |
220 |
|
221 |
radv_rdnss_finish: |
222 |
{ |
223 |
if (EMPTY_LIST(radv_dns_list)) |
224 |
cf_error("No nameserver in RDNSS section"); |
225 |
|
226 |
struct radv_rdnss_config *cf; |
227 |
WALK_LIST(cf, radv_dns_list) |
228 |
{ |
229 |
cf->lifetime = RADV_RDNSS->lifetime; |
230 |
cf->lifetime_mult = RADV_RDNSS->lifetime_mult; |
231 |
} |
232 |
}; |
233 |
|
234 |
radv_rdnss_opts: |
235 |
/* empty */ |
236 |
| radv_rdnss_opts radv_rdnss_item ';' |
237 |
; |
238 |
|
239 |
radv_rdnss: |
240 |
radv_rdnss_node |
241 |
| '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish |
242 |
; |
243 |
|
244 |
|
245 |
radv_dnssl_node: TEXT |
246 |
{ |
247 |
struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config)); |
248 |
add_tail(&radv_dns_list, NODE cf); |
249 |
|
250 |
cf->domain = $1; |
251 |
cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; |
252 |
|
253 |
if (radv_process_domain(cf) < 0) |
254 |
cf_error("Invalid domain dame"); |
255 |
}; |
256 |
|
257 |
radv_dnssl_start: |
258 |
{ |
259 |
RADV_DNSSL->lifetime = 0; |
260 |
RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT; |
261 |
}; |
262 |
|
263 |
radv_dnssl_item: |
264 |
| DOMAIN radv_dnssl_node |
265 |
| LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; } |
266 |
; |
267 |
|
268 |
radv_dnssl_finish: |
269 |
{ |
270 |
if (EMPTY_LIST(radv_dns_list)) |
271 |
cf_error("No domain in DNSSL section"); |
272 |
|
273 |
struct radv_dnssl_config *cf; |
274 |
WALK_LIST(cf, radv_dns_list) |
275 |
{ |
276 |
cf->lifetime = RADV_DNSSL->lifetime; |
277 |
cf->lifetime_mult = RADV_DNSSL->lifetime_mult; |
278 |
} |
279 |
}; |
280 |
|
281 |
radv_dnssl_opts: |
282 |
/* empty */ |
283 |
| radv_dnssl_opts radv_dnssl_item ';' |
284 |
; |
285 |
|
286 |
radv_dnssl: |
287 |
radv_dnssl_node |
288 |
| '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish |
289 |
; |
290 |
|
291 |
|
292 |
radv_mult: |
293 |
expr { $$ = $1; radv_mult_val = 0; } |
294 |
| MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); } |
295 |
; |
296 |
|
297 |
radv_sensitive: |
298 |
/* empty */ { $$ = -1; } |
299 |
| SENSITIVE bool { $$ = $2; } |
300 |
; |
301 |
|
302 |
CF_CODE |
303 |
|
304 |
CF_END |