Statistics
| Branch: | Revision:

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