]>
Commit | Line | Data |
---|---|---|
93e868c7 OZ |
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 | ||
18 | static struct radv_prefix_config *this_radv_prefix; | |
19 | ||
20 | CF_DECLS | |
21 | ||
22 | CF_KEYWORDS(RADV, PREFIX, INTERFACE, MIN, MAX, RA, DELAY, INTERVAL, | |
23 | MANAGED, OTHER, CONFIG, LINK, MTU, REACHABLE, TIME, RETRANS, | |
24 | TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, | |
25 | LIFETIME, SKIP, ONLINK, AUTONOMOUS) | |
26 | ||
27 | ||
28 | CF_GRAMMAR | |
29 | ||
30 | CF_ADDTO(proto, radv_proto '}') | |
31 | ||
32 | radv_proto_start: proto_start RADV | |
33 | { | |
2779d50a | 34 | this_proto = proto_config_new(&proto_radv, sizeof(struct radv_config), $1); |
93e868c7 OZ |
35 | init_list(&RADV_CFG->patt_list); |
36 | init_list(&RADV_CFG->pref_list); | |
37 | }; | |
38 | ||
39 | radv_proto_item: | |
40 | proto_item | |
41 | | PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); } | |
42 | | INTERFACE radv_iface | |
43 | ; | |
44 | ||
45 | radv_proto_opts: | |
46 | /* empty */ | |
47 | | radv_proto_opts radv_proto_item ';' | |
48 | ; | |
49 | ||
50 | radv_proto: | |
51 | radv_proto_start proto_name '{' radv_proto_opts; | |
52 | ||
53 | ||
54 | radv_iface_start: | |
55 | { | |
56 | this_ipatt = cfg_allocz(sizeof(struct radv_iface_config)); | |
57 | add_tail(&RADV_CFG->patt_list, NODE this_ipatt); | |
58 | init_list(&this_ipatt->ipn_list); | |
59 | init_list(&RADV_IFACE->pref_list); | |
60 | ||
61 | RADV_IFACE->min_ra_int = -1; /* undefined */ | |
62 | RADV_IFACE->max_ra_int = DEFAULT_MAX_RA_INT; | |
63 | RADV_IFACE->min_delay = DEFAULT_MIN_DELAY; | |
64 | RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT; | |
65 | RADV_IFACE->default_lifetime = -1; | |
66 | }; | |
67 | ||
68 | radv_iface_item: | |
69 | MIN RA INTERVAL expr { RADV_IFACE->min_ra_int = $4; if ($4 < 3) cf_error("Min RA interval must be at least 3"); } | |
70 | | 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"); } | |
71 | | MIN DELAY expr { RADV_IFACE->min_delay = $3; if ($3 <= 0) cf_error("Min delay must be positive"); } | |
72 | | MANAGED bool { RADV_IFACE->managed = $2; } | |
73 | | OTHER CONFIG bool { RADV_IFACE->other_config = $3; } | |
74 | | LINK MTU expr { RADV_IFACE->link_mtu = $3; if ($3 < 0) cf_error("Link MTU must be 0 or positive"); } | |
75 | | REACHABLE TIME expr { RADV_IFACE->reachable_time = $3; if (($3 < 0) || ($3 > 3600000)) cf_error("Reachable time must be in range 0-3600000"); } | |
76 | | RETRANS TIMER expr { RADV_IFACE->retrans_timer = $3; if ($3 < 0) cf_error("Retrans timer must be 0 or positive"); } | |
77 | | 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"); } | |
78 | | DEFAULT LIFETIME expr { RADV_IFACE->default_lifetime = $3; if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000"); } | |
79 | | PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); } | |
80 | ; | |
81 | ||
82 | radv_iface_finish: | |
83 | { | |
84 | struct radv_iface_config *ic = RADV_IFACE; | |
85 | ||
86 | if (ic->min_ra_int == (u32) -1) | |
87 | ic->min_ra_int = _MAX(ic->max_ra_int / 3, 3); | |
88 | ||
89 | if (ic->default_lifetime == (u32) -1) | |
90 | ic->default_lifetime = 3 * ic->max_ra_int; | |
91 | ||
92 | if ((ic->min_ra_int > 3) && | |
93 | (ic->min_ra_int > (ic->max_ra_int * 3 / 4))) | |
94 | cf_error("Min RA interval must be at most 3/4 * Max RA interval %d %d", ic->min_ra_int, ic->max_ra_int); | |
95 | ||
96 | if ((ic->default_lifetime > 0) && (ic->default_lifetime < ic->max_ra_int)) | |
97 | cf_error("Default lifetime must be either 0 or at least Max RA interval"); | |
98 | }; | |
99 | ||
100 | ||
101 | radv_iface_opts: | |
102 | /* empty */ | |
103 | | radv_iface_opts radv_iface_item ';' | |
104 | ; | |
105 | ||
106 | radv_iface_opt_list: | |
107 | /* empty */ | |
108 | | '{' radv_iface_opts '}' | |
109 | ; | |
110 | ||
111 | radv_iface: | |
112 | radv_iface_start iface_patt_list radv_iface_opt_list radv_iface_finish; | |
113 | ||
114 | ||
115 | radv_prefix_start: prefix | |
116 | { | |
117 | this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config)); | |
118 | RADV_PREFIX->prefix = $1.addr; | |
119 | RADV_PREFIX->pxlen = $1.len; | |
120 | ||
121 | RADV_PREFIX->onlink = 1; | |
122 | RADV_PREFIX->autonomous = 1; | |
123 | RADV_PREFIX->valid_lifetime = DEFAULT_VALID_LIFETIME; | |
124 | RADV_PREFIX->preferred_lifetime = DEFAULT_PREFERRED_LIFETIME; | |
125 | }; | |
126 | ||
127 | radv_prefix_item: | |
128 | SKIP bool { RADV_PREFIX->skip = $2; } | |
129 | | ONLINK bool { RADV_PREFIX->onlink = $2; } | |
130 | | AUTONOMOUS bool { RADV_PREFIX->autonomous = $2; } | |
131 | | VALID LIFETIME expr { RADV_PREFIX->valid_lifetime = $3; if ($3 < 0) cf_error("Valid lifetime must be 0 or positive"); } | |
132 | | PREFERRED LIFETIME expr { RADV_PREFIX->preferred_lifetime = $3; if ($3 < 0) cf_error("Preferred lifetime must be 0 or positive"); } | |
133 | ; | |
134 | ||
135 | radv_prefix_finish: | |
136 | { | |
137 | if (RADV_PREFIX->preferred_lifetime > RADV_PREFIX->valid_lifetime) | |
138 | cf_error("Preferred lifetime must be at most Valid lifetime"); | |
139 | }; | |
140 | ||
141 | radv_prefix_opts: | |
142 | /* empty */ | |
143 | | radv_prefix_opts radv_prefix_item ';' | |
144 | ; | |
145 | ||
146 | radv_prefix_opt_list: | |
147 | /* empty */ | |
148 | | '{' radv_prefix_opts '}' | |
149 | ; | |
150 | ||
151 | radv_prefix: | |
152 | radv_prefix_start radv_prefix_opt_list radv_prefix_finish; | |
153 | ||
154 | ||
155 | CF_CODE | |
156 | ||
157 | CF_END |