Statistics
| Branch: | Revision:

iof-bird-daemon / proto / radv / config.Y @ 48e5f32d

History | View | Annotate | Download (8.48 KB)

1 93e868c7 Ondrej Zajicek
/*
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 fc06fb62 Ondrej Zajicek
#define RADV_RDNSS (&this_radv_rdnss)
18
#define RADV_DNSSL (&this_radv_dnssl)
19 93e868c7 Ondrej Zajicek
20
static struct radv_prefix_config *this_radv_prefix;
21 fc06fb62 Ondrej Zajicek
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 93e868c7 Ondrej Zajicek
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 fc06fb62 Ondrej Zajicek
	TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, MULT,
32
	LIFETIME, SKIP, ONLINK, AUTONOMOUS, RDNSS, DNSSL, NS, DOMAIN,
33 36da2857 Ondrej Zajicek
	LOCAL, TRIGGER, SENSITIVE)
34 93e868c7 Ondrej Zajicek
35 36da2857 Ondrej Zajicek
%type<i> radv_mult radv_sensitive
36 93e868c7 Ondrej Zajicek
37
CF_GRAMMAR
38
39 fc06fb62 Ondrej Zajicek
CF_ADDTO(proto, radv_proto)
40 93e868c7 Ondrej Zajicek
41
radv_proto_start: proto_start RADV
42
{
43 2779d50a Ondrej Zajicek
  this_proto = proto_config_new(&proto_radv, sizeof(struct radv_config), $1);
44 93e868c7 Ondrej Zajicek
  init_list(&RADV_CFG->patt_list);
45
  init_list(&RADV_CFG->pref_list);
46 fc06fb62 Ondrej Zajicek
  init_list(&RADV_CFG->rdnss_list);
47
  init_list(&RADV_CFG->dnssl_list);
48 93e868c7 Ondrej Zajicek
};
49
50
radv_proto_item:
51
   proto_item
52
 | INTERFACE radv_iface
53 fc06fb62 Ondrej Zajicek
 | 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 36da2857 Ondrej Zajicek
 | TRIGGER prefix {
57
     RADV_CFG->trigger_prefix = $2.addr;
58
     RADV_CFG->trigger_pxlen = $2.len;
59
     RADV_CFG->trigger_valid = 1;
60
   }
61 93e868c7 Ondrej Zajicek
 ;
62
63
radv_proto_opts:
64
   /* empty */
65
 | radv_proto_opts radv_proto_item ';'
66
 ;
67
68
radv_proto:
69 fc06fb62 Ondrej Zajicek
   radv_proto_start proto_name '{' radv_proto_opts '}';
70 93e868c7 Ondrej Zajicek
71
72
radv_iface_start:
73
{
74
  this_ipatt = cfg_allocz(sizeof(struct radv_iface_config));
75
  add_tail(&RADV_CFG->patt_list, NODE this_ipatt);
76
  init_list(&this_ipatt->ipn_list);
77
  init_list(&RADV_IFACE->pref_list);
78 fc06fb62 Ondrej Zajicek
  init_list(&RADV_IFACE->rdnss_list);
79
  init_list(&RADV_IFACE->dnssl_list);
80 93e868c7 Ondrej Zajicek
81
  RADV_IFACE->min_ra_int = -1; /* undefined */
82
  RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT;
83
  RADV_IFACE->min_delay = DEFAULT_MIN_DELAY;
84
  RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT;
85
  RADV_IFACE->default_lifetime = -1;
86 36da2857 Ondrej Zajicek
  RADV_IFACE->default_lifetime_sensitive = 1;
87 93e868c7 Ondrej Zajicek
};
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 36da2857 Ondrej Zajicek
 | 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 93e868c7 Ondrej Zajicek
 | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
105 fc06fb62 Ondrej Zajicek
 | 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 93e868c7 Ondrej Zajicek
 ;
110
111
radv_iface_finish:
112
{
113
  struct radv_iface_config *ic = RADV_IFACE;
114
115
  if (ic->min_ra_int == (u32) -1)
116 41f8bf57 Ondrej Zajicek
    ic->min_ra_int = MAX_(ic->max_ra_int / 3, 3);
117 93e868c7 Ondrej Zajicek
118
  if (ic->default_lifetime == (u32) -1)
119
    ic->default_lifetime = 3 * ic->max_ra_int;
120
121
  if ((ic->min_ra_int > 3) &&
122
      (ic->min_ra_int > (ic->max_ra_int * 3 / 4)))
123
    cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int);
124
125
  if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int))
126
    cf_error("Default lifetime must be either 0 or at least Max RA interval");
127
};
128
129
130
radv_iface_opts:
131
   /* empty */
132
 | radv_iface_opts radv_iface_item ';'
133
 ;
134
135
radv_iface_opt_list:
136
   /* empty */
137
 | '{' radv_iface_opts '}'
138
 ;
139
140
radv_iface:
141
  radv_iface_start iface_patt_list radv_iface_opt_list radv_iface_finish;
142
143
144
radv_prefix_start: prefix
145
{
146
  this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
147
  RADV_PREFIX->prefix = $1.addr;
148
  RADV_PREFIX->pxlen = $1.len;
149
150
  RADV_PREFIX->onlink = 1;
151
  RADV_PREFIX->autonomous = 1;
152
  RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME;
153
  RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME;
154
};
155
156
radv_prefix_item:
157
   SKIP bool { RADV_PREFIX->skip = $2; }
