]> git.ipfire.org Git - thirdparty/bird.git/blob - nest/rt-table.c
Doc: Remove some superfluous slashes
[thirdparty/bird.git] / nest / rt-table.c
1 /*
2 * BIRD -- Routing Tables
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 /**
10 * DOC: Routing tables
11 *
12 * Routing tables are probably the most important structures BIRD uses. They
13 * hold all the information about known networks, the associated routes and
14 * their attributes.
15 *
16 * There are multiple routing tables (a primary one together with any
17 * number of secondary ones if requested by the configuration). Each table
18 * is basically a FIB containing entries describing the individual
19 * destination networks. For each network (represented by structure &net),
20 * there is a one-way linked list of route entries (&rte), the first entry
21 * on the list being the best one (i.e., the one we currently use
22 * for routing), the order of the other ones is undetermined.
23 *
24 * The &rte contains information specific to the route (preference, protocol
25 * metrics, time of last modification etc.) and a pointer to a &rta structure
26 * (see the route attribute module for a precise explanation) holding the
27 * remaining route attributes which are expected to be shared by multiple
28 * routes in order to conserve memory.
29 */
30
31 #undef LOCAL_DEBUG
32
33 #include "nest/bird.h"
34 #include "nest/route.h"
35 #include "nest/protocol.h"
36 #include "nest/cli.h"
37 #include "nest/iface.h"
38 #include "lib/resource.h"
39 #include "lib/event.h"
40 #include "lib/string.h"
41 #include "conf/conf.h"
42 #include "filter/filter.h"
43 #include "lib/string.h"
44 #include "lib/alloca.h"
45
46 pool *rt_table_pool;
47
48 static slab *rte_slab;
49 static linpool *rte_update_pool;
50
51 static list routing_tables;
52
53 static byte *rt_format_via(rte *e);
54 static void rt_free_hostcache(rtable *tab);
55 static void rt_notify_hostcache(rtable *tab, net *net);
56 static void rt_update_hostcache(rtable *tab);
57 static void rt_next_hop_update(rtable *tab);
58 static inline int rt_prune_table(rtable *tab);
59 static inline void rt_schedule_gc(rtable *tab);
60 static inline void rt_schedule_prune(rtable *tab);
61
62
63 /* Like fib_route(), but skips empty net entries */
64 static net *
65 net_route(rtable *tab, ip_addr a, int len)
66 {
67 ip_addr a0;
68 net *n;
69
70 while (len >= 0)
71 {
72 a0 = ipa_and(a, ipa_mkmask(len));
73 n = fib_find(&tab->fib, &a0, len);
74 if (n && rte_is_valid(n->routes))
75 return n;
76 len--;
77 }
78 return NULL;
79 }
80
81 static void
82 rte_init(struct fib_node *N)
83 {
84 net *n = (net *) N;
85
86 N->flags = 0;
87 n->routes = NULL;
88 }
89
90 /**
91 * rte_find - find a route
92 * @net: network node
93 * @src: route source
94 *
95 * The rte_find() function returns a route for destination @net
96 * which is from route source @src.
97 */
98 rte *
99 rte_find(net *net, struct rte_src *src)
100 {
101 rte *e = net->routes;
102
103 while (e && e->attrs->src != src)
104 e = e->next;
105 return e;
106 }
107
108 /**
109 * rte_get_temp - get a temporary &rte
110 * @a: attributes to assign to the new route (a &rta; in case it's
111 * un-cached, rte_update() will create a cached copy automatically)
112 *
113 * Create a temporary &rte and bind it with the attributes @a.
114 * Also set route preference to the default preference set for
115 * the protocol.
116 */
117 rte *
118 rte_get_temp(rta *a)
119 {
120 rte *e = sl_alloc(rte_slab);
121
122 e->attrs = a;
123 e->flags = 0;
124 e->pref = a->src->proto->preference;
125 return e;
126 }
127
128 rte *
129 rte_do_cow(rte *r)
130 {
131 rte *e = sl_alloc(rte_slab);
132
133 memcpy(e, r, sizeof(rte));
134 e->attrs = rta_clone(r->attrs);
135 e->flags = 0;
136 return e;
137 }
138
139 /**
140 * rte_cow_rta - get a private writable copy of &rte with writable &rta
141 * @r: a route entry to be copied
142 * @lp: a linpool from which to allocate &rta
143 *
144 * rte_cow_rta() takes a &rte and prepares it and associated &rta for
145 * modification. There are three possibilities: First, both &rte and &rta are
146 * private copies, in that case they are returned unchanged. Second, &rte is
147 * private copy, but &rta is cached, in that case &rta is duplicated using
148 * rta_do_cow(). Third, both &rte is shared and &rta is cached, in that case
149 * both structures are duplicated by rte_do_cow() and rta_do_cow().
150 *
151 * Note that in the second case, cached &rta loses one reference, while private
152 * copy created by rta_do_cow() is a shallow copy sharing indirect data (eattrs,
153 * nexthops, ...) with it. To work properly, original shared &rta should have
154 * another reference during the life of created private copy.
155 *
156 * Result: a pointer to the new writable &rte with writable &rta.
157 */
158 rte *
159 rte_cow_rta(rte *r, linpool *lp)
160 {
161 if (!rta_is_cached(r->attrs))
162 return r;
163
164 rte *e = rte_cow(r);
165 rta *a = rta_do_cow(r->attrs, lp);
166 rta_free(e->attrs);
167 e->attrs = a;
168 return e;
169 }
170
171 static int /* Actually better or at least as good as */
172 rte_better(rte *new, rte *old)
173 {
174 int (*better)(rte *, rte *);
175
176 if (!rte_is_valid(old))
177 return 1;
178 if (!rte_is_valid(new))
179 return 0;
180
181 if (new->pref > old->pref)
182 return 1;
183 if (new->pref < old->pref)
184 return 0;
185 if (new->attrs->src->proto->proto != old->attrs->src->proto->proto)
186 {
187 /*
188 * If the user has configured protocol preferences, so that two different protocols
189 * have the same preference, try to break the tie by comparing addresses. Not too
190 * useful, but keeps the ordering of routes unambiguous.
191 */
192 return new->attrs->src->proto->proto > old->attrs->src->proto->proto;
193 }
194 if (better = new->attrs->src->proto->rte_better)
195 return better(new, old);
196 return 0;
197 }
198
199 static int
200 rte_mergable(rte *pri, rte *sec)
201 {
202 int (*mergable)(rte *, rte *);
203
204 if (!rte_is_valid(pri) || !rte_is_valid(sec))
205 return 0;
206
207 if (pri->pref != sec->pref)
208 return 0;
209
210 if (pri->attrs->src->proto->proto != sec->attrs->src->proto->proto)
211 return 0;
212
213 if (mergable = pri->attrs->src->proto->rte_mergable)
214 return mergable(pri, sec);
215
216 return 0;
217 }
218
219 static void
220 rte_trace(struct proto *p, rte *e, int dir, char *msg)
221 {
222 log(L_TRACE "%s %c %s %I/%d %s", p->name, dir, msg, e->net->n.prefix, e->net->n.pxlen, rt_format_via(e));
223 }
224
225 static inline void
226 rte_trace_in(uint flag, struct proto *p, rte *e, char *msg)
227 {
228 if (p->debug & flag)
229 rte_trace(p, e, '>', msg);
230 }
231
232 static inline void
233 rte_trace_out(uint flag, struct proto *p, rte *e, char *msg)
234 {
235 if (p->debug & flag)
236 rte_trace(p, e, '<', msg);
237 }
238
239 static rte *
240 export_filter_(struct announce_hook *ah, rte *rt0, rte **rt_free, ea_list **tmpa, linpool *pool, int silent)
241 {
242 struct proto *p = ah->proto;
243 struct filter *filter = ah->out_filter;
244 struct proto_stats *stats = ah->stats;
245 ea_list *tmpb = NULL;
246 rte *rt;
247 int v;
248
249 rt = rt0;
250 *rt_free = NULL;
251
252 if (!tmpa)
253 tmpa = &tmpb;
254
255 *tmpa = rte_make_tmp_attrs(rt, pool);
256
257 v = p->import_control ? p->import_control(p, &rt, tmpa, pool) : 0;
258 if (v < 0)
259 {
260 if (silent)
261 goto reject;
262
263 stats->exp_updates_rejected++;
264 if (v == RIC_REJECT)
265 rte_trace_out(D_FILTERS, p, rt, "rejected by protocol");
266 goto reject;
267 }
268 if (v > 0)
269 {
270 if (!silent)
271 rte_trace_out(D_FILTERS, p, rt, "forced accept by protocol");
272 goto accept;
273 }
274
275 v = filter && ((filter == FILTER_REJECT) ||
276 (f_run(filter, &rt, tmpa, pool,
277 FF_FORCE_TMPATTR | (silent ? FF_SILENT : 0)) > F_ACCEPT));
278 if (v)
279 {
280 if (silent)
281 goto reject;
282
283 stats->exp_updates_filtered++;
284 rte_trace_out(D_FILTERS, p, rt, "filtered out");
285 goto reject;
286 }
287
288 accept:
289 if (rt != rt0)
290 *rt_free = rt;
291 return rt;
292
293 reject:
294 /* Discard temporary rte */
295 if (rt != rt0)
296 rte_free(rt);
297 return NULL;
298 }
299
300 static inline rte *
301 export_filter(struct announce_hook *ah, rte *rt0, rte **rt_free, ea_list **tmpa, int silent)
302 {
303 return export_filter_(ah, rt0, rt_free, tmpa, rte_update_pool, silent);
304 }
305
306 static void
307 do_rt_notify(struct announce_hook *ah, net *net, rte *new, rte *old, ea_list *tmpa, int refeed)
308 {
309 struct proto *p = ah->proto;
310 struct proto_stats *stats = ah->stats;
311
312
313 /*
314 * First, apply export limit.
315 *
316 * Export route limits has several problems. Because exp_routes
317 * counter is reset before refeed, we don't really know whether
318 * limit is breached and whether the update is new or not. Therefore
319 * the number of really exported routes may exceed the limit
320 * temporarily (routes exported before and new routes in refeed).
321 *
322 * Minor advantage is that if the limit is decreased and refeed is
323 * requested, the number of exported routes really decrease.
324 *
325 * Second problem is that with export limits, we don't know whether
326 * old was really exported (it might be blocked by limit). When a
327 * withdraw is exported, we announce it even when the previous
328 * update was blocked. This is not a big issue, but the same problem
329 * is in updating exp_routes counter. Therefore, to be consistent in
330 * increases and decreases of exp_routes, we count exported routes
331 * regardless of blocking by limits.
332 *
333 * Similar problem is in handling updates - when a new route is
334 * received and blocking is active, the route would be blocked, but
335 * when an update for the route will be received later, the update
336 * would be propagated (as old != NULL). Therefore, we have to block
337 * also non-new updates (contrary to import blocking).
338 */
339
340 struct proto_limit *l = ah->out_limit;
341 if (l && new)
342 {
343 if ((!old || refeed) && (stats->exp_routes >= l->limit))
344 proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes);
345
346 if (l->state == PLS_BLOCKED)
347 {
348 stats->exp_routes++; /* see note above */
349 stats->exp_updates_rejected++;
350 rte_trace_out(D_FILTERS, p, new, "rejected [limit]");
351 new = NULL;
352
353 if (!old)
354 return;
355 }
356 }
357
358
359 if (new)
360 stats->exp_updates_accepted++;
361 else
362 stats->exp_withdraws_accepted++;
363
364 /* Hack: We do not decrease exp_routes during refeed, we instead
365 reset exp_routes at the start of refeed. */
366 if (new)
367 stats->exp_routes++;
368 if (old && !refeed)
369 stats->exp_routes--;
370
371 if (p->debug & D_ROUTES)
372 {
373 if (new && old)
374 rte_trace_out(D_ROUTES, p, new, "replaced");
375 else if (new)
376 rte_trace_out(D_ROUTES, p, new, "added");
377 else if (old)
378 rte_trace_out(D_ROUTES, p, old, "removed");
379 }
380 if (!new)
381 p->rt_notify(p, ah->table, net, NULL, old, NULL);
382 else if (tmpa)
383 {
384 ea_list *t = tmpa;
385 while (t->next)
386 t = t->next;
387 t->next = new->attrs->eattrs;
388 p->rt_notify(p, ah->table, net, new, old, tmpa);
389 t->next = NULL;
390 }
391 else
392 p->rt_notify(p, ah->table, net, new, old, new->attrs->eattrs);
393 }
394
395 static void
396 rt_notify_basic(struct announce_hook *ah, net *net, rte *new0, rte *old0, int refeed)
397 {
398 struct proto *p = ah->proto;
399 struct proto_stats *stats = ah->stats;
400
401 rte *new = new0;
402 rte *old = old0;
403 rte *new_free = NULL;
404 rte *old_free = NULL;
405 ea_list *tmpa = NULL;
406
407 if (new)
408 stats->exp_updates_received++;
409 else
410 stats->exp_withdraws_received++;
411
412 /*
413 * This is a tricky part - we don't know whether route 'old' was
414 * exported to protocol 'p' or was filtered by the export filter.
415 * We try to run the export filter to know this to have a correct
416 * value in 'old' argument of rte_update (and proper filter value)
417 *
418 * FIXME - this is broken because 'configure soft' may change
419 * filters but keep routes. Refeed is expected to be called after
420 * change of the filters and with old == new, therefore we do not
421 * even try to run the filter on an old route, This may lead to
422 * 'spurious withdraws' but ensure that there are no 'missing
423 * withdraws'.
424 *
425 * This is not completely safe as there is a window between
426 * reconfiguration and the end of refeed - if a newly filtered
427 * route disappears during this period, proper withdraw is not
428 * sent (because old would be also filtered) and the route is
429 * not refeeded (because it disappeared before that).
430 */
431
432 if (new)
433 new = export_filter(ah, new, &new_free, &tmpa, 0);
434
435 if (old && !refeed)
436 old = export_filter(ah, old, &old_free, NULL, 1);
437
438 if (!new && !old)
439 {
440 /*
441 * As mentioned above, 'old' value may be incorrect in some race conditions.
442 * We generally ignore it with the exception of withdraw to pipe protocol.
443 * In that case we rather propagate unfiltered withdraws regardless of
444 * export filters to ensure that when a protocol is flushed, its routes are
445 * removed from all tables. Possible spurious unfiltered withdraws are not
446 * problem here as they are ignored if there is no corresponding route at
447 * the other end of the pipe. We directly call rt_notify() hook instead of
448 * do_rt_notify() to avoid logging and stat counters.
449 */
450
451 #ifdef CONFIG_PIPE
452 if ((p->proto == &proto_pipe) && !new0 && (p != old0->sender->proto))
453 p->rt_notify(p, ah->table, net, NULL, old0, NULL);
454 #endif
455
456 return;
457 }
458
459 do_rt_notify(ah, net, new, old, tmpa, refeed);
460
461 /* Discard temporary rte's */
462 if (new_free)
463 rte_free(new_free);
464 if (old_free)
465 rte_free(old_free);
466 }
467
468 static void
469 rt_notify_accepted(struct announce_hook *ah, net *net, rte *new_changed, rte *old_changed, rte *before_old, int feed)
470 {
471 // struct proto *p = ah->proto;
472 struct proto_stats *stats = ah->stats;
473
474 rte *r;
475 rte *new_best = NULL;
476 rte *old_best = NULL;
477 rte *new_free = NULL;
478 rte *old_free = NULL;
479 ea_list *tmpa = NULL;
480
481 /* Used to track whether we met old_changed position. If before_old is NULL
482 old_changed was the first and we met it implicitly before current best route. */
483 int old_meet = old_changed && !before_old;
484
485 /* Note that before_old is either NULL or valid (not rejected) route.
486 If old_changed is valid, before_old have to be too. If old changed route
487 was not valid, caller must use NULL for both old_changed and before_old. */
488
489 if (new_changed)
490 stats->exp_updates_received++;
491 else
492 stats->exp_withdraws_received++;
493
494 /* First, find the new_best route - first accepted by filters */
495 for (r=net->routes; rte_is_valid(r); r=r->next)
496 {
497 if (new_best = export_filter(ah, r, &new_free, &tmpa, 0))
498 break;
499
500 /* Note if we walked around the position of old_changed route */
501 if (r == before_old)
502 old_meet = 1;
503 }
504
505 /*
506 * Second, handle the feed case. That means we do not care for
507 * old_best. It is NULL for feed, and the new_best for refeed.
508 * For refeed, there is a hack similar to one in rt_notify_basic()
509 * to ensure withdraws in case of changed filters
510 */
511 if (feed)
512 {
513 if (feed == 2) /* refeed */
514 old_best = new_best ? new_best :
515 (rte_is_valid(net->routes) ? net->routes : NULL);
516 else
517 old_best = NULL;
518
519 if (!new_best && !old_best)
520 return;
521
522 goto found;
523 }
524
525 /*
526 * Now, we find the old_best route. Generally, it is the same as the
527 * new_best, unless new_best is the same as new_changed or
528 * old_changed is accepted before new_best.
529 *
530 * There are four cases:
531 *
532 * - We would find and accept old_changed before new_best, therefore
533 * old_changed is old_best. In remaining cases we suppose this
534 * is not true.
535 *
536 * - We found no new_best, therefore there is also no old_best and
537 * we ignore this withdraw.
538 *
539 * - We found new_best different than new_changed, therefore
540 * old_best is the same as new_best and we ignore this update.
541 *
542 * - We found new_best the same as new_changed, therefore it cannot
543 * be old_best and we have to continue search for old_best.
544 */
545
546 /* First case */
547 if (old_meet)
548 if (old_best = export_filter(ah, old_changed, &old_free, NULL, 1))
549 goto found;
550
551 /* Second case */
552 if (!new_best)
553 return;
554
555 /* Third case, we use r instead of new_best, because export_filter() could change it */
556 if (r != new_changed)
557 {
558 if (new_free)
559 rte_free(new_free);
560 return;
561 }
562
563 /* Fourth case */
564 for (r=r->next; rte_is_valid(r); r=r->next)
565 {
566 if (old_best = export_filter(ah, r, &old_free, NULL, 1))
567 goto found;
568
569 if (r == before_old)
570 if (old_best = export_filter(ah, old_changed, &old_free, NULL, 1))
571 goto found;
572 }
573
574 /* Implicitly, old_best is NULL and new_best is non-NULL */
575
576 found:
577 do_rt_notify(ah, net, new_best, old_best, tmpa, (feed == 2));
578
579 /* Discard temporary rte's */
580 if (new_free)
581 rte_free(new_free);
582 if (old_free)
583 rte_free(old_free);
584 }
585
586
587 static struct mpnh *
588 mpnh_merge_rta(struct mpnh *nhs, rta *a, linpool *pool, int max)
589 {
590 struct mpnh nh = { .gw = a->gw, .iface = a->iface };
591 struct mpnh *nh2 = (a->dest == RTD_MULTIPATH) ? a->nexthops : &nh;
592 return mpnh_merge(nhs, nh2, 1, 0, max, pool);
593 }
594
595 rte *
596 rt_export_merged(struct announce_hook *ah, net *net, rte **rt_free, ea_list **tmpa, linpool *pool, int silent)
597 {
598 // struct proto *p = ah->proto;
599 struct mpnh *nhs = NULL;
600 rte *best0, *best, *rt0, *rt, *tmp;
601
602 best0 = net->routes;
603 *rt_free = NULL;
604
605 if (!rte_is_valid(best0))
606 return NULL;
607
608 best = export_filter_(ah, best0, rt_free, tmpa, pool, silent);
609
610 if (!best || !rte_is_reachable(best))
611 return best;
612
613 for (rt0 = best0->next; rt0; rt0 = rt0->next)
614 {
615 if (!rte_mergable(best0, rt0))
616 continue;
617
618 rt = export_filter_(ah, rt0, &tmp, NULL, pool, 1);
619
620 if (!rt)
621 continue;
622
623 if (rte_is_reachable(rt))
624 nhs = mpnh_merge_rta(nhs, rt->attrs, pool, ah->proto->merge_limit);
625
626 if (tmp)
627 rte_free(tmp);
628 }
629
630 if (nhs)
631 {
632 nhs = mpnh_merge_rta(nhs, best->attrs, pool, ah->proto->merge_limit);
633
634 if (nhs->next)
635 {
636 best = rte_cow_rta(best, pool);
637 best->attrs->dest = RTD_MULTIPATH;
638 best->attrs->nexthops = nhs;
639 }
640 }
641
642 if (best != best0)
643 *rt_free = best;
644
645 return best;
646 }
647
648
649 static void
650 rt_notify_merged(struct announce_hook *ah, net *net, rte *new_changed, rte *old_changed,
651 rte *new_best, rte*old_best, int refeed)
652 {
653 // struct proto *p = ah->proto;
654
655 rte *new_best_free = NULL;
656 rte *old_best_free = NULL;
657 rte *new_changed_free = NULL;
658 rte *old_changed_free = NULL;
659 ea_list *tmpa = NULL;
660
661 /* We assume that all rte arguments are either NULL or rte_is_valid() */
662
663 /* This check should be done by the caller */
664 if (!new_best && !old_best)
665 return;
666
667 /* Check whether the change is relevant to the merged route */
668 if ((new_best == old_best) && !refeed)
669 {
670 new_changed = rte_mergable(new_best, new_changed) ?
671 export_filter(ah, new_changed, &new_changed_free, NULL, 1) : NULL;
672
673 old_changed = rte_mergable(old_best, old_changed) ?
674 export_filter(ah, old_changed, &old_changed_free, NULL, 1) : NULL;
675
676 if (!new_changed && !old_changed)
677 return;
678 }
679
680 if (new_best)
681 ah->stats->exp_updates_received++;
682 else
683 ah->stats->exp_withdraws_received++;
684
685 /* Prepare new merged route */
686 if (new_best)
687 new_best = rt_export_merged(ah, net, &new_best_free, &tmpa, rte_update_pool, 0);
688
689 /* Prepare old merged route (without proper merged next hops) */
690 /* There are some issues with running filter on old route - see rt_notify_basic() */
691 if (old_best && !refeed)
692 old_best = export_filter(ah, old_best, &old_best_free, NULL, 1);
693
694 if (new_best || old_best)
695 do_rt_notify(ah, net, new_best, old_best, tmpa, refeed);
696
697 /* Discard temporary rte's */
698 if (new_best_free)
699 rte_free(new_best_free);
700 if (old_best_free)
701 rte_free(old_best_free);
702 if (new_changed_free)
703 rte_free(new_changed_free);
704 if (old_changed_free)
705 rte_free(old_changed_free);
706 }
707
708
709 /**
710 * rte_announce - announce a routing table change
711 * @tab: table the route has been added to
712 * @type: type of route announcement (RA_OPTIMAL or RA_ANY)
713 * @net: network in question
714 * @new: the new route to be announced
715 * @old: the previous route for the same network
716 * @new_best: the new best route for the same network
717 * @old_best: the previous best route for the same network
718 * @before_old: The previous route before @old for the same network.
719 * If @before_old is NULL @old was the first.
720 *
721 * This function gets a routing table update and announces it
722 * to all protocols that acccepts given type of route announcement
723 * and are connected to the same table by their announcement hooks.
724 *
725 * Route announcement of type %RA_OPTIMAL si generated when optimal
726 * route (in routing table @tab) changes. In that case @old stores the
727 * old optimal route.
728 *
729 * Route announcement of type %RA_ANY si generated when any route (in
730 * routing table @tab) changes In that case @old stores the old route
731 * from the same protocol.
732 *
733 * For each appropriate protocol, we first call its import_control()
734 * hook which performs basic checks on the route (each protocol has a
735 * right to veto or force accept of the route before any filter is
736 * asked) and adds default values of attributes specific to the new
737 * protocol (metrics, tags etc.). Then it consults the protocol's
738 * export filter and if it accepts the route, the rt_notify() hook of
739 * the protocol gets called.
740 */
741 static void
742 rte_announce(rtable *tab, unsigned type, net *net, rte *new, rte *old,
743 rte *new_best, rte *old_best, rte *before_old)
744 {
745 if (!rte_is_valid(new))
746 new = NULL;
747
748 if (!rte_is_valid(old))
749 old = before_old = NULL;
750
751 if (!rte_is_valid(new_best))
752 new_best = NULL;
753
754 if (!rte_is_valid(old_best))
755 old_best = NULL;
756
757 if (!old && !new)
758 return;
759
760 if (type == RA_OPTIMAL)
761 {
762 if (new)
763 new->attrs->src->proto->stats.pref_routes++;
764 if (old)
765 old->attrs->src->proto->stats.pref_routes--;
766
767 if (tab->hostcache)
768 rt_notify_hostcache(tab, net);
769 }
770
771 struct announce_hook *a;
772 WALK_LIST(a, tab->hooks)
773 {
774 ASSERT(a->proto->export_state != ES_DOWN);
775 if (a->proto->accept_ra_types == type)
776 if (type == RA_ACCEPTED)
777 rt_notify_accepted(a, net, new, old, before_old, 0);
778 else if (type == RA_MERGED)
779 rt_notify_merged(a, net, new, old, new_best, old_best, 0);
780 else
781 rt_notify_basic(a, net, new, old, 0);
782 }
783 }
784
785 static inline int
786 rte_validate(rte *e)
787 {
788 int c;
789 net *n = e->net;
790
791 if ((n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(n->n.prefix,n->n.pxlen))
792 {
793 log(L_WARN "Ignoring bogus prefix %I/%d received via %s",
794 n->n.prefix, n->n.pxlen, e->sender->proto->name);
795 return 0;
796 }
797
798 c = ipa_classify_net(n->n.prefix);
799 if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
800 {
801 log(L_WARN "Ignoring bogus route %I/%d received via %s",
802 n->n.prefix, n->n.pxlen, e->sender->proto->name);
803 return 0;
804 }
805
806 if ((e->attrs->dest == RTD_MULTIPATH) && !mpnh_is_sorted(e->attrs->nexthops))
807 {
808 log(L_WARN "Ignoring unsorted multipath route %I/%d received via %s",
809 n->n.prefix, n->n.pxlen, e->sender->proto->name);
810 return 0;
811 }
812
813 return 1;
814 }
815
816 /**
817 * rte_free - delete a &rte
818 * @e: &rte to be deleted
819 *
820 * rte_free() deletes the given &rte from the routing table it's linked to.
821 */
822 void
823 rte_free(rte *e)
824 {
825 if (rta_is_cached(e->attrs))
826 rta_free(e->attrs);
827 sl_free(rte_slab, e);
828 }
829
830 static inline void
831 rte_free_quick(rte *e)
832 {
833 rta_free(e->attrs);
834 sl_free(rte_slab, e);
835 }
836
837 static int
838 rte_same(rte *x, rte *y)
839 {
840 return
841 x->attrs == y->attrs &&
842 x->flags == y->flags &&
843 x->pflags == y->pflags &&
844 x->pref == y->pref &&
845 (!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y));
846 }
847
848 static inline int rte_is_ok(rte *e) { return e && !rte_is_filtered(e); }
849
850 static void
851 rte_recalculate(struct announce_hook *ah, net *net, rte *new, struct rte_src *src)
852 {
853 struct proto *p = ah->proto;
854 struct rtable *table = ah->table;
855 struct proto_stats *stats = ah->stats;
856 static struct tbf rl_pipe = TBF_DEFAULT_LOG_LIMITS;
857 rte *before_old = NULL;
858 rte *old_best = net->routes;
859 rte *old = NULL;
860 rte **k;
861
862 k = &net->routes; /* Find and remove original route from the same protocol */
863 while (old = *k)
864 {
865 if (old->attrs->src == src)
866 {
867 /* If there is the same route in the routing table but from
868 * a different sender, then there are two paths from the
869 * source protocol to this routing table through transparent
870 * pipes, which is not allowed.
871 *
872 * We log that and ignore the route. If it is withdraw, we
873 * ignore it completely (there might be 'spurious withdraws',
874 * see FIXME in do_rte_announce())
875 */
876 if (old->sender->proto != p)
877 {
878 if (new)
879 {
880 log_rl(&rl_pipe, L_ERR "Pipe collision detected when sending %I/%d to table %s",
881 net->n.prefix, net->n.pxlen, table->name);
882 rte_free_quick(new);
883 }
884 return;
885 }
886
887 if (new && rte_same(old, new))
888 {
889 /* No changes, ignore the new route */
890
891 if (!rte_is_filtered(new))
892 {
893 stats->imp_updates_ignored++;
894 rte_trace_in(D_ROUTES, p, new, "ignored");
895 }
896
897 rte_free_quick(new);
898 return;
899 }
900 *k = old->next;
901 break;
902 }
903 k = &old->next;
904 before_old = old;
905 }
906
907 if (!old)
908 before_old = NULL;
909
910 if (!old && !new)
911 {
912 stats->imp_withdraws_ignored++;
913 return;
914 }
915
916 int new_ok = rte_is_ok(new);
917 int old_ok = rte_is_ok(old);
918
919 struct proto_limit *l = ah->rx_limit;
920 if (l && !old && new)
921 {
922 u32 all_routes = stats->imp_routes + stats->filt_routes;
923
924 if (all_routes >= l->limit)
925 proto_notify_limit(ah, l, PLD_RX, all_routes);
926
927 if (l->state == PLS_BLOCKED)
928 {
929 /* In receive limit the situation is simple, old is NULL so
930 we just free new and exit like nothing happened */
931
932 stats->imp_updates_ignored++;
933 rte_trace_in(D_FILTERS, p, new, "ignored [limit]");
934 rte_free_quick(new);
935 return;
936 }
937 }
938
939 l = ah->in_limit;
940 if (l && !old_ok && new_ok)
941 {
942 if (stats->imp_routes >= l->limit)
943 proto_notify_limit(ah, l, PLD_IN, stats->imp_routes);
944
945 if (l->state == PLS_BLOCKED)
946 {
947 /* In import limit the situation is more complicated. We
948 shouldn't just drop the route, we should handle it like
949 it was filtered. We also have to continue the route
950 processing if old or new is non-NULL, but we should exit
951 if both are NULL as this case is probably assumed to be
952 already handled. */
953
954 stats->imp_updates_ignored++;
955 rte_trace_in(D_FILTERS, p, new, "ignored [limit]");
956
957 if (ah->in_keep_filtered)
958 new->flags |= REF_FILTERED;
959 else
960 { rte_free_quick(new); new = NULL; }
961
962 /* Note that old && !new could be possible when
963 ah->in_keep_filtered changed in the recent past. */
964
965 if (!old && !new)
966 return;
967
968 new_ok = 0;
969 goto skip_stats1;
970 }
971 }
972
973 if (new_ok)
974 stats->imp_updates_accepted++;
975 else if (old_ok)
976 stats->imp_withdraws_accepted++;
977 else
978 stats->imp_withdraws_ignored++;
979
980 skip_stats1:
981
982 if (new)
983 rte_is_filtered(new) ? stats->filt_routes++ : stats->imp_routes++;
984 if (old)
985 rte_is_filtered(old) ? stats->filt_routes-- : stats->imp_routes--;
986
987 if (table->config->sorted)
988 {
989 /* If routes are sorted, just insert new route to appropriate position */
990 if (new)
991 {
992 if (before_old && !rte_better(new, before_old))
993 k = &before_old->next;
994 else
995 k = &net->routes;
996
997 for (; *k; k=&(*k)->next)
998 if (rte_better(new, *k))
999 break;
1000
1001 new->next = *k;
1002 *k = new;
1003 }
1004 }
1005 else
1006 {
1007 /* If routes are not sorted, find the best route and move it on
1008 the first position. There are several optimized cases. */
1009
1010 if (src->proto->rte_recalculate && src->proto->rte_recalculate(table, net, new, old, old_best))
1011 goto do_recalculate;
1012
1013 if (new && rte_better(new, old_best))
1014 {
1015 /* The first case - the new route is cleary optimal,
1016 we link it at the first position */
1017
1018 new->next = net->routes;
1019 net->routes = new;
1020 }
1021 else if (old == old_best)
1022 {
1023 /* The second case - the old best route disappeared, we add the
1024 new route (if we have any) to the list (we don't care about
1025 position) and then we elect the new optimal route and relink
1026 that route at the first position and announce it. New optimal
1027 route might be NULL if there is no more routes */
1028
1029 do_recalculate:
1030 /* Add the new route to the list */
1031 if (new)
1032 {
1033 new->next = net->routes;
1034 net->routes = new;
1035 }
1036
1037 /* Find a new optimal route (if there is any) */
1038 if (net->routes)
1039 {
1040 rte **bp = &net->routes;
1041 for (k=&(*bp)->next; *k; k=&(*k)->next)
1042 if (rte_better(*k, *bp))
1043 bp = k;
1044
1045 /* And relink it */
1046 rte *best = *bp;
1047 *bp = best->next;
1048 best->next = net->routes;
1049 net->routes = best;
1050 }
1051 }
1052 else if (new)
1053 {
1054 /* The third case - the new route is not better than the old
1055 best route (therefore old_best != NULL) and the old best
1056 route was not removed (therefore old_best == net->routes).
1057 We just link the new route after the old best route. */
1058
1059 ASSERT(net->routes != NULL);
1060 new->next = net->routes->next;
1061 net->routes->next = new;
1062 }
1063 /* The fourth (empty) case - suboptimal route was removed, nothing to do */
1064 }
1065
1066 if (new)
1067 new->lastmod = now;
1068
1069 /* Log the route change */
1070 if (p->debug & D_ROUTES)
1071 {
1072 if (new_ok)
1073 rte_trace(p, new, '>', new == net->routes ? "added [best]" : "added");
1074 else if (old_ok)
1075 {
1076 if (old != old_best)
1077 rte_trace(p, old, '>', "removed");
1078 else if (rte_is_ok(net->routes))
1079 rte_trace(p, old, '>', "removed [replaced]");
1080 else
1081 rte_trace(p, old, '>', "removed [sole]");
1082 }
1083 }
1084
1085 /* Propagate the route change */
1086 rte_announce(table, RA_ANY, net, new, old, NULL, NULL, NULL);
1087 if (net->routes != old_best)
1088 rte_announce(table, RA_OPTIMAL, net, net->routes, old_best, NULL, NULL, NULL);
1089 if (table->config->sorted)
1090 rte_announce(table, RA_ACCEPTED, net, new, old, NULL, NULL, before_old);
1091 rte_announce(table, RA_MERGED, net, new, old, net->routes, old_best, NULL);
1092
1093 if (!net->routes &&
1094 (table->gc_counter++ >= table->config->gc_max_ops) &&
1095 (table->gc_time + table->config->gc_min_time <= now))
1096 rt_schedule_gc(table);
1097
1098 if (old_ok && p->rte_remove)
1099 p->rte_remove(net, old);
1100 if (new_ok && p->rte_insert)
1101 p->rte_insert(net, new);
1102
1103 if (old)
1104 rte_free_quick(old);
1105 }
1106
1107 static int rte_update_nest_cnt; /* Nesting counter to allow recursive updates */
1108
1109 static inline void
1110 rte_update_lock(void)
1111 {
1112 rte_update_nest_cnt++;
1113 }
1114
1115 static inline void
1116 rte_update_unlock(void)
1117 {
1118 if (!--rte_update_nest_cnt)
1119 lp_flush(rte_update_pool);
1120 }
1121
1122 static inline void
1123 rte_hide_dummy_routes(net *net, rte **dummy)
1124 {
1125 if (net->routes && net->routes->attrs->source == RTS_DUMMY)
1126 {
1127 *dummy = net->routes;
1128 net->routes = (*dummy)->next;
1129 }
1130 }
1131
1132 static inline void
1133 rte_unhide_dummy_routes(net *net, rte **dummy)
1134 {
1135 if (*dummy)
1136 {
1137 (*dummy)->next = net->routes;
1138 net->routes = *dummy;
1139 }
1140 }
1141
1142 /**
1143 * rte_update - enter a new update to a routing table
1144 * @table: table to be updated
1145 * @ah: pointer to table announce hook
1146 * @net: network node
1147 * @p: protocol submitting the update
1148 * @src: protocol originating the update
1149 * @new: a &rte representing the new route or %NULL for route removal.
1150 *
1151 * This function is called by the routing protocols whenever they discover
1152 * a new route or wish to update/remove an existing route. The right announcement
1153 * sequence is to build route attributes first (either un-cached with @aflags set
1154 * to zero or a cached one using rta_lookup(); in this case please note that
1155 * you need to increase the use count of the attributes yourself by calling
1156 * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
1157 * the appropriate data and finally submit the new &rte by calling rte_update().
1158 *
1159 * @src specifies the protocol that originally created the route and the meaning
1160 * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
1161 * same value as @new->attrs->proto. @p specifies the protocol that called
1162 * rte_update(). In most cases it is the same protocol as @src. rte_update()
1163 * stores @p in @new->sender;
1164 *
1165 * When rte_update() gets any route, it automatically validates it (checks,
1166 * whether the network and next hop address are valid IP addresses and also
1167 * whether a normal routing protocol doesn't try to smuggle a host or link
1168 * scope route to the table), converts all protocol dependent attributes stored
1169 * in the &rte to temporary extended attributes, consults import filters of the
1170 * protocol to see if the route should be accepted and/or its attributes modified,
1171 * stores the temporary attributes back to the &rte.
1172 *
1173 * Now, having a "public" version of the route, we
1174 * automatically find any old route defined by the protocol @src
1175 * for network @n, replace it by the new one (or removing it if @new is %NULL),
1176 * recalculate the optimal route for this destination and finally broadcast
1177 * the change (if any) to all routing protocols by calling rte_announce().
1178 *
1179 * All memory used for attribute lists and other temporary allocations is taken
1180 * from a special linear pool @rte_update_pool and freed when rte_update()
1181 * finishes.
1182 */
1183
1184 void
1185 rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src)
1186 {
1187 struct proto *p = ah->proto;
1188 struct proto_stats *stats = ah->stats;
1189 struct filter *filter = ah->in_filter;
1190 ea_list *tmpa = NULL;
1191 rte *dummy = NULL;
1192
1193 rte_update_lock();
1194 if (new)
1195 {
1196 new->sender = ah;
1197
1198 stats->imp_updates_received++;
1199 if (!rte_validate(new))
1200 {
1201 rte_trace_in(D_FILTERS, p, new, "invalid");
1202 stats->imp_updates_invalid++;
1203 goto drop;
1204 }
1205
1206 if (filter == FILTER_REJECT)
1207 {
1208 stats->imp_updates_filtered++;
1209 rte_trace_in(D_FILTERS, p, new, "filtered out");
1210
1211 if (! ah->in_keep_filtered)
1212 goto drop;
1213
1214 /* new is a private copy, i could modify it */
1215 new->flags |= REF_FILTERED;
1216 }
1217 else
1218 {
1219 tmpa = rte_make_tmp_attrs(new, rte_update_pool);
1220 if (filter && (filter != FILTER_REJECT))
1221 {
1222 ea_list *old_tmpa = tmpa;
1223 int fr = f_run(filter, &new, &tmpa, rte_update_pool, 0);
1224 if (fr > F_ACCEPT)
1225 {
1226 stats->imp_updates_filtered++;
1227 rte_trace_in(D_FILTERS, p, new, "filtered out");
1228
1229 if (! ah->in_keep_filtered)
1230 goto drop;
1231
1232 new->flags |= REF_FILTERED;
1233 }
1234 if (tmpa != old_tmpa && src->proto->store_tmp_attrs)
1235 src->proto->store_tmp_attrs(new, tmpa);
1236 }
1237 }
1238 if (!rta_is_cached(new->attrs)) /* Need to copy attributes */
1239 new->attrs = rta_lookup(new->attrs);
1240 new->flags |= REF_COW;
1241 }
1242 else
1243 {
1244 stats->imp_withdraws_received++;
1245
1246 if (!net || !src)
1247 {
1248 stats->imp_withdraws_ignored++;
1249 rte_update_unlock();
1250 return;
1251 }
1252 }
1253
1254 recalc:
1255 rte_hide_dummy_routes(net, &dummy);
1256 rte_recalculate(ah, net, new, src);
1257 rte_unhide_dummy_routes(net, &dummy);
1258 rte_update_unlock();
1259 return;
1260
1261 drop:
1262 rte_free(new);
1263 new = NULL;
1264 goto recalc;
1265 }
1266
1267 /* Independent call to rte_announce(), used from next hop
1268 recalculation, outside of rte_update(). new must be non-NULL */
1269 static inline void
1270 rte_announce_i(rtable *tab, unsigned type, net *net, rte *new, rte *old,
1271 rte *new_best, rte *old_best)
1272 {
1273 rte_update_lock();
1274 rte_announce(tab, type, net, new, old, new_best, old_best, NULL);
1275 rte_update_unlock();
1276 }
1277
1278 static inline void
1279 rte_discard(rte *old) /* Non-filtered route deletion, used during garbage collection */
1280 {
1281 rte_update_lock();
1282 rte_recalculate(old->sender, old->net, NULL, old->attrs->src);
1283 rte_update_unlock();
1284 }
1285
1286 /* Check rtable for best route to given net whether it would be exported do p */
1287 int
1288 rt_examine(rtable *t, ip_addr prefix, int pxlen, struct proto *p, struct filter *filter)
1289 {
1290 net *n = net_find(t, prefix, pxlen);
1291 rte *rt = n ? n->routes : NULL;
1292
1293 if (!rte_is_valid(rt))
1294 return 0;
1295
1296 rte_update_lock();
1297
1298 /* Rest is stripped down export_filter() */
1299 ea_list *tmpa = rte_make_tmp_attrs(rt, rte_update_pool);
1300 int v = p->import_control ? p->import_control(p, &rt, &tmpa, rte_update_pool) : 0;
1301 if (v == RIC_PROCESS)
1302 v = (f_run(filter, &rt, &tmpa, rte_update_pool,
1303 FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT);
1304
1305 /* Discard temporary rte */
1306 if (rt != n->routes)
1307 rte_free(rt);
1308
1309 rte_update_unlock();
1310
1311 return v > 0;
1312 }
1313
1314
1315 /**
1316 * rt_refresh_begin - start a refresh cycle
1317 * @t: related routing table
1318 * @ah: related announce hook
1319 *
1320 * This function starts a refresh cycle for given routing table and announce
1321 * hook. The refresh cycle is a sequence where the protocol sends all its valid
1322 * routes to the routing table (by rte_update()). After that, all protocol
1323 * routes (more precisely routes with @ah as @sender) not sent during the
1324 * refresh cycle but still in the table from the past are pruned. This is
1325 * implemented by marking all related routes as stale by REF_STALE flag in
1326 * rt_refresh_begin(), then marking all related stale routes with REF_DISCARD
1327 * flag in rt_refresh_end() and then removing such routes in the prune loop.
1328 */
1329 void
1330 rt_refresh_begin(rtable *t, struct announce_hook *ah)
1331 {
1332 net *n;
1333 rte *e;
1334
1335 FIB_WALK(&t->fib, fn)
1336 {
1337 n = (net *) fn;
1338 for (e = n->routes; e; e = e->next)
1339 if (e->sender == ah)
1340 e->flags |= REF_STALE;
1341 }
1342 FIB_WALK_END;
1343 }
1344
1345 /**
1346 * rt_refresh_end - end a refresh cycle
1347 * @t: related routing table
1348 * @ah: related announce hook
1349 *
1350 * This function starts a refresh cycle for given routing table and announce
1351 * hook. See rt_refresh_begin() for description of refresh cycles.
1352 */
1353 void
1354 rt_refresh_end(rtable *t, struct announce_hook *ah)
1355 {
1356 int prune = 0;
1357 net *n;
1358 rte *e;
1359
1360 FIB_WALK(&t->fib, fn)
1361 {
1362 n = (net *) fn;
1363 for (e = n->routes; e; e = e->next)
1364 if ((e->sender == ah) && (e->flags & REF_STALE))
1365 {
1366 e->flags |= REF_DISCARD;
1367 prune = 1;
1368 }
1369 }
1370 FIB_WALK_END;
1371
1372 if (prune)
1373 rt_schedule_prune(t);
1374 }
1375
1376
1377 /**
1378 * rte_dump - dump a route
1379 * @e: &rte to be dumped
1380 *
1381 * This functions dumps contents of a &rte to debug output.
1382 */
1383 void
1384 rte_dump(rte *e)
1385 {
1386 net *n = e->net;
1387 debug("%-1I/%2d ", n->n.prefix, n->n.pxlen);
1388 debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod);
1389 rta_dump(e->attrs);
1390 if (e->attrs->src->proto->proto->dump_attrs)
1391 e->attrs->src->proto->proto->dump_attrs(e);
1392 debug("\n");
1393 }
1394
1395 /**
1396 * rt_dump - dump a routing table
1397 * @t: routing table to be dumped
1398 *
1399 * This function dumps contents of a given routing table to debug output.
1400 */
1401 void
1402 rt_dump(rtable *t)
1403 {
1404 rte *e;
1405 net *n;
1406 struct announce_hook *a;
1407
1408 debug("Dump of routing table <%s>\n", t->name);
1409 #ifdef DEBUGGING
1410 fib_check(&t->fib);
1411 #endif
1412 FIB_WALK(&t->fib, fn)
1413 {
1414 n = (net *) fn;
1415 for(e=n->routes; e; e=e->next)
1416 rte_dump(e);
1417 }
1418 FIB_WALK_END;
1419 WALK_LIST(a, t->hooks)
1420 debug("\tAnnounces routes to protocol %s\n", a->proto->name);
1421 debug("\n");
1422 }
1423
1424 /**
1425 * rt_dump_all - dump all routing tables
1426 *
1427 * This function dumps contents of all routing tables to debug output.
1428 */
1429 void
1430 rt_dump_all(void)
1431 {
1432 rtable *t;
1433
1434 WALK_LIST(t, routing_tables)
1435 rt_dump(t);
1436 }
1437
1438 static inline void
1439 rt_schedule_prune(rtable *tab)
1440 {
1441 rt_mark_for_prune(tab);
1442 ev_schedule(tab->rt_event);
1443 }
1444
1445 static inline void
1446 rt_schedule_gc(rtable *tab)
1447 {
1448 if (tab->gc_scheduled)
1449 return;
1450
1451 tab->gc_scheduled = 1;
1452 ev_schedule(tab->rt_event);
1453 }
1454
1455 static inline void
1456 rt_schedule_hcu(rtable *tab)
1457 {
1458 if (tab->hcu_scheduled)
1459 return;
1460
1461 tab->hcu_scheduled = 1;
1462 ev_schedule(tab->rt_event);
1463 }
1464
1465 static inline void
1466 rt_schedule_nhu(rtable *tab)
1467 {
1468 if (tab->nhu_state == 0)
1469 ev_schedule(tab->rt_event);
1470
1471 /* state change 0->1, 2->3 */
1472 tab->nhu_state |= 1;
1473 }
1474
1475
1476 static void
1477 rt_prune_nets(rtable *tab)
1478 {
1479 struct fib_iterator fit;
1480 int ncnt = 0, ndel = 0;
1481
1482 #ifdef DEBUGGING
1483 fib_check(&tab->fib);
1484 #endif
1485
1486 FIB_ITERATE_INIT(&fit, &tab->fib);
1487 again:
1488 FIB_ITERATE_START(&tab->fib, &fit, f)
1489 {
1490 net *n = (net *) f;
1491 ncnt++;
1492 if (!n->routes) /* Orphaned FIB entry */
1493 {
1494 FIB_ITERATE_PUT(&fit, f);
1495 fib_delete(&tab->fib, f);
1496 ndel++;
1497 goto again;
1498 }
1499 }
1500 FIB_ITERATE_END(f);
1501 DBG("Pruned %d of %d networks\n", ndel, ncnt);
1502
1503 tab->gc_counter = 0;
1504 tab->gc_time = now;
1505 tab->gc_scheduled = 0;
1506 }
1507
1508 static void
1509 rt_event(void *ptr)
1510 {
1511 rtable *tab = ptr;
1512
1513 if (tab->hcu_scheduled)
1514 rt_update_hostcache(tab);
1515
1516 if (tab->nhu_state)
1517 rt_next_hop_update(tab);
1518
1519 if (tab->prune_state)
1520 if (!rt_prune_table(tab))
1521 {
1522 /* Table prune unfinished */
1523 ev_schedule(tab->rt_event);
1524 return;
1525 }
1526
1527 if (tab->gc_scheduled)
1528 {
1529 rt_prune_nets(tab);
1530 rt_prune_sources(); // FIXME this should be moved to independent event
1531 }
1532 }
1533
1534 void
1535 rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
1536 {
1537 bzero(t, sizeof(*t));
1538 fib_init(&t->fib, p, sizeof(net), 0, rte_init);
1539 t->name = name;
1540 t->config = cf;
1541 init_list(&t->hooks);
1542 if (cf)
1543 {
1544 t->rt_event = ev_new(p);
1545 t->rt_event->hook = rt_event;
1546 t->rt_event->data = t;
1547 t->gc_time = now;
1548 }
1549 }
1550
1551 /**
1552 * rt_init - initialize routing tables
1553 *
1554 * This function is called during BIRD startup. It initializes the
1555 * routing table module.
1556 */
1557 void
1558 rt_init(void)
1559 {
1560 rta_init();
1561 rt_table_pool = rp_new(&root_pool, "Routing tables");
1562 rte_update_pool = lp_new(rt_table_pool, 4080);
1563 rte_slab = sl_new(rt_table_pool, sizeof(rte));
1564 init_list(&routing_tables);
1565 }
1566
1567
1568 static int
1569 rt_prune_step(rtable *tab, int *limit)
1570 {
1571 struct fib_iterator *fit = &tab->prune_fit;
1572
1573 DBG("Pruning route table %s\n", tab->name);
1574 #ifdef DEBUGGING
1575 fib_check(&tab->fib);
1576 #endif
1577
1578 if (tab->prune_state == RPS_NONE)
1579 return 1;
1580
1581 if (tab->prune_state == RPS_SCHEDULED)
1582 {
1583 FIB_ITERATE_INIT(fit, &tab->fib);
1584 tab->prune_state = RPS_RUNNING;
1585 }
1586
1587 again:
1588 FIB_ITERATE_START(&tab->fib, fit, fn)
1589 {
1590 net *n = (net *) fn;
1591 rte *e;
1592
1593 rescan:
1594 for (e=n->routes; e; e=e->next)
1595 if (e->sender->proto->flushing || (e->flags & REF_DISCARD))
1596 {
1597 if (*limit <= 0)
1598 {
1599 FIB_ITERATE_PUT(fit, fn);
1600 return 0;
1601 }
1602
1603 rte_discard(e);
1604 (*limit)--;
1605
1606 goto rescan;
1607 }
1608 if (!n->routes) /* Orphaned FIB entry */
1609 {
1610 FIB_ITERATE_PUT(fit, fn);
1611 fib_delete(&tab->fib, fn);
1612 goto again;
1613 }
1614 }
1615 FIB_ITERATE_END(fn);
1616
1617 #ifdef DEBUGGING
1618 fib_check(&tab->fib);
1619 #endif
1620
1621 tab->prune_state = RPS_NONE;
1622 return 1;
1623 }
1624
1625 /**
1626 * rt_prune_table - prune a routing table
1627 * @tab: a routing table for pruning
1628 *
1629 * This function scans the routing table @tab and removes routes belonging to
1630 * flushing protocols, discarded routes and also stale network entries, in a
1631 * similar fashion like rt_prune_loop(). Returns 1 when all such routes are
1632 * pruned. Contrary to rt_prune_loop(), this function is not a part of the
1633 * protocol flushing loop, but it is called from rt_event() for just one routing
1634 * table.
1635 *
1636 * Note that rt_prune_table() and rt_prune_loop() share (for each table) the
1637 * prune state (@prune_state) and also the pruning iterator (@prune_fit).
1638 */
1639 static inline int
1640 rt_prune_table(rtable *tab)
1641 {
1642 int limit = 512;
1643 return rt_prune_step(tab, &limit);
1644 }
1645
1646 /**
1647 * rt_prune_loop - prune routing tables
1648 *
1649 * The prune loop scans routing tables and removes routes belonging to flushing
1650 * protocols, discarded routes and also stale network entries. Returns 1 when
1651 * all such routes are pruned. It is a part of the protocol flushing loop.
1652 */
1653 int
1654 rt_prune_loop(void)
1655 {
1656 int limit = 512;
1657 rtable *t;
1658
1659 WALK_LIST(t, routing_tables)
1660 if (! rt_prune_step(t, &limit))
1661 return 0;
1662
1663 return 1;
1664 }
1665
1666 void
1667 rt_preconfig(struct config *c)
1668 {
1669 struct symbol *s = cf_get_symbol("master");
1670
1671 init_list(&c->tables);
1672 c->master_rtc = rt_new_table(s);
1673 }
1674
1675
1676 /*
1677 * Some functions for handing internal next hop updates
1678 * triggered by rt_schedule_nhu().
1679 */
1680
1681 static inline int
1682 rta_next_hop_outdated(rta *a)
1683 {
1684 struct hostentry *he = a->hostentry;
1685
1686 if (!he)
1687 return 0;
1688
1689 if (!he->src)
1690 return a->dest != RTD_UNREACHABLE;
1691
1692 return (a->iface != he->src->iface) || !ipa_equal(a->gw, he->gw) ||
1693 (a->dest != he->dest) || (a->igp_metric != he->igp_metric) ||
1694 !mpnh_same(a->nexthops, he->src->nexthops);
1695 }
1696
1697 static inline void
1698 rta_apply_hostentry(rta *a, struct hostentry *he)
1699 {
1700 a->hostentry = he;
1701 a->iface = he->src ? he->src->iface : NULL;
1702 a->gw = he->gw;
1703 a->dest = he->dest;
1704 a->igp_metric = he->igp_metric;
1705 a->nexthops = he->src ? he->src->nexthops : NULL;
1706 }
1707
1708 static inline rte *
1709 rt_next_hop_update_rte(rtable *tab UNUSED, rte *old)
1710 {
1711 rta a;
1712 memcpy(&a, old->attrs, sizeof(rta));
1713 rta_apply_hostentry(&a, old->attrs->hostentry);
1714 a.aflags = 0;
1715
1716 rte *e = sl_alloc(rte_slab);
1717 memcpy(e, old, sizeof(rte));
1718 e->attrs = rta_lookup(&a);
1719
1720 return e;
1721 }
1722
1723 static inline int
1724 rt_next_hop_update_net(rtable *tab, net *n)
1725 {
1726 rte **k, *e, *new, *old_best, **new_best;
1727 int count = 0;
1728 int free_old_best = 0;
1729
1730 old_best = n->routes;
1731 if (!old_best)
1732 return 0;
1733
1734 for (k = &n->routes; e = *k; k = &e->next)
1735 if (rta_next_hop_outdated(e->attrs))
1736 {
1737 new = rt_next_hop_update_rte(tab, e);
1738 *k = new;
1739
1740 rte_announce_i(tab, RA_ANY, n, new, e, NULL, NULL);
1741 rte_trace_in(D_ROUTES, new->sender->proto, new, "updated");
1742
1743 /* Call a pre-comparison hook */
1744 /* Not really an efficient way to compute this */
1745 if (e->attrs->src->proto->rte_recalculate)
1746 e->attrs->src->proto->rte_recalculate(tab, n, new, e, NULL);
1747
1748 if (e != old_best)
1749 rte_free_quick(e);
1750 else /* Freeing of the old best rte is postponed */
1751 free_old_best = 1;
1752
1753 e = new;
1754 count++;
1755 }
1756
1757 if (!count)
1758 return 0;
1759
1760 /* Find the new best route */
1761 new_best = NULL;
1762 for (k = &n->routes; e = *k; k = &e->next)
1763 {
1764 if (!new_best || rte_better(e, *new_best))
1765 new_best = k;
1766 }
1767
1768 /* Relink the new best route to the first position */
1769 new = *new_best;
1770 if (new != n->routes)
1771 {
1772 *new_best = new->next;
1773 new->next = n->routes;
1774 n->routes = new;
1775 }
1776
1777 /* Announce the new best route */
1778 if (new != old_best)
1779 {
1780 rte_announce_i(tab, RA_OPTIMAL, n, new, old_best, NULL, NULL);
1781 rte_trace_in(D_ROUTES, new->sender->proto, new, "updated [best]");
1782 }
1783
1784 /* FIXME: Better announcement of merged routes */
1785 rte_announce_i(tab, RA_MERGED, n, new, old_best, new, old_best);
1786
1787 if (free_old_best)
1788 rte_free_quick(old_best);
1789
1790 return count;
1791 }
1792
1793 static void
1794 rt_next_hop_update(rtable *tab)
1795 {
1796 struct fib_iterator *fit = &tab->nhu_fit;
1797 int max_feed = 32;
1798
1799 if (tab->nhu_state == 0)
1800 return;
1801
1802 if (tab->nhu_state == 1)
1803 {
1804 FIB_ITERATE_INIT(fit, &tab->fib);
1805 tab->nhu_state = 2;
1806 }
1807
1808 FIB_ITERATE_START(&tab->fib, fit, fn)
1809 {
1810 if (max_feed <= 0)
1811 {
1812 FIB_ITERATE_PUT(fit, fn);
1813 ev_schedule(tab->rt_event);
1814 return;
1815 }
1816 max_feed -= rt_next_hop_update_net(tab, (net *) fn);
1817 }
1818 FIB_ITERATE_END(fn);
1819
1820 /* state change 2->0, 3->1 */
1821 tab->nhu_state &= 1;
1822
1823 if (tab->nhu_state > 0)
1824 ev_schedule(tab->rt_event);
1825 }
1826
1827
1828 struct rtable_config *
1829 rt_new_table(struct symbol *s)
1830 {
1831 /* Hack that allows to 'redefine' the master table */
1832 if ((s->class == SYM_TABLE) && (s->def == new_config->master_rtc))
1833 return s->def;
1834
1835 struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
1836
1837 cf_define_symbol(s, SYM_TABLE, c);
1838 c->name = s->name;
1839 add_tail(&new_config->tables, &c->n);
1840 c->gc_max_ops = 1000;
1841 c->gc_min_time = 5;
1842 return c;
1843 }
1844
1845 /**
1846 * rt_lock_table - lock a routing table
1847 * @r: routing table to be locked
1848 *
1849 * Lock a routing table, because it's in use by a protocol,
1850 * preventing it from being freed when it gets undefined in a new
1851 * configuration.
1852 */
1853 void
1854 rt_lock_table(rtable *r)
1855 {
1856 r->use_count++;
1857 }
1858
1859 /**
1860 * rt_unlock_table - unlock a routing table
1861 * @r: routing table to be unlocked
1862 *
1863 * Unlock a routing table formerly locked by rt_lock_table(),
1864 * that is decrease its use count and delete it if it's scheduled
1865 * for deletion by configuration changes.
1866 */
1867 void
1868 rt_unlock_table(rtable *r)
1869 {
1870 if (!--r->use_count && r->deleted)
1871 {
1872 struct config *conf = r->deleted;
1873 DBG("Deleting routing table %s\n", r->name);
1874 r->config->table = NULL;
1875 if (r->hostcache)
1876 rt_free_hostcache(r);
1877 rem_node(&r->n);
1878 fib_free(&r->fib);
1879 rfree(r->rt_event);
1880 mb_free(r);
1881 config_del_obstacle(conf);
1882 }
1883 }
1884
1885 /**
1886 * rt_commit - commit new routing table configuration
1887 * @new: new configuration
1888 * @old: original configuration or %NULL if it's boot time config
1889 *
1890 * Scan differences between @old and @new configuration and modify
1891 * the routing tables according to these changes. If @new defines a
1892 * previously unknown table, create it, if it omits a table existing
1893 * in @old, schedule it for deletion (it gets deleted when all protocols
1894 * disconnect from it by calling rt_unlock_table()), if it exists
1895 * in both configurations, leave it unchanged.
1896 */
1897 void
1898 rt_commit(struct config *new, struct config *old)
1899 {
1900 struct rtable_config *o, *r;
1901
1902 DBG("rt_commit:\n");
1903 if (old)
1904 {
1905 WALK_LIST(o, old->tables)
1906 {
1907 rtable *ot = o->table;
1908 if (!ot->deleted)
1909 {
1910 struct symbol *sym = cf_find_symbol(new, o->name);
1911 if (sym && sym->class == SYM_TABLE && !new->shutdown)
1912 {
1913 DBG("\t%s: same\n", o->name);
1914 r = sym->def;
1915 r->table = ot;
1916 ot->name = r->name;
1917 ot->config = r;
1918 if (o->sorted != r->sorted)
1919 log(L_WARN "Reconfiguration of rtable sorted flag not implemented");
1920 }
1921 else
1922 {
1923 DBG("\t%s: deleted\n", o->name);
1924 ot->deleted = old;
1925 config_add_obstacle(old);
1926 rt_lock_table(ot);
1927 rt_unlock_table(ot);
1928 }
1929 }
1930 }
1931 }
1932
1933 WALK_LIST(r, new->tables)
1934 if (!r->table)
1935 {
1936 rtable *t = mb_alloc(rt_table_pool, sizeof(struct rtable));
1937 DBG("\t%s: created\n", r->name);
1938 rt_setup(rt_table_pool, t, r->name, r);
1939 add_tail(&routing_tables, &t->n);
1940 r->table = t;
1941 }
1942 DBG("\tdone\n");
1943 }
1944
1945 static inline void
1946 do_feed_baby(struct proto *p, int type, struct announce_hook *h, net *n, rte *e)
1947 {
1948 rte_update_lock();
1949 if (type == RA_ACCEPTED)
1950 rt_notify_accepted(h, n, e, NULL, NULL, p->refeeding ? 2 : 1);
1951 else if (type == RA_MERGED)
1952 rt_notify_merged(h, n, NULL, NULL, e, p->refeeding ? e : NULL, p->refeeding);
1953 else
1954 rt_notify_basic(h, n, e, p->refeeding ? e : NULL, p->refeeding);
1955 rte_update_unlock();
1956 }
1957
1958 /**
1959 * rt_feed_baby - advertise routes to a new protocol
1960 * @p: protocol to be fed
1961 *
1962 * This function performs one pass of advertisement of routes to a newly
1963 * initialized protocol. It's called by the protocol code as long as it
1964 * has something to do. (We avoid transferring all the routes in single
1965 * pass in order not to monopolize CPU time.)
1966 */
1967 int
1968 rt_feed_baby(struct proto *p)
1969 {
1970 struct announce_hook *h;
1971 struct fib_iterator *fit;
1972 int max_feed = 256;
1973
1974 if (!p->feed_ahook) /* Need to initialize first */
1975 {
1976 if (!p->ahooks)
1977 return 1;
1978 DBG("Announcing routes to new protocol %s\n", p->name);
1979 p->feed_ahook = p->ahooks;
1980 fit = p->feed_iterator = mb_alloc(p->pool, sizeof(struct fib_iterator));
1981 goto next_hook;
1982 }
1983 fit = p->feed_iterator;
1984
1985 again:
1986 h = p->feed_ahook;
1987 FIB_ITERATE_START(&h->table->fib, fit, fn)
1988 {
1989 net *n = (net *) fn;
1990 rte *e = n->routes;
1991 if (max_feed <= 0)
1992 {
1993 FIB_ITERATE_PUT(fit, fn);
1994 return 0;
1995 }
1996
1997 /* XXXX perhaps we should change feed for RA_ACCEPTED to not use 'new' */
1998
1999 if ((p->accept_ra_types == RA_OPTIMAL) ||
2000 (p->accept_ra_types == RA_ACCEPTED) ||
2001 (p->accept_ra_types == RA_MERGED))
2002 if (rte_is_valid(e))
2003 {
2004 if (p->export_state != ES_FEEDING)
2005 return 1; /* In the meantime, the protocol fell down. */
2006
2007 do_feed_baby(p, p->accept_ra_types, h, n, e);
2008 max_feed--;
2009 }
2010
2011 if (p->accept_ra_types == RA_ANY)
2012 for(e = n->routes; e; e = e->next)
2013 {
2014 if (p->export_state != ES_FEEDING)
2015 return 1; /* In the meantime, the protocol fell down. */
2016
2017 if (!rte_is_valid(e))
2018 continue;
2019
2020 do_feed_baby(p, RA_ANY, h, n, e);
2021 max_feed--;
2022 }
2023 }
2024 FIB_ITERATE_END(fn);
2025 p->feed_ahook = h->next;
2026 if (!p->feed_ahook)
2027 {
2028 mb_free(p->feed_iterator);
2029 p->feed_iterator = NULL;
2030 return 1;
2031 }
2032
2033 next_hook:
2034 h = p->feed_ahook;
2035 FIB_ITERATE_INIT(fit, &h->table->fib);
2036 goto again;
2037 }
2038
2039 /**
2040 * rt_feed_baby_abort - abort protocol feeding
2041 * @p: protocol
2042 *
2043 * This function is called by the protocol code when the protocol
2044 * stops or ceases to exist before the last iteration of rt_feed_baby()
2045 * has finished.
2046 */
2047 void
2048 rt_feed_baby_abort(struct proto *p)
2049 {
2050 if (p->feed_ahook)
2051 {
2052 /* Unlink the iterator and exit */
2053 fit_get(&p->feed_ahook->table->fib, p->feed_iterator);
2054 p->feed_ahook = NULL;
2055 }
2056 }
2057
2058
2059 static inline unsigned
2060 ptr_hash(void *ptr)
2061 {
2062 uintptr_t p = (uintptr_t) ptr;
2063 return p ^ (p << 8) ^ (p >> 16);
2064 }
2065
2066 static inline unsigned
2067 hc_hash(ip_addr a, rtable *dep)
2068 {
2069 return (ipa_hash(a) ^ ptr_hash(dep)) & 0xffff;
2070 }
2071
2072 static inline void
2073 hc_insert(struct hostcache *hc, struct hostentry *he)
2074 {
2075 uint k = he->hash_key >> hc->hash_shift;
2076 he->next = hc->hash_table[k];
2077 hc->hash_table[k] = he;
2078 }
2079
2080 static inline void
2081 hc_remove(struct hostcache *hc, struct hostentry *he)
2082 {
2083 struct hostentry **hep;
2084 uint k = he->hash_key >> hc->hash_shift;
2085
2086 for (hep = &hc->hash_table[k]; *hep != he; hep = &(*hep)->next);
2087 *hep = he->next;
2088 }
2089
2090 #define HC_DEF_ORDER 10
2091 #define HC_HI_MARK *4
2092 #define HC_HI_STEP 2
2093 #define HC_HI_ORDER 16 /* Must be at most 16 */
2094 #define HC_LO_MARK /5
2095 #define HC_LO_STEP 2
2096 #define HC_LO_ORDER 10
2097
2098 static void
2099 hc_alloc_table(struct hostcache *hc, unsigned order)
2100 {
2101 uint hsize = 1 << order;
2102 hc->hash_order = order;
2103 hc->hash_shift = 16 - order;
2104 hc->hash_max = (order >= HC_HI_ORDER) ? ~0U : (hsize HC_HI_MARK);
2105 hc->hash_min = (order <= HC_LO_ORDER) ? 0U : (hsize HC_LO_MARK);
2106
2107 hc->hash_table = mb_allocz(rt_table_pool, hsize * sizeof(struct hostentry *));
2108 }
2109
2110 static void
2111 hc_resize(struct hostcache *hc, unsigned new_order)
2112 {
2113 struct hostentry **old_table = hc->hash_table;
2114 struct hostentry *he, *hen;
2115 uint old_size = 1 << hc->hash_order;
2116 uint i;
2117
2118 hc_alloc_table(hc, new_order);
2119 for (i = 0; i < old_size; i++)
2120 for (he = old_table[i]; he != NULL; he=hen)
2121 {
2122 hen = he->next;
2123 hc_insert(hc, he);
2124 }
2125 mb_free(old_table);
2126 }
2127
2128 static struct hostentry *
2129 hc_new_hostentry(struct hostcache *hc, ip_addr a, ip_addr ll, rtable *dep, unsigned k)
2130 {
2131 struct hostentry *he = sl_alloc(hc->slab);
2132
2133 he->addr = a;
2134 he->link = ll;
2135 he->tab = dep;
2136 he->hash_key = k;
2137 he->uc = 0;
2138 he->src = NULL;
2139
2140 add_tail(&hc->hostentries, &he->ln);
2141 hc_insert(hc, he);
2142
2143 hc->hash_items++;
2144 if (hc->hash_items > hc->hash_max)
2145 hc_resize(hc, hc->hash_order + HC_HI_STEP);
2146
2147 return he;
2148 }
2149
2150 static void
2151 hc_delete_hostentry(struct hostcache *hc, struct hostentry *he)
2152 {
2153 rta_free(he->src);
2154
2155 rem_node(&he->ln);
2156 hc_remove(hc, he);
2157 sl_free(hc->slab, he);
2158
2159 hc->hash_items--;
2160 if (hc->hash_items < hc->hash_min)
2161 hc_resize(hc, hc->hash_order - HC_LO_STEP);
2162 }
2163
2164 static void
2165 rt_init_hostcache(rtable *tab)
2166 {
2167 struct hostcache *hc = mb_allocz(rt_table_pool, sizeof(struct hostcache));
2168 init_list(&hc->hostentries);
2169
2170 hc->hash_items = 0;
2171 hc_alloc_table(hc, HC_DEF_ORDER);
2172 hc->slab = sl_new(rt_table_pool, sizeof(struct hostentry));
2173
2174 hc->lp = lp_new(rt_table_pool, 1008);
2175 hc->trie = f_new_trie(hc->lp, sizeof(struct f_trie_node));
2176
2177 tab->hostcache = hc;
2178 }
2179
2180 static void
2181 rt_free_hostcache(rtable *tab)
2182 {
2183 struct hostcache *hc = tab->hostcache;
2184
2185 node *n;
2186 WALK_LIST(n, hc->hostentries)
2187 {
2188 struct hostentry *he = SKIP_BACK(struct hostentry, ln, n);
2189 rta_free(he->src);
2190
2191 if (he->uc)
2192 log(L_ERR "Hostcache is not empty in table %s", tab->name);
2193 }
2194
2195 rfree(hc->slab);
2196 rfree(hc->lp);
2197 mb_free(hc->hash_table);
2198 mb_free(hc);
2199 }
2200
2201 static void
2202 rt_notify_hostcache(rtable *tab, net *net)
2203 {
2204 struct hostcache *hc = tab->hostcache;
2205
2206 if (tab->hcu_scheduled)
2207 return;
2208
2209 if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
2210 rt_schedule_hcu(tab);
2211 }
2212
2213 static int
2214 if_local_addr(ip_addr a, struct iface *i)
2215 {
2216 struct ifa *b;
2217
2218 WALK_LIST(b, i->addrs)
2219 if (ipa_equal(a, b->ip))
2220 return 1;
2221
2222 return 0;
2223 }
2224
2225 static u32
2226 rt_get_igp_metric(rte *rt)
2227 {
2228 eattr *ea = ea_find(rt->attrs->eattrs, EA_GEN_IGP_METRIC);
2229
2230 if (ea)
2231 return ea->u.data;
2232
2233 rta *a = rt->attrs;
2234
2235 #ifdef CONFIG_OSPF
2236 if ((a->source == RTS_OSPF) ||
2237 (a->source == RTS_OSPF_IA) ||
2238 (a->source == RTS_OSPF_EXT1))
2239 return rt->u.ospf.metric1;
2240 #endif
2241
2242 #ifdef CONFIG_RIP
2243 if (a->source == RTS_RIP)
2244 return rt->u.rip.metric;
2245 #endif
2246
2247 /* Device routes */
2248 if ((a->dest != RTD_ROUTER) && (a->dest != RTD_MULTIPATH))
2249 return 0;
2250
2251 return IGP_METRIC_UNKNOWN;
2252 }
2253
2254 static int
2255 rt_update_hostentry(rtable *tab, struct hostentry *he)
2256 {
2257 rta *old_src = he->src;
2258 int pxlen = 0;
2259
2260 /* Reset the hostentry */
2261 he->src = NULL;
2262 he->gw = IPA_NONE;
2263 he->dest = RTD_UNREACHABLE;
2264 he->igp_metric = 0;
2265
2266 net *n = net_route(tab, he->addr, MAX_PREFIX_LENGTH);
2267 if (n)
2268 {
2269 rte *e = n->routes;
2270 rta *a = e->attrs;
2271 pxlen = n->n.pxlen;
2272
2273 if (a->hostentry)
2274 {
2275 /* Recursive route should not depend on another recursive route */
2276 log(L_WARN "Next hop address %I resolvable through recursive route for %I/%d",
2277 he->addr, n->n.prefix, pxlen);
2278 goto done;
2279 }
2280
2281 if (a->dest == RTD_DEVICE)
2282 {
2283 if (if_local_addr(he->addr, a->iface))
2284 {
2285 /* The host address is a local address, this is not valid */
2286 log(L_WARN "Next hop address %I is a local address of iface %s",
2287 he->addr, a->iface->name);
2288 goto done;
2289 }
2290
2291 /* The host is directly reachable, use link as a gateway */
2292 he->gw = he->link;
2293 he->dest = RTD_ROUTER;
2294 }
2295 else
2296 {
2297 /* The host is reachable through some route entry */
2298 he->gw = a->gw;
2299 he->dest = a->dest;
2300 }
2301
2302 he->src = rta_clone(a);
2303 he->igp_metric = rt_get_igp_metric(e);
2304 }
2305
2306 done:
2307 /* Add a prefix range to the trie */
2308 trie_add_prefix(tab->hostcache->trie, he->addr, MAX_PREFIX_LENGTH, pxlen, MAX_PREFIX_LENGTH);
2309
2310 rta_free(old_src);
2311 return old_src != he->src;
2312 }
2313
2314 static void
2315 rt_update_hostcache(rtable *tab)
2316 {
2317 struct hostcache *hc = tab->hostcache;
2318 struct hostentry *he;
2319 node *n, *x;
2320
2321 /* Reset the trie */
2322 lp_flush(hc->lp);
2323 hc->trie = f_new_trie(hc->lp, sizeof(struct f_trie_node));
2324
2325 WALK_LIST_DELSAFE(n, x, hc->hostentries)
2326 {
2327 he = SKIP_BACK(struct hostentry, ln, n);
2328 if (!he->uc)
2329 {
2330 hc_delete_hostentry(hc, he);
2331 continue;
2332 }
2333
2334 if (rt_update_hostentry(tab, he))
2335 rt_schedule_nhu(he->tab);
2336 }
2337
2338 tab->hcu_scheduled = 0;
2339 }
2340
2341 static struct hostentry *
2342 rt_get_hostentry(rtable *tab, ip_addr a, ip_addr ll, rtable *dep)
2343 {
2344 struct hostentry *he;
2345
2346 if (!tab->hostcache)
2347 rt_init_hostcache(tab);
2348
2349 uint k = hc_hash(a, dep);
2350 struct hostcache *hc = tab->hostcache;
2351 for (he = hc->hash_table[k >> hc->hash_shift]; he != NULL; he = he->next)
2352 if (ipa_equal(he->addr, a) && (he->tab == dep))
2353 return he;
2354
2355 he = hc_new_hostentry(hc, a, ll, dep, k);
2356 rt_update_hostentry(tab, he);
2357 return he;
2358 }
2359
2360 void
2361 rta_set_recursive_next_hop(rtable *dep, rta *a, rtable *tab, ip_addr *gw, ip_addr *ll)
2362 {
2363 rta_apply_hostentry(a, rt_get_hostentry(tab, *gw, *ll, dep));
2364 }
2365
2366
2367 /*
2368 * CLI commands
2369 */
2370
2371 static byte *
2372 rt_format_via(rte *e)
2373 {
2374 rta *a = e->attrs;
2375
2376 /* Max text length w/o IP addr and interface name is 16 */
2377 static byte via[STD_ADDRESS_P_LENGTH+sizeof(a->iface->name)+16];
2378
2379 switch (a->dest)
2380 {
2381 case RTD_ROUTER: bsprintf(via, "via %I on %s", a->gw, a->iface->name); break;
2382 case RTD_DEVICE: bsprintf(via, "dev %s", a->iface->name); break;
2383 case RTD_BLACKHOLE: bsprintf(via, "blackhole"); break;
2384 case RTD_UNREACHABLE: bsprintf(via, "unreachable"); break;
2385 case RTD_PROHIBIT: bsprintf(via, "prohibited"); break;
2386 case RTD_MULTIPATH: bsprintf(via, "multipath"); break;
2387 default: bsprintf(via, "???");
2388 }
2389 return via;
2390 }
2391
2392 static void
2393 rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tmpa)
2394 {
2395 byte from[STD_ADDRESS_P_LENGTH+8];
2396 byte tm[TM_DATETIME_BUFFER_SIZE], info[256];
2397 rta *a = e->attrs;
2398 int primary = (e->net->routes == e);
2399 int sync_error = (e->net->n.flags & KRF_SYNC_ERROR);
2400 void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs);
2401 struct mpnh *nh;
2402
2403 tm_format_datetime(tm, &config->tf_route, e->lastmod);
2404 if (ipa_nonzero(a->from) && !ipa_equal(a->from, a->gw))
2405 bsprintf(from, " from %I", a->from);
2406 else
2407 from[0] = 0;
2408
2409 get_route_info = a->src->proto->proto->get_route_info;
2410 if (get_route_info || d->verbose)
2411 {
2412 /* Need to normalize the extended attributes */
2413 ea_list *t = tmpa;
2414 t = ea_append(t, a->eattrs);
2415 tmpa = alloca(ea_scan(t));
2416 ea_merge(t, tmpa);
2417 ea_sort(tmpa);
2418 }
2419 if (get_route_info)
2420 get_route_info(e, info, tmpa);
2421 else
2422 bsprintf(info, " (%d)", e->pref);
2423 cli_printf(c, -1007, "%-18s %s [%s %s%s]%s%s", ia, rt_format_via(e), a->src->proto->name,
2424 tm, from, primary ? (sync_error ? " !" : " *") : "", info);
2425 for (nh = a->nexthops; nh; nh = nh->next)
2426 cli_printf(c, -1007, "\tvia %I on %s weight %d", nh->gw, nh->iface->name, nh->weight + 1);
2427 if (d->verbose)
2428 rta_show(c, a, tmpa);
2429 }
2430
2431 static void
2432 rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
2433 {
2434 rte *e, *ee;
2435 byte ia[STD_ADDRESS_P_LENGTH+8];
2436 struct ea_list *tmpa;
2437 struct announce_hook *a = NULL;
2438 int first = 1;
2439 int pass = 0;
2440
2441 bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
2442
2443 if (d->export_mode)
2444 {
2445 if (! d->export_protocol->rt_notify)
2446 return;
2447
2448 a = proto_find_announce_hook(d->export_protocol, d->table);
2449 if (!a)
2450 return;
2451 }
2452
2453 for (e = n->routes; e; e = e->next)
2454 {
2455 if (rte_is_filtered(e) != d->filtered)
2456 continue;
2457
2458 d->rt_counter++;
2459 d->net_counter += first;
2460 first = 0;
2461
2462 if (pass)
2463 continue;
2464
2465 ee = e;
2466 rte_update_lock(); /* We use the update buffer for filtering */
2467 tmpa = rte_make_tmp_attrs(e, rte_update_pool);
2468
2469 /* Special case for merged export */
2470 if ((d->export_mode == RSEM_EXPORT) && (d->export_protocol->accept_ra_types == RA_MERGED))
2471 {
2472 rte *rt_free;
2473 e = rt_export_merged(a, n, &rt_free, &tmpa, rte_update_pool, 1);
2474 pass = 1;
2475
2476 if (!e)
2477 { e = ee; goto skip; }
2478 }
2479 else if (d->export_mode)
2480 {
2481 struct proto *ep = d->export_protocol;
2482 int ic = ep->import_control ? ep->import_control(ep, &e, &tmpa, rte_update_pool) : 0;
2483
2484 if (ep->accept_ra_types == RA_OPTIMAL || ep->accept_ra_types == RA_MERGED)
2485 pass = 1;
2486
2487 if (ic < 0)
2488 goto skip;
2489
2490 if (d->export_mode > RSEM_PREEXPORT)
2491 {
2492 /*
2493 * FIXME - This shows what should be exported according to current
2494 * filters, but not what was really exported. 'configure soft'
2495 * command may change the export filter and do not update routes.
2496 */
2497 int do_export = (ic > 0) ||
2498 (f_run(a->out_filter, &e, &tmpa, rte_update_pool,
2499 FF_FORCE_TMPATTR | FF_SILENT) <= F_ACCEPT);
2500
2501 if (do_export != (d->export_mode == RSEM_EXPORT))
2502 goto skip;
2503
2504 if ((d->export_mode == RSEM_EXPORT) && (ep->accept_ra_types == RA_ACCEPTED))
2505 pass = 1;
2506 }
2507 }
2508
2509 if (d->show_protocol && (d->show_protocol != e->attrs->src->proto))
2510 goto skip;
2511
2512 if (f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)
2513 goto skip;
2514
2515 d->show_counter++;
2516 if (d->stats < 2)
2517 rt_show_rte(c, ia, e, d, tmpa);
2518 ia[0] = 0;
2519
2520 skip:
2521 if (e != ee)
2522 {
2523 rte_free(e);
2524 e = ee;
2525 }
2526 rte_update_unlock();
2527
2528 if (d->primary_only)
2529 break;
2530 }
2531 }
2532
2533 static void
2534 rt_show_cont(struct cli *c)
2535 {
2536 struct rt_show_data *d = c->rover;
2537 #ifdef DEBUGGING
2538 unsigned max = 4;
2539 #else
2540 unsigned max = 64;
2541 #endif
2542 struct fib *fib = &d->table->fib;
2543 struct fib_iterator *it = &d->fit;
2544
2545 FIB_ITERATE_START(fib, it, f)
2546 {
2547 net *n = (net *) f;
2548 if (d->running_on_config && d->running_on_config != config)
2549 {
2550 cli_printf(c, 8004, "Stopped due to reconfiguration");
2551 goto done;
2552 }
2553 if (d->export_protocol && (d->export_protocol->export_state == ES_DOWN))
2554 {
2555 cli_printf(c, 8005, "Protocol is down");
2556 goto done;
2557 }
2558 if (!max--)
2559 {
2560 FIB_ITERATE_PUT(it, f);
2561 return;
2562 }
2563 rt_show_net(c, n, d);
2564 }
2565 FIB_ITERATE_END(f);
2566 if (d->stats)
2567 cli_printf(c, 14, "%d of %d routes for %d networks", d->show_counter, d->rt_counter, d->net_counter);
2568 else
2569 cli_printf(c, 0, "");
2570 done:
2571 c->cont = c->cleanup = NULL;
2572 }
2573
2574 static void
2575 rt_show_cleanup(struct cli *c)
2576 {
2577 struct rt_show_data *d = c->rover;
2578
2579 /* Unlink the iterator */
2580 fit_get(&d->table->fib, &d->fit);
2581 }
2582
2583 void
2584 rt_show(struct rt_show_data *d)
2585 {
2586 net *n;
2587
2588 /* Default is either a master table or a table related to a respective protocol */
2589 if (!d->table && d->export_protocol) d->table = d->export_protocol->table;
2590 if (!d->table && d->show_protocol) d->table = d->show_protocol->table;
2591 if (!d->table) d->table = config->master_rtc->table;
2592
2593 /* Filtered routes are neither exported nor have sensible ordering */
2594 if (d->filtered && (d->export_mode || d->primary_only))
2595 cli_msg(0, "");
2596
2597 if (d->pxlen == 256)
2598 {
2599 FIB_ITERATE_INIT(&d->fit, &d->table->fib);
2600 this_cli->cont = rt_show_cont;
2601 this_cli->cleanup = rt_show_cleanup;
2602 this_cli->rover = d;
2603 }
2604 else
2605 {
2606 if (d->show_for)
2607 n = net_route(d->table, d->prefix, d->pxlen);
2608 else
2609 n = net_find(d->table, d->prefix, d->pxlen);
2610
2611 if (n)
2612 rt_show_net(this_cli, n, d);
2613
2614 if (d->rt_counter)
2615 cli_msg(0, "");
2616 else
2617 cli_msg(8001, "Network not in table");
2618 }
2619 }
2620
2621 /*
2622 * Documentation for functions declared inline in route.h
2623 */
2624 #if 0
2625
2626 /**
2627 * net_find - find a network entry
2628 * @tab: a routing table
2629 * @addr: address of the network
2630 * @len: length of the network prefix
2631 *
2632 * net_find() looks up the given network in routing table @tab and
2633 * returns a pointer to its &net entry or %NULL if no such network
2634 * exists.
2635 */
2636 static inline net *net_find(rtable *tab, ip_addr addr, unsigned len)
2637 { DUMMY; }
2638
2639 /**
2640 * net_get - obtain a network entry
2641 * @tab: a routing table
2642 * @addr: address of the network
2643 * @len: length of the network prefix
2644 *
2645 * net_get() looks up the given network in routing table @tab and
2646 * returns a pointer to its &net entry. If no such entry exists, it's
2647 * created.
2648 */
2649 static inline net *net_get(rtable *tab, ip_addr addr, unsigned len)
2650 { DUMMY; }
2651
2652 /**
2653 * rte_cow - copy a route for writing
2654 * @r: a route entry to be copied
2655 *
2656 * rte_cow() takes a &rte and prepares it for modification. The exact action
2657 * taken depends on the flags of the &rte -- if it's a temporary entry, it's
2658 * just returned unchanged, else a new temporary entry with the same contents
2659 * is created.
2660 *
2661 * The primary use of this function is inside the filter machinery -- when
2662 * a filter wants to modify &rte contents (to change the preference or to
2663 * attach another set of attributes), it must ensure that the &rte is not
2664 * shared with anyone else (and especially that it isn't stored in any routing
2665 * table).
2666 *
2667 * Result: a pointer to the new writable &rte.
2668 */
2669 static inline rte * rte_cow(rte *r)
2670 { DUMMY; }
2671
2672 #endif