Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / proto / radv / config.Y @ 6b3f1a54

History | View | Annotate | Download (10.1 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, LINGER, 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, PROPAGATE,
34
	ROUTE, ROUTES, RA_PREFERENCE, RA_LIFETIME)
35

    
36
CF_ENUM(T_ENUM_RA_PREFERENCE, RA_PREF_, LOW, MEDIUM, HIGH)
37

    
38
%type<i> radv_mult radv_sensitive radv_preference
39

    
40
CF_GRAMMAR
41

    
42
CF_ADDTO(proto, radv_proto)
43

    
44
radv_proto_start: proto_start RADV
45
{
46
  this_proto = proto_config_new(&proto_radv, $1);
47

    
48
  init_list(&RADV_CFG->patt_list);
49
  init_list(&RADV_CFG->pref_list);
50
  init_list(&RADV_CFG->rdnss_list);
51
  init_list(&RADV_CFG->dnssl_list);
52
};
53

    
54
radv_proto_item:
55
   proto_item
56
 | proto_channel
57
 | INTERFACE radv_iface
58
 | PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); }
59
 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); }
60
 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); }
61
 | TRIGGER net_ip6 { RADV_CFG->trigger = $2; }
62
 | PROPAGATE ROUTES bool { RADV_CFG->propagate_routes = $3; }
63
 ;
64

    
65
radv_proto_opts:
66
   /* empty */
67
 | radv_proto_opts radv_proto_item ';'
68
 ;
69

    
70
radv_proto:
71
   radv_proto_start proto_name '{' radv_proto_opts '}';
72

    
73

    
74
radv_iface_start:
75
{
76
  this_ipatt = cfg_allocz(sizeof(struct radv_iface_config));
77
  add_tail(&RADV_CFG->patt_list, NODE this_ipatt);
78
  init_list(&this_ipatt->ipn_list);
79
  init_list(&RADV_IFACE->pref_list);
80
  init_list(&RADV_IFACE->rdnss_list);
81
  init_list(&RADV_IFACE->dnssl_list);
82

    
83
  RADV_IFACE->min_ra_int = (u32) -1; /* undefined */
84
  RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT;
85
  RADV_IFACE->min_delay = DEFAULT_MIN_DELAY;
86
  RADV_IFACE->prefix_linger_time = (u32) -1;
87
  RADV_IFACE->route_linger_time = (u32) -1;
88
  RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT;
89
  RADV_IFACE->default_lifetime = (u32) -1;
90
  RADV_IFACE->default_lifetime_sensitive = 1;
91
  RADV_IFACE->default_preference = RA_PREF_MEDIUM;
92
  RADV_IFACE->route_lifetime = (u32) -1;
93
  RADV_IFACE->route_lifetime_sensitive = 0;
94
  RADV_IFACE->route_preference = RA_PREF_MEDIUM;
95
};
96

    
97
radv_iface_item:
98
   MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); }
99
 | 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"); }
100
 | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); }
101
 | MANAGED bool { RADV_IFACE->managed = $2; }
102
 | OTHER CONFIG bool { RADV_IFACE->other_config = $3; }
103
 | LINK MTU expr { RADV_IFACE->link_mtu = $3; }
104
 | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if ($3 > 3600000) cf_error("Reachable time must be in range 0-3600000"); }
105
 | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; }
106
 | CURRENT HOP LIMIT expr { RADV_IFACE->current_hop_limit = $4; if ($4 > 255) cf_error("Current hop limit must be in range 0-255"); }
107
 | DEFAULT LIFETIME expr radv_sensitive {
108
     RADV_IFACE->default_lifetime = $3;
109
     if ($3 > 9000)  cf_error("Default lifetime must be in range 0-9000");
110
     if ($4 != (uint) -1) RADV_IFACE->default_lifetime_sensitive = $4;
111
   }
112
 | ROUTE LIFETIME expr radv_sensitive {
113
     RADV_IFACE->route_lifetime = $3;
114
     if ($4 != (uint) -1) RADV_IFACE->route_lifetime_sensitive = $4;
115
   }
116
 | DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
117
 | ROUTE PREFERENCE radv_preference { RADV_IFACE->route_preference = $3; }
118
 | PREFIX LINGER TIME expr { RADV_IFACE->prefix_linger_time = $4; }
119
 | ROUTE LINGER TIME expr { RADV_IFACE->route_linger_time = $4; }
120
 | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
121
 | RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); }
122
 | DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); }
123
 | RDNSS LOCAL bool { RADV_IFACE->rdnss_local = $3; }
124
 | DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; }
125
 ;
126

    
127
radv_preference:
128
   LOW { $$ = RA_PREF_LOW; }
129
 | MEDIUM { $$ = RA_PREF_MEDIUM; }
130
 | HIGH { $$ = RA_PREF_HIGH; }
131

    
132
radv_iface_finish:
133
{
134
  struct radv_iface_config *ic = RADV_IFACE;
135

    
136
  if (ic->min_ra_int == (u32) -1)
137
    ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3);
138

    
139
  if (ic->default_lifetime == (u32) -1)
140
    ic->default_lifetime = 3 * ic->max_ra_int;
141

    
142
  if (ic->route_lifetime == (u32) -1)
143
    ic->route_lifetime = 3 * ic->max_ra_int;
144

    
145
  if (ic->prefix_linger_time == (u32) -1)
146
    ic->prefix_linger_time = 3 * ic->max_ra_int;
147

    
148
  if (ic->route_linger_time == (u32) -1)
149
    ic->route_linger_time = 3 * ic->max_ra_int;
