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