158
 | ONLINK bool { RADV_PREFIX->onlink = $2; }
159
 | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; }
160 36da2857 Ondrej Zajicek
 | VALID LIFETIME expr radv_sensitive {
161
     RADV_PREFIX->valid_lifetime = $3;
162
     if ($3 < 0) cf_error("Valid lifetime must be 0 or positive");
163
     if ($4 != -1) RADV_PREFIX->valid_lifetime_sensitive = $4;
164
   }
165
 | PREFERRED LIFETIME expr radv_sensitive {
166
     RADV_PREFIX->preferred_lifetime = $3;
167
     if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive");
168
     if ($4 != -1) RADV_PREFIX->preferred_lifetime_sensitive = $4;
169
   }
170 93e868c7 Ondrej Zajicek
 ;
171
172
radv_prefix_finish:
173
{
174
  if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime)
175
    cf_error("Preferred lifetime must be at most Valid lifetime");
176 36da2857 Ondrej Zajicek
177
  if (RADV_PREFIX->valid_lifetime_sensitive > RADV_PREFIX->preferred_lifetime_sensitive)
178
    cf_error("Valid lifetime sensitive requires that Preferred lifetime is sensitive too");
179 93e868c7 Ondrej Zajicek
};
180
181
radv_prefix_opts:
182
   /* empty */
183
 | radv_prefix_opts radv_prefix_item ';'
184
 ;
185
186
radv_prefix_opt_list:
187
   /* empty */
188
 | '{' radv_prefix_opts '}'
189
 ;
190
191
radv_prefix:
192
  radv_prefix_start radv_prefix_opt_list radv_prefix_finish;
193
194
195 fc06fb62 Ondrej Zajicek
196
radv_rdnss_node: ipa
197
{
198
  struct radv_rdnss_config *cf = cfg_allocz(sizeof(struct radv_rdnss_config));
199
  add_tail(&radv_dns_list, NODE cf);
200
201
  cf->server = $1;
202
  cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
203
};
204
205
radv_rdnss_start:
206
{
207
  RADV_RDNSS->lifetime = 0;
208
  RADV_RDNSS->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
209
};
210
211
radv_rdnss_item:
212
 | NS radv_rdnss_node
213
 | LIFETIME radv_mult { RADV_RDNSS->lifetime = $2; RADV_RDNSS->lifetime_mult = radv_mult_val; }
214
 ;
215
216
radv_rdnss_finish:
217
{
218
  if (EMPTY_LIST(radv_dns_list))
219
    cf_error("No nameserver in RDNSS section");
220
221
  struct radv_rdnss_config *cf;
222
  WALK_LIST(cf, radv_dns_list)
223
  {
224
    cf->lifetime = RADV_RDNSS->lifetime;
225
    cf->lifetime_mult = RADV_RDNSS->lifetime_mult;
226
  }
227
};
228
229
radv_rdnss_opts:
230
   /* empty */
231
 | radv_rdnss_opts radv_rdnss_item ';'
232
 ;
233
234
radv_rdnss:
235
   radv_rdnss_node
236
 | '{' radv_rdnss_start radv_rdnss_opts '}' radv_rdnss_finish
237
 ;
238
239
240
radv_dnssl_node: TEXT
241
{
242
  struct radv_dnssl_config *cf = cfg_allocz(sizeof(struct radv_dnssl_config));
243
  add_tail(&radv_dns_list, NODE cf);
244
245
  cf->domain = $1;
246
  cf->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
247
248
  if (radv_process_domain(cf) < 0)
249
    cf_error("Invalid domain dame");
250
};
251
252
radv_dnssl_start:
253
{
254
  RADV_DNSSL->lifetime = 0;
255
  RADV_DNSSL->lifetime_mult = DEFAULT_DNS_LIFETIME_MULT;
256
};
257
258
radv_dnssl_item:
259
 | DOMAIN radv_dnssl_node
260
 | LIFETIME radv_mult { RADV_DNSSL->lifetime = $2; RADV_DNSSL->lifetime_mult = radv_mult_val; }
261
 ;
262
263
radv_dnssl_finish:
264
{
265
  if (EMPTY_LIST(radv_dns_list))
266
    cf_error("No domain in DNSSL section");
267
268
  struct radv_dnssl_config *cf;
269
  WALK_LIST(cf, radv_dns_list)
270
  {
271
    cf->lifetime = RADV_DNSSL->lifetime;
272
    cf->lifetime_mult = RADV_DNSSL->lifetime_mult;
273
  }
274
};
275
276
radv_dnssl_opts:
277
   /* empty */
278
 | radv_dnssl_opts radv_dnssl_item ';'
279
 ;
280
281
radv_dnssl:
282
   radv_dnssl_node
283
 | '{' radv_dnssl_start radv_dnssl_opts '}' radv_dnssl_finish
284
 ;
285
286
287
radv_mult:
288
   expr { $$ = $1; radv_mult_val = 0; }
289
 | MULT expr { $$ = 0; radv_mult_val = $2; if (($2 < 1) || ($2 > 254)) cf_error("Multiplier must be in range 1-254"); }
290
 ;
291
292 36da2857 Ondrej Zajicek
radv_sensitive:
293 155134f3 Ondrej Filip
   /* empty */ { $$ = -1; }
294
 | SENSITIVE bool { $$ = $2; }
295 36da2857 Ondrej Zajicek
 ;
296
297 93e868c7 Ondrej Zajicek
CF_CODE
298
299
CF_END