150

    
151
  if ((ic->min_ra_int > 3) &&
152
      (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
153
    cf_error("Min RA interval must be at most 3/4 * Max RA interval");
154

    
155
  if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
156
    cf_error("Default lifetime must be either 0 or at least Max RA interval");
157

    
158
  if ((ic->route_lifetime > 0) && (ic->route_lifetime < ic->max_ra_int))
159
    cf_error("Route lifetime must be either 0 or at least Max RA interval");
160

    
161
  if ((ic->prefix_linger_time > 0) && (ic->prefix_linger_time < ic->max_ra_int))
162
    cf_error("Prefix linger time must be either 0 or at least Max RA interval");
163

    
164
  if ((ic->route_linger_time > 0) && (ic->route_linger_time < ic->max_ra_int))
165
    cf_error("Route linger time must be either 0 or at least Max RA interval");
166

    
167
  RADV_CFG->max_linger_time = MAX_(RADV_CFG->max_linger_time, ic->route_linger_time);
168
};
169

    
170

    
171
radv_iface_opts:
172
   /* empty */
173
 | radv_iface_opts radv_iface_item ';'
174
 ;
175

    
176
radv_iface_opt_list:
177
   /* empty */
178
 | '{' radv_iface_opts '}'
179
 ;
180

    
181
radv_iface:
182
  radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish;
183

    
184

    
185
radv_prefix_start: net_ip6
186
{
187
  this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
188
  RADV_PREFIX->prefix = *(net_addr_ip6 *) &($1);
189

    
190
  RADV_PREFIX->onlink = 1;
191
  RADV_PREFIX->autonomous = 1;
192
  RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME;
193
  RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME;
194
};
195

    
196
radv_prefix_item:
197
   SKIP bool { RADV_PREFIX->skip = $2; }
198
 | ONLINK bool { RADV_PREFIX->onlink = $2; }
199
 | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
200
 | VALID LIFETIME expr radv_sensitive {
201
     RADV_PREFIX->valid_lifetime = $3;
202
     if ($4 != (uint) -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
203
   }
204
 | PREFERRED LIFETIME expr radv_sensitive {
205
     RADV_PREFIX->preferred_lifetime = $3;
206
     if ($4 != (uint) -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
207
   }
208
 ;
209

    
210
radv_prefix_finish:
211
{
212
  if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime)
213
    cf_error("Preferred lifetime must be at most Valid lifetime");
214

    
215
  if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive)
216
    cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too");
217
};
218

    
219
radv_prefix_opts:
220
   /* empty */
221
 | radv_prefix_opts radv_prefix_item ';'
222
 ;
223

    
224
radv_prefix_opt_list:
225
   /* empty */
226
 | '{' radv_prefix_opts '}'
227
 ;
228

    
229
radv_prefix:
230
  radv_prefix_start radv_prefix_opt_list radv_prefix_finish;
231

    
232

    
233

    
234
radv_rdnss_node: ipa
235
{
236
  struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config));
237
  add_tail(&radv_dns_list, NODE cf);
238

    
239
  cf->server = $1;
240
  cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
241
};
242

    
243
radv_rdnss_start:
244
{
245
  RADV_RDNSS->lifetime = 0;
246
  RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
247
};
248

    
249
radv_rdnss_item:
250
 | NS radv_rdnss_node
251
 | LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; }
252
 ;
253

    
254
radv_rdnss_finish:
255
{
256
  if (EMPTY_LIST(radv_dns_list))
257
    cf_error("No nameserver in RDNSS section");
258

    
259
  struct radv_rdnss_config *cf;
260
  WALK_LIST(cf, radv_dns_list)
261
  {
262
    cf->lifetime = RADV_RDNSS->lifetime;
263
    cf->lifetime_mult = RADV_RDNSS->lifetime_mult;
264
  }
265
};
266

    
267
radv_rdnss_opts:
268
   /* empty */
269
 | radv_rdnss_opts radv_rdnss_item ';'
270
 ;
271

    
272
radv_rdnss:
273
   radv_rdnss_node
274
 | '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish
275
 ;
276

    
277

    
278
radv_dnssl_node: TEXT
279
{
280
  struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config));
281
  add_tail(&radv_dns_list, NODE cf);
282

    
283
  cf->domain = $1;
284
  cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
285

    
286
  if (radv_process_domain(cf) < 0)
287
    cf_error("Invalid domain dame");
288
};
289

    
290
radv_dnssl_start:
291
{
292
  RADV_DNSSL->lifetime = 0;
293
  RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
294
};
295

    
296
radv_dnssl_item:
297
 | DOMAIN radv_dnssl_node
298
 | LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; }
299
 ;
300

    
301
radv_dnssl_finish:
302
{
303
  if (EMPTY_LIST(radv_dns_list))
304
    cf_error("No domain in DNSSL section");
305

    
306
  struct radv_dnssl_config *cf;
307
  WALK_LIST(cf, radv_dns_list)
308
  {
309
    cf->lifetime = RADV_DNSSL->lifetime;
310
    cf->lifetime_mult = RADV_DNSSL->lifetime_mult;
311
  }
312
};
313

    
314
radv_dnssl_opts:
315
   /* empty */
316
 | radv_dnssl_opts radv_dnssl_item ';'
317
 ;
318

    
319
radv_dnssl:
320
   radv_dnssl_node
321
 | '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish
322
 ;
323

    
324

    
325
radv_mult:
326
   expr { $$ = $1; radv_mult_val = 0; }
327
 | MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); }
328
 ;
329

    
330
radv_sensitive:
331
   /* empty */ { $$ = (uint) -1; }
332
 | SENSITIVE bool { $$ = $2; }
333
 ;
334

    
335
CF_ADDTO(dynamic_attr, RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); })
336
CF_ADDTO(dynamic_attr, RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); })
337

    
338
CF_CODE
339

    
340
CF_END