1 /*
2 *
3 * Authors:
4 * Lars Fenneberg <lf@elemental.net>
5 *
6 * This software is Copyright 1996,1997 by the above mentioned author(s),
7 * All Rights Reserved.
8 *
9 * The license which is distributed with this software in the file COPYRIGHT
10 * applies to this software. If your distribution is missing this file, you
11 * may request it from <reubenhwk@gmail.com>.
12 *
13 */
14
15 #include "config.h"
16 #include "defaults.h"
17 #include "includes.h"
18 #include "radvd.h"
19
20 #define IFACE_SETUP_DELAY 1
21
iface_init_defaults(struct Interface * iface)22 void iface_init_defaults(struct Interface *iface)
23 {
24 memset(iface, 0, sizeof(struct Interface));
25
26 iface->state_info.changed = 1;
27
28 iface->IgnoreIfMissing = DFLT_IgnoreIfMissing;
29 iface->AdvSendAdvert = DFLT_AdvSendAdv;
30 iface->MaxRtrAdvInterval = DFLT_MaxRtrAdvInterval;
31 iface->AdvSourceLLAddress = DFLT_AdvSourceLLAddress;
32 iface->MinDelayBetweenRAs = DFLT_MinDelayBetweenRAs;
33 iface->MinRtrAdvInterval = -1;
34 iface->UnicastOnly = DFLT_UnicastOnly;
35 iface->AdvRASolicitedUnicast = DFLT_AdvRASolicitedUnicast;
36
37 iface->ra_header_info.AdvDefaultPreference = DFLT_AdvDefaultPreference;
38 iface->ra_header_info.AdvDefaultLifetime = -1;
39 iface->ra_header_info.AdvReachableTime = DFLT_AdvReachableTime;
40 iface->ra_header_info.AdvRetransTimer = DFLT_AdvRetransTimer;
41 iface->ra_header_info.AdvCurHopLimit = DFLT_AdvCurHopLimit;
42 iface->ra_header_info.AdvHomeAgentFlag = DFLT_AdvHomeAgentFlag;
43
44 iface->mipv6.AdvIntervalOpt = DFLT_AdvIntervalOpt;
45 iface->mipv6.AdvHomeAgentInfo = DFLT_AdvHomeAgentInfo;
46 iface->mipv6.HomeAgentPreference = DFLT_HomeAgentPreference;
47 iface->mipv6.AdvMobRtrSupportFlag = DFLT_AdvMobRtrSupportFlag;
48 iface->mipv6.HomeAgentLifetime = -1;
49
50 iface->AdvLinkMTU = DFLT_AdvLinkMTU;
51 iface->AdvRAMTU = DFLT_AdvRAMTU;
52 }
53
touch_iface(struct Interface * iface)54 void touch_iface(struct Interface *iface)
55 {
56 iface->state_info.changed = 1;
57 iface->state_info.ready = 0;
58 iface->state_info.racount = 0;
59 reschedule_iface(iface, 0);
60 }
61
setup_iface(int sock,struct Interface * iface)62 int setup_iface(int sock, struct Interface *iface)
63 {
64 int was_ready = iface->state_info.ready;
65
66 iface->state_info.changed = 0;
67 iface->state_info.ready = 0;
68
69 /* The device index must be setup first so we can search it later */
70 if (update_device_index(iface) < 0) {
71 return -1;
72 }
73
74 /* Check IFF_UP, IFF_RUNNING and IFF_MULTICAST */
75 if (check_device(sock, iface) < 0) {
76 return -1;
77 }
78
79 /* Set iface->max_mtu and iface hardware address */
80 if (update_device_info(sock, iface) < 0) {
81 return -1;
82 }
83
84 /* Make sure the settings in the config file for this interface are ok (this depends
85 * on iface->max_mtu already being set). */
86 if (check_iface(iface) < 0) {
87 return -1;
88 }
89
90 /* Save the first link local address seen on the specified interface to
91 * iface->props.if_addr and keep a list off all addrs in iface->props.if_addrs */
92 if (setup_iface_addrs(iface) < 0) {
93 return -1;
94 }
95
96 /* Check if we a usable RA source address */
97 if (iface->props.if_addr_rasrc == NULL) {
98 dlog(LOG_DEBUG, 5, "no configured AdvRASrcAddress present, skipping send");
99 return -1;
100 }
101
102 iface->state_info.ready = was_ready;
103
104 /* join the allrouters multicast group so we get the solicitations */
105 if (setup_allrouters_membership(sock, iface) < 0) {
106 iface->state_info.ready = 0;
107 return -1;
108 }
109
110 iface->state_info.ready = 1;
111
112 dlog(LOG_DEBUG, 4, "%s is ready", iface->props.name);
113
114 return 0;
115 }
116
prefix_init_defaults(struct AdvPrefix * prefix)117 void prefix_init_defaults(struct AdvPrefix *prefix)
118 {
119 memset(prefix, 0, sizeof(struct AdvPrefix));
120
121 prefix->AdvOnLinkFlag = DFLT_AdvOnLinkFlag;
122 prefix->AdvAutonomousFlag = DFLT_AdvAutonomousFlag;
123 prefix->AdvRouterAddr = DFLT_AdvRouterAddr;
124 prefix->AdvValidLifetime = DFLT_AdvValidLifetime;
125 prefix->AdvPreferredLifetime = DFLT_AdvPreferredLifetime;
126 prefix->DeprecatePrefixFlag = DFLT_DeprecatePrefixFlag;
127 prefix->DecrementLifetimesFlag = DFLT_DecrementLifetimesFlag;
128
129 prefix->curr_validlft = prefix->AdvValidLifetime;
130 prefix->curr_preferredlft = prefix->AdvPreferredLifetime;
131 }
132
route_init_defaults(struct AdvRoute * route,struct Interface * iface)133 void route_init_defaults(struct AdvRoute *route, struct Interface *iface)
134 {
135 memset(route, 0, sizeof(struct AdvRoute));
136
137 route->AdvRouteLifetime = DFLT_AdvRouteLifetime(iface);
138 route->AdvRoutePreference = DFLT_AdvRoutePreference;
139 route->RemoveRouteFlag = DFLT_RemoveRouteFlag;
140 }
141
rdnss_init_defaults(struct AdvRDNSS * rdnss,struct Interface * iface)142 void rdnss_init_defaults(struct AdvRDNSS *rdnss, struct Interface *iface)
143 {
144 memset(rdnss, 0, sizeof(struct AdvRDNSS));
145
146 rdnss->AdvRDNSSLifetime = DFLT_AdvRDNSSLifetime(iface);
147 rdnss->AdvRDNSSNumber = 0;
148 rdnss->FlushRDNSSFlag = DFLT_FlushRDNSSFlag;
149 }
150
dnssl_init_defaults(struct AdvDNSSL * dnssl,struct Interface * iface)151 void dnssl_init_defaults(struct AdvDNSSL *dnssl, struct Interface *iface)
152 {
153 memset(dnssl, 0, sizeof(struct AdvDNSSL));
154
155 dnssl->AdvDNSSLLifetime = DFLT_AdvDNSSLLifetime(iface);
156 dnssl->FlushDNSSLFlag = DFLT_FlushDNSSLFlag;
157 }
158
check_iface(struct Interface * iface)159 int check_iface(struct Interface *iface)
160 {
161 int res = 0;
162 int MIPv6 = 0;
163 struct in6_addr zeroaddr;
164 memset(&zeroaddr, 0, sizeof(zeroaddr));
165
166 /* Check if we use Mobile IPv6 extensions */
167 if (iface->ra_header_info.AdvHomeAgentFlag || iface->mipv6.AdvHomeAgentInfo || iface->mipv6.AdvIntervalOpt) {
168 MIPv6 = 1;
169 flog(LOG_INFO, "using Mobile IPv6 extensions");
170 }
171
172 /* Check forwarding on interface */
173 if (check_ip6_iface_forwarding(iface->props.name) < 1) {
174 flog(LOG_WARNING, "IPv6 forwarding on interface seems to be disabled, but continuing anyway");
175 }
176
177 struct AdvPrefix *prefix = iface->AdvPrefixList;
178 while (!MIPv6 && prefix) {
179 if (prefix->AdvRouterAddr) {
180 MIPv6 = 1;
181 }
182 prefix = prefix->next;
183 }
184
185 if (iface->MinRtrAdvInterval < 0)
186 iface->MinRtrAdvInterval = DFLT_MinRtrAdvInterval(iface);
187
188 if ((iface->MinRtrAdvInterval < (MIPv6 ? MIN_MinRtrAdvInterval_MIPv6 : MIN_MinRtrAdvInterval)) ||
189 (iface->MinRtrAdvInterval > MAX_MinRtrAdvInterval(iface))) {
190 flog(LOG_ERR,
191 "MinRtrAdvInterval for %s (%.2f) must be at least %.2f but no more than 3/4 of MaxRtrAdvInterval (%.2f)",
192 iface->props.name, iface->MinRtrAdvInterval,
193 MIPv6 ? MIN_MinRtrAdvInterval_MIPv6 : (int)MIN_MinRtrAdvInterval, MAX_MinRtrAdvInterval(iface));
194 res = -1;
195 }
196
197 if ((iface->MaxRtrAdvInterval < (MIPv6 ? MIN_MaxRtrAdvInterval_MIPv6 : MIN_MaxRtrAdvInterval)) ||
198 (iface->MaxRtrAdvInterval > MAX_MaxRtrAdvInterval)) {
199 flog(LOG_ERR, "MaxRtrAdvInterval for %s (%.2f) must be between %.2f and %d", iface->props.name,
200 iface->MaxRtrAdvInterval, MIPv6 ? MIN_MaxRtrAdvInterval_MIPv6 : (int)MIN_MaxRtrAdvInterval,
201 MAX_MaxRtrAdvInterval);
202 res = -1;
203 }
204
205 if (iface->MinDelayBetweenRAs < (MIPv6 ? MIN_DELAY_BETWEEN_RAS_MIPv6 : MIN_DELAY_BETWEEN_RAS)) {
206 flog(LOG_ERR, "MinDelayBetweenRAs for %s (%.2f) must be at least %.2f", iface->props.name,
207 iface->MinDelayBetweenRAs, MIPv6 ? MIN_DELAY_BETWEEN_RAS_MIPv6 : MIN_DELAY_BETWEEN_RAS);
208 res = -1;
209 }
210
211 if ((iface->AdvLinkMTU != 0) && ((iface->AdvLinkMTU < MIN_AdvLinkMTU) ||
212 (iface->sllao.if_maxmtu != -1 && (iface->AdvLinkMTU > iface->sllao.if_maxmtu)))) {
213 flog(LOG_ERR, "AdvLinkMTU for %s (%u) must be zero or between %u and %u", iface->props.name, iface->AdvLinkMTU,
214 MIN_AdvLinkMTU, iface->sllao.if_maxmtu);
215 res = -1;
216 }
217
218 if (iface->ra_header_info.AdvReachableTime > MAX_AdvReachableTime) {
219 flog(LOG_ERR, "AdvReachableTime for %s (%u) must not be greater than %u", iface->props.name,
220 iface->ra_header_info.AdvReachableTime, MAX_AdvReachableTime);
221 res = -1;
222 }
223
224 if (iface->ra_header_info.AdvDefaultLifetime < 0)
225 iface->ra_header_info.AdvDefaultLifetime = DFLT_AdvDefaultLifetime(iface);
226
227 if ((iface->ra_header_info.AdvDefaultLifetime != 0) &&
228 ((iface->ra_header_info.AdvDefaultLifetime > MAX_AdvDefaultLifetime) ||
229 (iface->ra_header_info.AdvDefaultLifetime < MIN_AdvDefaultLifetime(iface)))) {
230 flog(LOG_ERR, "AdvDefaultLifetime for %s (%u) must be zero or between %u and %u", iface->props.name,
231 iface->ra_header_info.AdvDefaultLifetime, (int)MIN_AdvDefaultLifetime(iface), MAX_AdvDefaultLifetime);
232 res = -1;
233 }
234
235 /* Mobile IPv6 ext */
236 if (iface->mipv6.HomeAgentLifetime < 0)
237 iface->mipv6.HomeAgentLifetime = DFLT_HomeAgentLifetime(iface);
238
239 /* Mobile IPv6 ext */
240 if (iface->mipv6.AdvHomeAgentInfo) {
241 if ((iface->mipv6.HomeAgentLifetime > MAX_HomeAgentLifetime) ||
242 (iface->mipv6.HomeAgentLifetime < MIN_HomeAgentLifetime)) {
243 flog(LOG_ERR, "HomeAgentLifetime for %s (%u) must be between %u and %u", iface->props.name,
244 iface->mipv6.HomeAgentLifetime, MIN_HomeAgentLifetime, MAX_HomeAgentLifetime);
245 res = -1;
246 }
247 }
248
249 /* Mobile IPv6 ext */
250 if (iface->mipv6.AdvHomeAgentInfo && !(iface->ra_header_info.AdvHomeAgentFlag)) {
251 flog(LOG_ERR, "AdvHomeAgentFlag for %s must be set with HomeAgentInfo", iface->props.name);
252 res = -1;
253 }
254 if (iface->mipv6.AdvMobRtrSupportFlag && !(iface->mipv6.AdvHomeAgentInfo)) {
255 flog(LOG_ERR, "AdvHomeAgentInfo for %s must be set with AdvMobRtrSupportFlag", iface->props.name);
256 res = -1;
257 }
258
259 /* XXX: need this? prefix = iface->AdvPrefixList; */
260
261 while (prefix) {
262 if (prefix->PrefixLen > MAX_PrefixLen) {
263 flog(LOG_ERR, "invalid prefix length (%u) for %s", prefix->PrefixLen, iface->props.name);
264 res = -1;
265 }
266
267 if (prefix->AdvPreferredLifetime > prefix->AdvValidLifetime) {
268 flog(LOG_ERR, "AdvValidLifetime for %s (%u) must be "
269 "greater than AdvPreferredLifetime for",
270 iface->props.name, prefix->AdvValidLifetime);
271 res = -1;
272 }
273
274 prefix = prefix->next;
275 }
276
277 struct AdvRoute *route = iface->AdvRouteList;
278 while (route) {
279 if (route->PrefixLen > MAX_PrefixLen) {
280 flog(LOG_ERR, "invalid route prefix length (%u) for %s", route->PrefixLen, iface->props.name);
281 res = -1;
282 }
283
284 /* For the default route 0::/0, we need to explicitly check the
285 * lifetime against the AdvDefaultLifetime value.
286 *
287 * If exactly one of the two has a zero value, then nodes processing
288 * the RA may have a flap in their default route.
289 *
290 * AdvDefaultLifetime == 0 && route.AdvRouteLifetime > 0:
291 * - default route is deleted and then re-added.
292 * AdvDefaultLifetime > 0 && route.AdvRouteLifetime == 0:
293 * - default route is added and then deleted.
294 */
295 if (IN6_IS_ADDR_UNSPECIFIED(&(route->Prefix))) {
296 int route_zerolife = (route->AdvRouteLifetime == 0);
297 int defaultroute_zerolife = (iface->ra_header_info.AdvDefaultLifetime == 0);
298 if (route_zerolife ^ defaultroute_zerolife) {
299 flog(
300 LOG_ERR,
301 "route 0::/0 lifetime (%u) conflicts with AdvDefaultLifetime (%u), default routes will flap!",
302 route->AdvRouteLifetime, iface->ra_header_info.AdvDefaultLifetime);
303 // res = -1; // In some future version, abort on this configuration error.
304 }
305 }
306
307 route = route->next;
308 }
309
310 return res;
311 }
312
find_iface_by_index(struct Interface * iface,int index)313 struct Interface *find_iface_by_index(struct Interface *iface, int index)
314 {
315 for (; iface; iface = iface->next) {
316 if (iface->props.if_index == index) {
317 return iface;
318 }
319 }
320
321 return 0;
322 }
323
find_iface_by_name(struct Interface * iface,const char * name)324 struct Interface *find_iface_by_name(struct Interface *iface, const char *name)
325 {
326 if (!name) {
327 return 0;
328 }
329
330 for (; iface; iface = iface->next) {
331 if (strcmp(iface->props.name, name) == 0) {
332 return iface;
333 }
334 }
335
336 return 0;
337 }
338
find_iface_by_time(struct Interface * iface)339 struct Interface *find_iface_by_time(struct Interface *iface)
340 {
341 if (!iface) {
342 return 0;
343 }
344
345 int timeout = next_time_msec(iface);
346 struct Interface *next = iface;
347
348 for (iface = iface->next; iface; iface = iface->next) {
349 int t = next_time_msec(iface);
350 if (timeout > t) {
351 timeout = t;
352 next = iface;
353 }
354 }
355
356 return next;
357 }
358
reschedule_iface(struct Interface * iface,double next)359 void reschedule_iface(struct Interface *iface, double next)
360 {
361 #ifdef HAVE_NETLINK
362 if (!iface->state_info.changed && !iface->state_info.ready) {
363 next = 10 * iface->MaxRtrAdvInterval;
364 } else if (next == 0) {
365 next = IFACE_SETUP_DELAY;
366 } else
367 #endif
368 if (iface->state_info.racount < MAX_INITIAL_RTR_ADVERTISEMENTS) {
369 next = min(MAX_INITIAL_RTR_ADVERT_INTERVAL, iface->MaxRtrAdvInterval);
370 }
371
372 dlog(LOG_DEBUG, 5, "%s next scheduled RA in %g second(s)", iface->props.name, next);
373
374 iface->times.next_multicast = next_timespec(next);
375 }
376
for_each_iface(struct Interface * ifaces,void (* foo)(struct Interface *,void *),void * data)377 void for_each_iface(struct Interface *ifaces, void (*foo)(struct Interface *, void *), void *data)
378 {
379 for (; ifaces; ifaces = ifaces->next) {
380 foo(ifaces, data);
381 }
382 }
383
free_iface_list(struct Interface * iface)384 static void free_iface_list(struct Interface *iface)
385 {
386 while (iface) {
387 struct Interface *next_iface = iface->next;
388
389 dlog(LOG_DEBUG, 4, "freeing interface %s", iface->props.name);
390
391 struct AdvPrefix *prefix = iface->AdvPrefixList;
392 while (prefix) {
393 struct AdvPrefix *next_prefix = prefix->next;
394
395 free(prefix);
396 prefix = next_prefix;
397 }
398
399 struct AdvRoute *route = iface->AdvRouteList;
400 while (route) {
401 struct AdvRoute *next_route = route->next;
402
403 free(route);
404 route = next_route;
405 }
406
407 struct AdvRDNSS *rdnss = iface->AdvRDNSSList;
408 while (rdnss) {
409 struct AdvRDNSS *next_rdnss = rdnss->next;
410
411 free(rdnss);
412 rdnss = next_rdnss;
413 }
414
415 struct AdvDNSSL *dnssl = iface->AdvDNSSLList;
416 while (dnssl) {
417 struct AdvDNSSL *next_dnssl = dnssl->next;
418
419 for (int i = 0; i < dnssl->AdvDNSSLNumber; i++)
420 free(dnssl->AdvDNSSLSuffixes[i]);
421 free(dnssl->AdvDNSSLSuffixes);
422 free(dnssl);
423
424 dnssl = next_dnssl;
425 }
426
427 struct Clients *clients = iface->ClientList;
428 while (clients) {
429 struct Clients *next_client = clients->next;
430
431 free(clients);
432 clients = next_client;
433 }
434
435 free(iface->props.if_addrs);
436
437 free(iface);
438 iface = next_iface;
439 }
440 }
441
free_ifaces(struct Interface * ifaces)442 void free_ifaces(struct Interface *ifaces)
443 {
444 dlog(LOG_DEBUG, 3, "Freeing Interfaces");
445
446 free_iface_list(ifaces);
447 }
448