]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/rt-table.c
2 * BIRD -- Routing Tables
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
12 * Routing tables are probably the most important structures BIRD uses. They
13 * hold all the information about known networks, the associated routes and
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.
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.
33 #include "nest/bird.h"
34 #include "nest/route.h"
35 #include "nest/protocol.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"
48 static slab
*rte_slab
;
49 static linpool
*rte_update_pool
;
51 static list routing_tables
;
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
);
59 static inline void rt_schedule_gc(rtable
*tab
);
61 /* Like fib_route(), but skips empty net entries */
63 net_route(rtable
*tab
, ip_addr a
, int len
)
70 a0
= ipa_and(a
, ipa_mkmask(len
));
71 n
= fib_find(&tab
->fib
, &a0
, len
);
80 rte_init(struct fib_node
*N
)
89 * rte_find - find a route
93 * The rte_find() function returns a route for destination @net
94 * which belongs has been defined by protocol @p.
97 rte_find(net
*net
, struct proto
*p
)
101 while (e
&& e
->attrs
->proto
!= p
)
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)
111 * Create a temporary &rte and bind it with the attributes @a.
112 * Also set route preference to the default preference set for
118 rte
*e
= sl_alloc(rte_slab
);
122 e
->pref
= a
->proto
->preference
;
129 rte
*e
= sl_alloc(rte_slab
);
131 memcpy(e
, r
, sizeof(rte
));
132 e
->attrs
= rta_clone(r
->attrs
);
137 static int /* Actually better or at least as good as */
138 rte_better(rte
*new, rte
*old
)
140 int (*better
)(rte
*, rte
*);
144 if (new->pref
> old
->pref
)
146 if (new->pref
< old
->pref
)
148 if (new->attrs
->proto
->proto
!= old
->attrs
->proto
->proto
)
151 * If the user has configured protocol preferences, so that two different protocols
152 * have the same preference, try to break the tie by comparing addresses. Not too
153 * useful, but keeps the ordering of routes unambiguous.
155 return new->attrs
->proto
->proto
> old
->attrs
->proto
->proto
;
157 if (better
= new->attrs
->proto
->rte_better
)
158 return better(new, old
);
163 rte_trace(struct proto
*p
, rte
*e
, int dir
, char *msg
)
165 byte via
[STD_ADDRESS_P_LENGTH
+32];
167 rt_format_via(e
, via
);
168 log(L_TRACE
"%s %c %s %I/%d %s", p
->name
, dir
, msg
, e
->net
->n
.prefix
, e
->net
->n
.pxlen
, via
);
172 rte_trace_in(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
175 rte_trace(p
, e
, '>', msg
);
179 rte_trace_out(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
182 rte_trace(p
, e
, '<', msg
);
186 export_filter(struct announce_hook
*ah
, rte
*rt0
, rte
**rt_free
, ea_list
**tmpa
, int silent
)
188 struct proto
*p
= ah
->proto
;
189 struct filter
*filter
= ah
->out_filter
;
190 struct proto_stats
*stats
= ah
->stats
;
191 ea_list
*tmpb
= NULL
;
198 /* If called does not care for eattrs, we prepare one internally */
201 struct proto
*src
= rt
->attrs
->proto
;
202 tmpb
= src
->make_tmp_attrs
? src
->make_tmp_attrs(rt
, rte_update_pool
) : NULL
;
206 v
= p
->import_control
? p
->import_control(p
, &rt
, tmpa
, rte_update_pool
) : 0;
212 stats
->exp_updates_rejected
++;
213 rte_trace_out(D_FILTERS
, p
, rt
, "rejected by protocol");
219 rte_trace_out(D_FILTERS
, p
, rt
, "forced accept by protocol");
223 v
= filter
&& ((filter
== FILTER_REJECT
) ||
224 (f_run(filter
, &rt
, tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
));
230 stats
->exp_updates_filtered
++;
231 rte_trace_out(D_FILTERS
, p
, rt
, "filtered out");
241 /* Discard temporary rte */
248 do_rt_notify(struct announce_hook
*ah
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
, int refeed
)
250 struct proto
*p
= ah
->proto
;
251 struct proto_stats
*stats
= ah
->stats
;
254 stats
->exp_updates_accepted
++;
256 stats
->exp_withdraws_accepted
++;
258 /* Hack: We do not decrease exp_routes during refeed, we instead
259 reset exp_routes at the start of refeed. */
265 if (p
->debug
& D_ROUTES
)
268 rte_trace_out(D_ROUTES
, p
, new, "replaced");
270 rte_trace_out(D_ROUTES
, p
, new, "added");
272 rte_trace_out(D_ROUTES
, p
, old
, "removed");
275 p
->rt_notify(p
, ah
->table
, net
, NULL
, old
, NULL
);
281 t
->next
= new->attrs
->eattrs
;
282 p
->rt_notify(p
, ah
->table
, net
, new, old
, tmpa
);
286 p
->rt_notify(p
, ah
->table
, net
, new, old
, new->attrs
->eattrs
);
292 rt_notify_basic(struct announce_hook
*ah
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
, int refeed
)
294 // struct proto *p = ah->proto;
295 struct proto_stats
*stats
= ah
->stats
;
297 rte
*new_free
= NULL
;
298 rte
*old_free
= NULL
;
301 stats
->exp_updates_received
++;
303 stats
->exp_withdraws_received
++;
306 * This is a tricky part - we don't know whether route 'old' was
307 * exported to protocol 'p' or was filtered by the export filter.
308 * We try to run the export filter to know this to have a correct
309 * value in 'old' argument of rte_update (and proper filter value)
311 * FIXME - this is broken because 'configure soft' may change
312 * filters but keep routes. Refeed is expected to be called after
313 * change of the filters and with old == new, therefore we do not
314 * even try to run the filter on an old route, This may lead to
315 * 'spurious withdraws' but ensure that there are no 'missing
318 * This is not completely safe as there is a window between
319 * reconfiguration and the end of refeed - if a newly filtered
320 * route disappears during this period, proper withdraw is not
321 * sent (because old would be also filtered) and the route is
322 * not refeeded (because it disappeared before that).
326 new = export_filter(ah
, new, &new_free
, &tmpa
, 0);
329 old
= export_filter(ah
, old
, &old_free
, NULL
, 1);
331 /* FIXME - This is broken because of incorrect 'old' value (see above) */
335 do_rt_notify(ah
, net
, new, old
, tmpa
, refeed
);
337 /* Discard temporary rte's */
345 rt_notify_accepted(struct announce_hook
*ah
, net
*net
, rte
*new_changed
, rte
*old_changed
, rte
*before_old
,
346 ea_list
*tmpa
, int feed
)
348 // struct proto *p = ah->proto;
349 struct proto_stats
*stats
= ah
->stats
;
351 rte
*new_best
= NULL
;
352 rte
*old_best
= NULL
;
353 rte
*new_free
= NULL
;
354 rte
*old_free
= NULL
;
357 /* Used to track whether we met old_changed position. If it is NULL
358 it was the first and met it implicitly before current best route. */
359 int old_meet
= (old_changed
&& !before_old
) ? 1 : 0;
362 stats
->exp_updates_received
++;
364 stats
->exp_withdraws_received
++;
366 /* First, find the new_best route - first accepted by filters */
367 for (r
=net
->routes
; r
; r
=r
->next
)
369 if (new_best
= export_filter(ah
, r
, &new_free
, &tmpa
, 0))
372 /* Note if we walked around the position of old_changed route */
378 * Second, handle the feed case. That means we do not care for
379 * old_best. It is NULL for feed, and the new_best for refeed.
380 * For refeed, there is a hack similar to one in rt_notify_basic()
381 * to ensure withdraws in case of changed filters
385 if (feed
== 2) /* refeed */
386 old_best
= new_best
? new_best
: net
->routes
;
390 if (!new_best
&& !old_best
)
397 * Now, we find the old_best route. Generally, it is the same as the
398 * new_best, unless new_best is the same as new_changed or
399 * old_changed is accepted before new_best.
401 * There are four cases:
403 * - We would find and accept old_changed before new_best, therefore
404 * old_changed is old_best. In remaining cases we suppose this
407 * - We found no new_best, therefore there is also no old_best and
408 * we ignore this withdraw.
410 * - We found new_best different than new_changed, therefore
411 * old_best is the same as new_best and we ignore this update.
413 * - We found new_best the same as new_changed, therefore it cannot
414 * be old_best and we have to continue search for old_best.
419 if (old_best
= export_filter(ah
, old_changed
, &old_free
, NULL
, 1))
426 /* Third case, we use r instead of new_best, because export_filter() could change it */
427 if (r
!= new_changed
)
435 for (r
=r
->next
; r
; r
=r
->next
)
437 if (old_best
= export_filter(ah
, r
, &old_free
, NULL
, 1))
441 if (old_best
= export_filter(ah
, old_changed
, &old_free
, NULL
, 1))
445 /* Implicitly, old_best is NULL and new_best is non-NULL */
448 do_rt_notify(ah
, net
, new_best
, old_best
, tmpa
, (feed
== 2));
450 /* Discard temporary rte's */
458 * rte_announce - announce a routing table change
459 * @tab: table the route has been added to
460 * @type: type of route announcement (RA_OPTIMAL or RA_ANY)
461 * @net: network in question
462 * @new: the new route to be announced
463 * @old: the previous route for the same network
464 * @tmpa: a list of temporary attributes belonging to the new route
466 * This function gets a routing table update and announces it
467 * to all protocols that acccepts given type of route announcement
468 * and are connected to the same table by their announcement hooks.
470 * Route announcement of type RA_OPTIMAL si generated when optimal
471 * route (in routing table @tab) changes. In that case @old stores the
474 * Route announcement of type RA_ANY si generated when any route (in
475 * routing table @tab) changes In that case @old stores the old route
476 * from the same protocol.
478 * For each appropriate protocol, we first call its import_control()
479 * hook which performs basic checks on the route (each protocol has a
480 * right to veto or force accept of the route before any filter is
481 * asked) and adds default values of attributes specific to the new
482 * protocol (metrics, tags etc.). Then it consults the protocol's
483 * export filter and if it accepts the route, the rt_notify() hook of
484 * the protocol gets called.
487 rte_announce(rtable
*tab
, unsigned type
, net
*net
, rte
*new, rte
*old
, rte
*before_old
, ea_list
*tmpa
)
489 struct announce_hook
*a
;
491 if (type
== RA_OPTIMAL
)
494 new->attrs
->proto
->stats
.pref_routes
++;
496 old
->attrs
->proto
->stats
.pref_routes
--;
499 rt_notify_hostcache(tab
, net
);
502 WALK_LIST(a
, tab
->hooks
)
504 ASSERT(a
->proto
->core_state
== FS_HAPPY
|| a
->proto
->core_state
== FS_FEEDING
);
505 if (a
->proto
->accept_ra_types
== type
)
506 if (type
== RA_ACCEPTED
)
507 rt_notify_accepted(a
, net
, new, old
, before_old
, tmpa
, 0);
509 rt_notify_basic(a
, net
, new, old
, tmpa
, 0);
519 if ((n
->n
.pxlen
> BITS_PER_IP_ADDRESS
) || !ip_is_prefix(n
->n
.prefix
,n
->n
.pxlen
))
521 log(L_WARN
"Ignoring bogus prefix %I/%d received via %s",
522 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->proto
->name
);
526 c
= ipa_classify_net(n
->n
.prefix
);
527 if ((c
< 0) || !(c
& IADDR_HOST
) || ((c
& IADDR_SCOPE_MASK
) <= SCOPE_LINK
))
529 log(L_WARN
"Ignoring bogus route %I/%d received via %s",
530 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->proto
->name
);
538 * rte_free - delete a &rte
539 * @e: &rte to be deleted
541 * rte_free() deletes the given &rte from the routing table it's linked to.
546 if (e
->attrs
->aflags
& RTAF_CACHED
)
548 sl_free(rte_slab
, e
);
552 rte_free_quick(rte
*e
)
555 sl_free(rte_slab
, e
);
559 rte_same(rte
*x
, rte
*y
)
562 x
->attrs
== y
->attrs
&&
563 x
->flags
== y
->flags
&&
564 x
->pflags
== y
->pflags
&&
565 x
->pref
== y
->pref
&&
566 (!x
->attrs
->proto
->rte_same
|| x
->attrs
->proto
->rte_same(x
, y
));
570 rte_recalculate(struct announce_hook
*ah
, net
*net
, rte
*new, ea_list
*tmpa
, struct proto
*src
)
572 struct proto
*p
= ah
->proto
;
573 struct rtable
*table
= ah
->table
;
574 struct proto_stats
*stats
= ah
->stats
;
575 rte
*before_old
= NULL
;
576 rte
*old_best
= net
->routes
;
580 k
= &net
->routes
; /* Find and remove original route from the same protocol */
583 if (old
->attrs
->proto
== src
)
585 /* If there is the same route in the routing table but from
586 * a different sender, then there are two paths from the
587 * source protocol to this routing table through transparent
588 * pipes, which is not allowed.
590 * We log that and ignore the route. If it is withdraw, we
591 * ignore it completely (there might be 'spurious withdraws',
592 * see FIXME in do_rte_announce())
594 if (old
->sender
->proto
!= p
)
598 log(L_ERR
"Pipe collision detected when sending %I/%d to table %s",
599 net
->n
.prefix
, net
->n
.pxlen
, table
->name
);
605 if (new && rte_same(old
, new))
607 /* No changes, ignore the new route */
608 stats
->imp_updates_ignored
++;
609 rte_trace_in(D_ROUTES
, p
, new, "ignored");
612 /* lastmod is used internally by RIP as the last time
613 when the route was received. */
614 if (src
->proto
== &proto_rip
)
631 stats
->imp_withdraws_ignored
++;
636 stats
->imp_updates_accepted
++;
638 stats
->imp_withdraws_accepted
++;
645 if (table
->config
->sorted
)
647 /* If routes are sorted, just insert new route to appropriate position */
650 if (before_old
&& !rte_better(new, before_old
))
651 k
= &before_old
->next
;
655 for (; *k
; k
=&(*k
)->next
)
656 if (rte_better(new, *k
))
665 /* If routes are not sorted, find the best route and move it on
666 the first position. There are several optimized cases. */
668 if (src
->rte_recalculate
&& src
->rte_recalculate(table
, net
, new, old
, old_best
))
671 if (new && rte_better(new, old_best
))
673 /* The first case - the new route is cleary optimal,
674 we link it at the first position */
676 new->next
= net
->routes
;
679 else if (old
== old_best
)
681 /* The second case - the old best route disappeared, we add the
682 new route (if we have any) to the list (we don't care about
683 position) and then we elect the new optimal route and relink
684 that route at the first position and announce it. New optimal
685 route might be NULL if there is no more routes */
688 /* Add the new route to the list */
691 new->next
= net
->routes
;
695 /* Find a new optimal route (if there is any) */
698 rte
**bp
= &net
->routes
;
699 for (k
=&(*bp
)->next
; *k
; k
=&(*k
)->next
)
700 if (rte_better(*k
, *bp
))
706 best
->next
= net
->routes
;
712 /* The third case - the new route is not better than the old
713 best route (therefore old_best != NULL) and the old best
714 route was not removed (therefore old_best == net->routes).
715 We just link the new route after the old best route. */
717 ASSERT(net
->routes
!= NULL
);
718 new->next
= net
->routes
->next
;
719 net
->routes
->next
= new;
721 /* The fourth (empty) case - suboptimal route was removed, nothing to do */
727 /* Log the route change */
729 rte_trace_in(D_ROUTES
, p
, new, net
->routes
== new ? "added [best]" : "added");
731 if (!new && (p
->debug
& D_ROUTES
))
734 rte_trace_in(D_ROUTES
, p
, old
, "removed");
735 else if (net
->routes
)
736 rte_trace_in(D_ROUTES
, p
, old
, "removed [replaced]");
738 rte_trace_in(D_ROUTES
, p
, old
, "removed [sole]");
741 /* Propagate the route change */
742 rte_announce(table
, RA_ANY
, net
, new, old
, NULL
, tmpa
);
743 if (net
->routes
!= old_best
)
744 rte_announce(table
, RA_OPTIMAL
, net
, net
->routes
, old_best
, NULL
, tmpa
);
745 if (table
->config
->sorted
)
746 rte_announce(table
, RA_ACCEPTED
, net
, new, old
, before_old
, tmpa
);
749 (table
->gc_counter
++ >= table
->config
->gc_max_ops
) &&
750 (table
->gc_time
+ table
->config
->gc_min_time
<= now
))
751 rt_schedule_gc(table
);
756 p
->rte_remove(net
, old
);
762 p
->rte_insert(net
, new);
766 static int rte_update_nest_cnt
; /* Nesting counter to allow recursive updates */
769 rte_update_lock(void)
771 rte_update_nest_cnt
++;
775 rte_update_unlock(void)
777 if (!--rte_update_nest_cnt
)
778 lp_flush(rte_update_pool
);
782 * rte_update - enter a new update to a routing table
783 * @table: table to be updated
784 * @ah: pointer to table announce hook
786 * @p: protocol submitting the update
787 * @src: protocol originating the update
788 * @new: a &rte representing the new route or %NULL for route removal.
790 * This function is called by the routing protocols whenever they discover
791 * a new route or wish to update/remove an existing route. The right announcement
792 * sequence is to build route attributes first (either un-cached with @aflags set
793 * to zero or a cached one using rta_lookup(); in this case please note that
794 * you need to increase the use count of the attributes yourself by calling
795 * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
796 * the appropriate data and finally submit the new &rte by calling rte_update().
798 * @src specifies the protocol that originally created the route and the meaning
799 * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
800 * same value as @new->attrs->proto. @p specifies the protocol that called
801 * rte_update(). In most cases it is the same protocol as @src. rte_update()
802 * stores @p in @new->sender;
804 * When rte_update() gets any route, it automatically validates it (checks,
805 * whether the network and next hop address are valid IP addresses and also
806 * whether a normal routing protocol doesn't try to smuggle a host or link
807 * scope route to the table), converts all protocol dependent attributes stored
808 * in the &rte to temporary extended attributes, consults import filters of the
809 * protocol to see if the route should be accepted and/or its attributes modified,
810 * stores the temporary attributes back to the &rte.
812 * Now, having a "public" version of the route, we
813 * automatically find any old route defined by the protocol @src
814 * for network @n, replace it by the new one (or removing it if @new is %NULL),
815 * recalculate the optimal route for this destination and finally broadcast
816 * the change (if any) to all routing protocols by calling rte_announce().
818 * All memory used for attribute lists and other temporary allocations is taken
819 * from a special linear pool @rte_update_pool and freed when rte_update()
824 rte_update2(struct announce_hook
*ah
, net
*net
, rte
*new, struct proto
*src
)
826 struct proto
*p
= ah
->proto
;
827 struct proto_stats
*stats
= ah
->stats
;
828 struct filter
*filter
= ah
->in_filter
;
829 ea_list
*tmpa
= NULL
;
836 stats
->imp_updates_received
++;
837 if (!rte_validate(new))
839 rte_trace_in(D_FILTERS
, p
, new, "invalid");
840 stats
->imp_updates_invalid
++;
843 if (filter
== FILTER_REJECT
)
845 stats
->imp_updates_filtered
++;
846 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
849 if (src
->make_tmp_attrs
)
850 tmpa
= src
->make_tmp_attrs(new, rte_update_pool
);
853 ea_list
*old_tmpa
= tmpa
;
854 int fr
= f_run(filter
, &new, &tmpa
, rte_update_pool
, 0);
857 stats
->imp_updates_filtered
++;
858 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
861 if (tmpa
!= old_tmpa
&& src
->store_tmp_attrs
)
862 src
->store_tmp_attrs(new, tmpa
);
864 if (!(new->attrs
->aflags
& RTAF_CACHED
)) /* Need to copy attributes */
865 new->attrs
= rta_lookup(new->attrs
);
866 new->flags
|= REF_COW
;
869 stats
->imp_withdraws_received
++;
871 rte_recalculate(ah
, net
, new, tmpa
, src
);
877 rte_recalculate(ah
, net
, NULL
, NULL
, src
);
881 /* Independent call to rte_announce(), used from next hop
882 recalculation, outside of rte_update(). new must be non-NULL */
884 rte_announce_i(rtable
*tab
, unsigned type
, net
*n
, rte
*new, rte
*old
)
890 src
= new->attrs
->proto
;
891 tmpa
= src
->make_tmp_attrs
? src
->make_tmp_attrs(new, rte_update_pool
) : NULL
;
892 rte_announce(tab
, type
, n
, new, old
, NULL
, tmpa
);
897 rte_discard(rtable
*t
, rte
*old
) /* Non-filtered route deletion, used during garbage collection */
900 rte_recalculate(old
->sender
, old
->net
, NULL
, NULL
, old
->attrs
->proto
);
905 * rte_dump - dump a route
906 * @e: &rte to be dumped
908 * This functions dumps contents of a &rte to debug output.
915 debug("%-1I/%2d ", n
->n
.prefix
, n
->n
.pxlen
);
918 debug("KF=%02x PF=%02x pref=%d lm=%d ", n
->n
.flags
, e
->pflags
, e
->pref
, now
-e
->lastmod
);
920 if (e
->attrs
->proto
->proto
->dump_attrs
)
921 e
->attrs
->proto
->proto
->dump_attrs(e
);
926 * rt_dump - dump a routing table
927 * @t: routing table to be dumped
929 * This function dumps contents of a given routing table to debug output.
936 struct announce_hook
*a
;
938 debug("Dump of routing table <%s>\n", t
->name
);
942 FIB_WALK(&t
->fib
, fn
)
945 for(e
=n
->routes
; e
; e
=e
->next
)
949 WALK_LIST(a
, t
->hooks
)
950 debug("\tAnnounces routes to protocol %s\n", a
->proto
->name
);
955 * rt_dump_all - dump all routing tables
957 * This function dumps contents of all routing tables to debug output.
964 WALK_LIST(t
, routing_tables
)
969 rt_schedule_gc(rtable
*tab
)
971 if (tab
->gc_scheduled
)
974 tab
->gc_scheduled
= 1;
975 ev_schedule(tab
->rt_event
);
979 rt_schedule_hcu(rtable
*tab
)
981 if (tab
->hcu_scheduled
)
984 tab
->hcu_scheduled
= 1;
985 ev_schedule(tab
->rt_event
);
989 rt_schedule_nhu(rtable
*tab
)
991 if (tab
->nhu_state
== 0)
992 ev_schedule(tab
->rt_event
);
994 /* state change 0->1, 2->3 */
999 rt_prune_nets(rtable
*tab
)
1001 struct fib_iterator fit
;
1002 int ncnt
= 0, ndel
= 0;
1005 fib_check(&tab
->fib
);
1008 FIB_ITERATE_INIT(&fit
, &tab
->fib
);
1010 FIB_ITERATE_START(&tab
->fib
, &fit
, f
)
1014 if (!n
->routes
) /* Orphaned FIB entry */
1016 FIB_ITERATE_PUT(&fit
, f
);
1017 fib_delete(&tab
->fib
, f
);
1023 DBG("Pruned %d of %d networks\n", ndel
, ncnt
);
1025 tab
->gc_counter
= 0;
1027 tab
->gc_scheduled
= 0;
1035 if (tab
->hcu_scheduled
)
1036 rt_update_hostcache(tab
);
1039 rt_next_hop_update(tab
);
1041 if (tab
->gc_scheduled
)
1046 rt_setup(pool
*p
, rtable
*t
, char *name
, struct rtable_config
*cf
)
1048 bzero(t
, sizeof(*t
));
1049 fib_init(&t
->fib
, p
, sizeof(net
), 0, rte_init
);
1052 init_list(&t
->hooks
);
1055 t
->rt_event
= ev_new(p
);
1056 t
->rt_event
->hook
= rt_event
;
1057 t
->rt_event
->data
= t
;
1063 * rt_init - initialize routing tables
1065 * This function is called during BIRD startup. It initializes the
1066 * routing table module.
1072 rt_table_pool
= rp_new(&root_pool
, "Routing tables");
1073 rte_update_pool
= lp_new(rt_table_pool
, 4080);
1074 rte_slab
= sl_new(rt_table_pool
, sizeof(rte
));
1075 init_list(&routing_tables
);
1079 /* Called from proto_schedule_flush_loop() only,
1080 ensuring that all prune states are zero */
1082 rt_schedule_prune_all(void)
1086 WALK_LIST(t
, routing_tables
)
1091 rt_prune_step(rtable
*tab
, int *max_feed
)
1093 struct fib_iterator
*fit
= &tab
->prune_fit
;
1095 DBG("Pruning route table %s\n", tab
->name
);
1097 fib_check(&tab
->fib
);
1100 if (tab
->prune_state
== 0)
1103 if (tab
->prune_state
== 1)
1105 FIB_ITERATE_INIT(fit
, &tab
->fib
);
1106 tab
->prune_state
= 2;
1110 FIB_ITERATE_START(&tab
->fib
, fit
, fn
)
1112 net
*n
= (net
*) fn
;
1116 for (e
=n
->routes
; e
; e
=e
->next
)
1117 if (e
->sender
->proto
->core_state
!= FS_HAPPY
&&
1118 e
->sender
->proto
->core_state
!= FS_FEEDING
)
1122 FIB_ITERATE_PUT(fit
, fn
);
1126 rte_discard(tab
, e
);
1131 if (!n
->routes
) /* Orphaned FIB entry */
1133 FIB_ITERATE_PUT(fit
, fn
);
1134 fib_delete(&tab
->fib
, fn
);
1138 FIB_ITERATE_END(fn
);
1141 fib_check(&tab
->fib
);
1144 tab
->prune_state
= 0;
1149 * rt_prune_loop - prune routing tables
1150 * @tab: routing table to be pruned
1152 * The prune loop scans routing tables and removes routes belonging to
1153 * inactive protocols and also stale network entries. Returns 1 when
1154 * all such routes are pruned. It is a part of the protocol flushing
1163 WALK_LIST(t
, routing_tables
)
1164 if (! rt_prune_step(t
, &max_feed
))
1171 rt_preconfig(struct config
*c
)
1173 struct symbol
*s
= cf_find_symbol("master");
1175 init_list(&c
->tables
);
1176 c
->master_rtc
= rt_new_table(s
);
1181 * Some functions for handing internal next hop updates
1182 * triggered by rt_schedule_nhu().
1186 rta_next_hop_outdated(rta
*a
)
1188 struct hostentry
*he
= a
->hostentry
;
1194 return a
->dest
!= RTD_UNREACHABLE
;
1196 return (a
->iface
!= he
->src
->iface
) || !ipa_equal(a
->gw
, he
->gw
) ||
1197 (a
->dest
!= he
->dest
) || (a
->igp_metric
!= he
->igp_metric
) ||
1198 !mpnh_same(a
->nexthops
, he
->src
->nexthops
);
1202 rta_apply_hostentry(rta
*a
, struct hostentry
*he
)
1205 a
->iface
= he
->src
? he
->src
->iface
: NULL
;
1208 a
->igp_metric
= he
->igp_metric
;
1209 a
->nexthops
= he
->src
? he
->src
->nexthops
: NULL
;
1213 rt_next_hop_update_rte(rtable
*tab
, rte
*old
)
1216 memcpy(&a
, old
->attrs
, sizeof(rta
));
1217 rta_apply_hostentry(&a
, old
->attrs
->hostentry
);
1220 rte
*e
= sl_alloc(rte_slab
);
1221 memcpy(e
, old
, sizeof(rte
));
1222 e
->attrs
= rta_lookup(&a
);
1228 rt_next_hop_update_net(rtable
*tab
, net
*n
)
1230 rte
**k
, *e
, *new, *old_best
, **new_best
;
1232 int free_old_best
= 0;
1234 old_best
= n
->routes
;
1238 for (k
= &n
->routes
; e
= *k
; k
= &e
->next
)
1239 if (rta_next_hop_outdated(e
->attrs
))
1241 new = rt_next_hop_update_rte(tab
, e
);
1244 rte_announce_i(tab
, RA_ANY
, n
, new, e
);
1245 rte_trace_in(D_ROUTES
, new->sender
->proto
, new, "updated");
1247 /* Call a pre-comparison hook */
1248 /* Not really an efficient way to compute this */
1249 if (e
->attrs
->proto
->rte_recalculate
)
1250 e
->attrs
->proto
->rte_recalculate(tab
, n
, new, e
, NULL
);
1254 else /* Freeing of the old best rte is postponed */
1264 /* Find the new best route */
1266 for (k
= &n
->routes
; e
= *k
; k
= &e
->next
)
1268 if (!new_best
|| rte_better(e
, *new_best
))
1272 /* Relink the new best route to the first position */
1274 if (new != n
->routes
)
1276 *new_best
= new->next
;
1277 new->next
= n
->routes
;
1281 /* Announce the new best route */
1282 if (new != old_best
)
1284 rte_announce_i(tab
, RA_OPTIMAL
, n
, new, old_best
);
1285 rte_trace_in(D_ROUTES
, new->sender
->proto
, new, "updated [best]");
1289 rte_free_quick(old_best
);
1295 rt_next_hop_update(rtable
*tab
)
1297 struct fib_iterator
*fit
= &tab
->nhu_fit
;
1300 if (tab
->nhu_state
== 0)
1303 if (tab
->nhu_state
== 1)
1305 FIB_ITERATE_INIT(fit
, &tab
->fib
);
1309 FIB_ITERATE_START(&tab
->fib
, fit
, fn
)
1313 FIB_ITERATE_PUT(fit
, fn
);
1314 ev_schedule(tab
->rt_event
);
1317 max_feed
-= rt_next_hop_update_net(tab
, (net
*) fn
);
1319 FIB_ITERATE_END(fn
);
1321 /* state change 2->0, 3->1 */
1322 tab
->nhu_state
&= 1;
1324 if (tab
->nhu_state
> 0)
1325 ev_schedule(tab
->rt_event
);
1329 struct rtable_config
*
1330 rt_new_table(struct symbol
*s
)
1332 struct rtable_config
*c
= cfg_allocz(sizeof(struct rtable_config
));
1334 cf_define_symbol(s
, SYM_TABLE
, c
);
1336 add_tail(&new_config
->tables
, &c
->n
);
1337 c
->gc_max_ops
= 1000;
1343 * rt_lock_table - lock a routing table
1344 * @r: routing table to be locked
1346 * Lock a routing table, because it's in use by a protocol,
1347 * preventing it from being freed when it gets undefined in a new
1351 rt_lock_table(rtable
*r
)
1357 * rt_unlock_table - unlock a routing table
1358 * @r: routing table to be unlocked
1360 * Unlock a routing table formerly locked by rt_lock_table(),
1361 * that is decrease its use count and delete it if it's scheduled
1362 * for deletion by configuration changes.
1365 rt_unlock_table(rtable
*r
)
1367 if (!--r
->use_count
&& r
->deleted
)
1369 struct config
*conf
= r
->deleted
;
1370 DBG("Deleting routing table %s\n", r
->name
);
1372 rt_free_hostcache(r
);
1377 config_del_obstacle(conf
);
1382 * rt_commit - commit new routing table configuration
1383 * @new: new configuration
1384 * @old: original configuration or %NULL if it's boot time config
1386 * Scan differences between @old and @new configuration and modify
1387 * the routing tables according to these changes. If @new defines a
1388 * previously unknown table, create it, if it omits a table existing
1389 * in @old, schedule it for deletion (it gets deleted when all protocols
1390 * disconnect from it by calling rt_unlock_table()), if it exists
1391 * in both configurations, leave it unchanged.
1394 rt_commit(struct config
*new, struct config
*old
)
1396 struct rtable_config
*o
, *r
;
1398 DBG("rt_commit:\n");
1401 WALK_LIST(o
, old
->tables
)
1403 rtable
*ot
= o
->table
;
1406 struct symbol
*sym
= cf_find_symbol(o
->name
);
1407 if (sym
&& sym
->class == SYM_TABLE
&& !new->shutdown
)
1409 DBG("\t%s: same\n", o
->name
);
1414 if (o
->sorted
!= r
->sorted
)
1415 log(L_WARN
"Reconfiguration of rtable sorted flag not implemented");
1419 DBG("\t%s: deleted\n", o
->name
);
1421 config_add_obstacle(old
);
1423 rt_unlock_table(ot
);
1429 WALK_LIST(r
, new->tables
)
1432 rtable
*t
= mb_alloc(rt_table_pool
, sizeof(struct rtable
));
1433 DBG("\t%s: created\n", r
->name
);
1434 rt_setup(rt_table_pool
, t
, r
->name
, r
);
1435 add_tail(&routing_tables
, &t
->n
);
1442 do_feed_baby(struct proto
*p
, int type
, struct announce_hook
*h
, net
*n
, rte
*e
)
1444 struct proto
*src
= e
->attrs
->proto
;
1448 tmpa
= src
->make_tmp_attrs
? src
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
1449 if (type
== RA_ACCEPTED
)
1450 rt_notify_accepted(h
, n
, e
, NULL
, NULL
, tmpa
, p
->refeeding
? 2 : 1);
1452 rt_notify_basic(h
, n
, e
, p
->refeeding
? e
: NULL
, tmpa
, p
->refeeding
);
1453 rte_update_unlock();
1457 * rt_feed_baby - advertise routes to a new protocol
1458 * @p: protocol to be fed
1460 * This function performs one pass of advertisement of routes to a newly
1461 * initialized protocol. It's called by the protocol code as long as it
1462 * has something to do. (We avoid transferring all the routes in single
1463 * pass in order not to monopolize CPU time.)
1466 rt_feed_baby(struct proto
*p
)
1468 struct announce_hook
*h
;
1469 struct fib_iterator
*fit
;
1472 if (!p
->feed_ahook
) /* Need to initialize first */
1476 DBG("Announcing routes to new protocol %s\n", p
->name
);
1477 p
->feed_ahook
= p
->ahooks
;
1478 fit
= p
->feed_iterator
= mb_alloc(p
->pool
, sizeof(struct fib_iterator
));
1481 fit
= p
->feed_iterator
;
1485 FIB_ITERATE_START(&h
->table
->fib
, fit
, fn
)
1487 net
*n
= (net
*) fn
;
1491 FIB_ITERATE_PUT(fit
, fn
);
1495 if ((p
->accept_ra_types
== RA_OPTIMAL
) ||
1496 (p
->accept_ra_types
== RA_ACCEPTED
))
1499 if (p
->core_state
!= FS_FEEDING
)
1500 return 1; /* In the meantime, the protocol fell down. */
1501 do_feed_baby(p
, p
->accept_ra_types
, h
, n
, e
);
1505 if (p
->accept_ra_types
== RA_ANY
)
1506 for(e
= n
->routes
; e
!= NULL
; e
= e
->next
)
1508 if (p
->core_state
!= FS_FEEDING
)
1509 return 1; /* In the meantime, the protocol fell down. */
1510 do_feed_baby(p
, RA_ANY
, h
, n
, e
);
1514 FIB_ITERATE_END(fn
);
1515 p
->feed_ahook
= h
->next
;
1518 mb_free(p
->feed_iterator
);
1519 p
->feed_iterator
= NULL
;
1525 FIB_ITERATE_INIT(fit
, &h
->table
->fib
);
1530 * rt_feed_baby_abort - abort protocol feeding
1533 * This function is called by the protocol code when the protocol
1534 * stops or ceases to exist before the last iteration of rt_feed_baby()
1538 rt_feed_baby_abort(struct proto
*p
)
1542 /* Unlink the iterator and exit */
1543 fit_get(&p
->feed_ahook
->table
->fib
, p
->feed_iterator
);
1544 p
->feed_ahook
= NULL
;
1549 static inline unsigned
1552 uintptr_t p
= (uintptr_t) ptr
;
1553 return p
^ (p
<< 8) ^ (p
>> 16);
1556 static inline unsigned
1557 hc_hash(ip_addr a
, rtable
*dep
)
1559 return (ipa_hash(a
) ^ ptr_hash(dep
)) & 0xffff;
1563 hc_insert(struct hostcache
*hc
, struct hostentry
*he
)
1565 unsigned int k
= he
->hash_key
>> hc
->hash_shift
;
1566 he
->next
= hc
->hash_table
[k
];
1567 hc
->hash_table
[k
] = he
;
1571 hc_remove(struct hostcache
*hc
, struct hostentry
*he
)
1573 struct hostentry
**hep
;
1574 unsigned int k
= he
->hash_key
>> hc
->hash_shift
;
1576 for (hep
= &hc
->hash_table
[k
]; *hep
!= he
; hep
= &(*hep
)->next
);
1580 #define HC_DEF_ORDER 10
1581 #define HC_HI_MARK *4
1582 #define HC_HI_STEP 2
1583 #define HC_HI_ORDER 16 /* Must be at most 16 */
1584 #define HC_LO_MARK /5
1585 #define HC_LO_STEP 2
1586 #define HC_LO_ORDER 10
1589 hc_alloc_table(struct hostcache
*hc
, unsigned order
)
1591 unsigned hsize
= 1 << order
;
1592 hc
->hash_order
= order
;
1593 hc
->hash_shift
= 16 - order
;
1594 hc
->hash_max
= (order
>= HC_HI_ORDER
) ? ~0 : (hsize HC_HI_MARK
);
1595 hc
->hash_min
= (order
<= HC_LO_ORDER
) ? 0 : (hsize HC_LO_MARK
);
1597 hc
->hash_table
= mb_allocz(rt_table_pool
, hsize
* sizeof(struct hostentry
*));
1601 hc_resize(struct hostcache
*hc
, unsigned new_order
)
1603 unsigned old_size
= 1 << hc
->hash_order
;
1604 struct hostentry
**old_table
= hc
->hash_table
;
1605 struct hostentry
*he
, *hen
;
1608 hc_alloc_table(hc
, new_order
);
1609 for (i
= 0; i
< old_size
; i
++)
1610 for (he
= old_table
[i
]; he
!= NULL
; he
=hen
)
1618 static struct hostentry
*
1619 hc_new_hostentry(struct hostcache
*hc
, ip_addr a
, ip_addr ll
, rtable
*dep
, unsigned k
)
1621 struct hostentry
*he
= sl_alloc(hc
->slab
);
1630 add_tail(&hc
->hostentries
, &he
->ln
);
1634 if (hc
->hash_items
> hc
->hash_max
)
1635 hc_resize(hc
, hc
->hash_order
+ HC_HI_STEP
);
1641 hc_delete_hostentry(struct hostcache
*hc
, struct hostentry
*he
)
1647 sl_free(hc
->slab
, he
);
1650 if (hc
->hash_items
< hc
->hash_min
)
1651 hc_resize(hc
, hc
->hash_order
- HC_LO_STEP
);
1655 rt_init_hostcache(rtable
*tab
)
1657 struct hostcache
*hc
= mb_allocz(rt_table_pool
, sizeof(struct hostcache
));
1658 init_list(&hc
->hostentries
);
1661 hc_alloc_table(hc
, HC_DEF_ORDER
);
1662 hc
->slab
= sl_new(rt_table_pool
, sizeof(struct hostentry
));
1664 hc
->lp
= lp_new(rt_table_pool
, 1008);
1665 hc
->trie
= f_new_trie(hc
->lp
);
1667 tab
->hostcache
= hc
;
1671 rt_free_hostcache(rtable
*tab
)
1673 struct hostcache
*hc
= tab
->hostcache
;
1676 WALK_LIST(n
, hc
->hostentries
)
1678 struct hostentry
*he
= SKIP_BACK(struct hostentry
, ln
, n
);
1682 log(L_ERR
"Hostcache is not empty in table %s", tab
->name
);
1687 mb_free(hc
->hash_table
);
1692 rt_notify_hostcache(rtable
*tab
, net
*net
)
1694 struct hostcache
*hc
= tab
->hostcache
;
1696 if (tab
->hcu_scheduled
)
1699 if (trie_match_prefix(hc
->trie
, net
->n
.prefix
, net
->n
.pxlen
))
1700 rt_schedule_hcu(tab
);
1704 if_local_addr(ip_addr a
, struct iface
*i
)
1708 WALK_LIST(b
, i
->addrs
)
1709 if (ipa_equal(a
, b
->ip
))
1716 rt_get_igp_metric(rte
*rt
)
1718 eattr
*ea
= ea_find(rt
->attrs
->eattrs
, EA_GEN_IGP_METRIC
);
1726 if ((a
->source
== RTS_OSPF
) ||
1727 (a
->source
== RTS_OSPF_IA
) ||
1728 (a
->source
== RTS_OSPF_EXT1
))
1729 return rt
->u
.ospf
.metric1
;
1733 if (a
->source
== RTS_RIP
)
1734 return rt
->u
.rip
.metric
;
1738 if ((a
->dest
!= RTD_ROUTER
) && (a
->dest
!= RTD_MULTIPATH
))
1741 return IGP_METRIC_UNKNOWN
;
1745 rt_update_hostentry(rtable
*tab
, struct hostentry
*he
)
1747 rta
*old_src
= he
->src
;
1750 /* Reset the hostentry */
1753 he
->dest
= RTD_UNREACHABLE
;
1756 net
*n
= net_route(tab
, he
->addr
, MAX_PREFIX_LENGTH
);
1759 rta
*a
= n
->routes
->attrs
;
1764 /* Recursive route should not depend on another recursive route */
1765 log(L_WARN
"Next hop address %I resolvable through recursive route for %I/%d",
1766 he
->addr
, n
->n
.prefix
, pxlen
);
1770 if (a
->dest
== RTD_DEVICE
)
1772 if (if_local_addr(he
->addr
, a
->iface
))
1774 /* The host address is a local address, this is not valid */
1775 log(L_WARN
"Next hop address %I is a local address of iface %s",
1776 he
->addr
, a
->iface
->name
);
1780 /* The host is directly reachable, use link as a gateway */
1782 he
->dest
= RTD_ROUTER
;
1786 /* The host is reachable through some route entry */
1791 he
->src
= rta_clone(a
);
1792 he
->igp_metric
= rt_get_igp_metric(n
->routes
);
1796 /* Add a prefix range to the trie */
1797 trie_add_prefix(tab
->hostcache
->trie
, he
->addr
, MAX_PREFIX_LENGTH
, pxlen
, MAX_PREFIX_LENGTH
);
1800 return old_src
!= he
->src
;
1804 rt_update_hostcache(rtable
*tab
)
1806 struct hostcache
*hc
= tab
->hostcache
;
1807 struct hostentry
*he
;
1810 /* Reset the trie */
1812 hc
->trie
= f_new_trie(hc
->lp
);
1814 WALK_LIST_DELSAFE(n
, x
, hc
->hostentries
)
1816 he
= SKIP_BACK(struct hostentry
, ln
, n
);
1819 hc_delete_hostentry(hc
, he
);
1823 if (rt_update_hostentry(tab
, he
))
1824 rt_schedule_nhu(he
->tab
);
1827 tab
->hcu_scheduled
= 0;
1830 static struct hostentry
*
1831 rt_find_hostentry(rtable
*tab
, ip_addr a
, ip_addr ll
, rtable
*dep
)
1833 struct hostentry
*he
;
1835 if (!tab
->hostcache
)
1836 rt_init_hostcache(tab
);
1838 unsigned int k
= hc_hash(a
, dep
);
1839 struct hostcache
*hc
= tab
->hostcache
;
1840 for (he
= hc
->hash_table
[k
>> hc
->hash_shift
]; he
!= NULL
; he
= he
->next
)
1841 if (ipa_equal(he
->addr
, a
) && (he
->tab
== dep
))
1844 he
= hc_new_hostentry(hc
, a
, ll
, dep
, k
);
1845 rt_update_hostentry(tab
, he
);
1850 rta_set_recursive_next_hop(rtable
*dep
, rta
*a
, rtable
*tab
, ip_addr
*gw
, ip_addr
*ll
)
1852 rta_apply_hostentry(a
, rt_find_hostentry(tab
, *gw
, *ll
, dep
));
1860 rt_format_via(rte
*e
, byte
*via
)
1866 case RTD_ROUTER
: bsprintf(via
, "via %I on %s", a
->gw
, a
->iface
->name
); break;
1867 case RTD_DEVICE
: bsprintf(via
, "dev %s", a
->iface
->name
); break;
1868 case RTD_BLACKHOLE
: bsprintf(via
, "blackhole"); break;
1869 case RTD_UNREACHABLE
: bsprintf(via
, "unreachable"); break;
1870 case RTD_PROHIBIT
: bsprintf(via
, "prohibited"); break;
1871 case RTD_MULTIPATH
: bsprintf(via
, "multipath"); break;
1872 default: bsprintf(via
, "???");
1877 rt_show_rte(struct cli
*c
, byte
*ia
, rte
*e
, struct rt_show_data
*d
, ea_list
*tmpa
)
1879 byte via
[STD_ADDRESS_P_LENGTH
+32], from
[STD_ADDRESS_P_LENGTH
+8];
1880 byte tm
[TM_DATETIME_BUFFER_SIZE
], info
[256];
1882 int primary
= (e
->net
->routes
== e
);
1883 int sync_error
= (e
->net
->n
.flags
& KRF_SYNC_ERROR
);
1886 rt_format_via(e
, via
);
1887 tm_format_datetime(tm
, &config
->tf_route
, e
->lastmod
);
1888 if (ipa_nonzero(a
->from
) && !ipa_equal(a
->from
, a
->gw
))
1889 bsprintf(from
, " from %I", a
->from
);
1892 if (a
->proto
->proto
->get_route_info
|| d
->verbose
)
1894 /* Need to normalize the extended attributes */
1896 t
= ea_append(t
, a
->eattrs
);
1897 tmpa
= alloca(ea_scan(t
));
1901 if (a
->proto
->proto
->get_route_info
)
1902 a
->proto
->proto
->get_route_info(e
, info
, tmpa
);
1904 bsprintf(info
, " (%d)", e
->pref
);
1905 cli_printf(c
, -1007, "%-18s %s [%s %s%s]%s%s", ia
, via
, a
->proto
->name
,
1906 tm
, from
, primary
? (sync_error
? " !" : " *") : "", info
);
1907 for (nh
= a
->nexthops
; nh
; nh
= nh
->next
)
1908 cli_printf(c
, -1007, "\tvia %I on %s weight %d", nh
->gw
, nh
->iface
->name
, nh
->weight
+ 1);
1910 rta_show(c
, a
, tmpa
);
1914 rt_show_net(struct cli
*c
, net
*n
, struct rt_show_data
*d
)
1917 byte ia
[STD_ADDRESS_P_LENGTH
+8];
1918 struct announce_hook
*a
;
1921 bsprintf(ia
, "%I/%d", n
->n
.prefix
, n
->n
.pxlen
);
1924 for(e
=n
->routes
; e
; e
=e
->next
)
1926 struct ea_list
*tmpa
, *old_tmpa
;
1927 struct proto
*p0
= e
->attrs
->proto
;
1928 struct proto
*p1
= d
->export_protocol
;
1929 struct proto
*p2
= d
->show_protocol
;
1932 rte_update_lock(); /* We use the update buffer for filtering */
1933 old_tmpa
= tmpa
= p0
->make_tmp_attrs
? p0
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
1934 ok
= (d
->filter
== FILTER_ACCEPT
|| f_run(d
->filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) <= F_ACCEPT
);
1935 if (p2
&& p2
!= p0
) ok
= 0;
1936 if (ok
&& d
->export_mode
)
1939 if ((ic
= p1
->import_control
? p1
->import_control(p1
, &e
, &tmpa
, rte_update_pool
) : 0) < 0)
1941 else if (!ic
&& d
->export_mode
> 1)
1943 /* FIXME - this shows what should be exported according
1944 to current filters, but not what was really exported.
1945 'configure soft' command may change the export filter
1946 and do not update routes */
1948 if ((a
= proto_find_announce_hook(p1
, d
->table
)) && ((a
->out_filter
== FILTER_REJECT
) ||
1949 (a
->out_filter
&& f_run(a
->out_filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
)))
1957 rt_show_rte(c
, ia
, e
, d
, tmpa
);
1965 rte_update_unlock();
1966 if (d
->primary_only
)
1972 rt_show_cont(struct cli
*c
)
1974 struct rt_show_data
*d
= c
->rover
;
1980 struct fib
*fib
= &d
->table
->fib
;
1981 struct fib_iterator
*it
= &d
->fit
;
1983 FIB_ITERATE_START(fib
, it
, f
)
1986 if (d
->running_on_config
&& d
->running_on_config
!= config
)
1988 cli_printf(c
, 8004, "Stopped due to reconfiguration");
1991 if (d
->export_protocol
&&
1992 d
->export_protocol
->core_state
!= FS_HAPPY
&&
1993 d
->export_protocol
->core_state
!= FS_FEEDING
)
1995 cli_printf(c
, 8005, "Protocol is down");
2000 FIB_ITERATE_PUT(it
, f
);
2003 rt_show_net(c
, n
, d
);
2007 cli_printf(c
, 14, "%d of %d routes for %d networks", d
->show_counter
, d
->rt_counter
, d
->net_counter
);
2009 cli_printf(c
, 0, "");
2011 c
->cont
= c
->cleanup
= NULL
;
2015 rt_show_cleanup(struct cli
*c
)
2017 struct rt_show_data
*d
= c
->rover
;
2019 /* Unlink the iterator */
2020 fit_get(&d
->table
->fib
, &d
->fit
);
2024 rt_show(struct rt_show_data
*d
)
2028 if (d
->pxlen
== 256)
2030 FIB_ITERATE_INIT(&d
->fit
, &d
->table
->fib
);
2031 this_cli
->cont
= rt_show_cont
;
2032 this_cli
->cleanup
= rt_show_cleanup
;
2033 this_cli
->rover
= d
;
2038 n
= net_route(d
->table
, d
->prefix
, d
->pxlen
);
2040 n
= net_find(d
->table
, d
->prefix
, d
->pxlen
);
2043 rt_show_net(this_cli
, n
, d
);
2047 cli_msg(8001, "Network not in table");
2052 * Documentation for functions declared inline in route.h
2057 * net_find - find a network entry
2058 * @tab: a routing table
2059 * @addr: address of the network
2060 * @len: length of the network prefix
2062 * net_find() looks up the given network in routing table @tab and
2063 * returns a pointer to its &net entry or %NULL if no such network
2066 static inline net
*net_find(rtable
*tab
, ip_addr addr
, unsigned len
)
2070 * net_get - obtain a network entry
2071 * @tab: a routing table
2072 * @addr: address of the network
2073 * @len: length of the network prefix
2075 * net_get() looks up the given network in routing table @tab and
2076 * returns a pointer to its &net entry. If no such entry exists, it's
2079 static inline net
*net_get(rtable
*tab
, ip_addr addr
, unsigned len
)
2083 * rte_cow - copy a route for writing
2084 * @r: a route entry to be copied
2086 * rte_cow() takes a &rte and prepares it for modification. The exact action
2087 * taken depends on the flags of the &rte -- if it's a temporary entry, it's
2088 * just returned unchanged, else a new temporary entry with the same contents
2091 * The primary use of this function is inside the filter machinery -- when
2092 * a filter wants to modify &rte contents (to change the preference or to
2093 * attach another set of attributes), it must ensure that the &rte is not
2094 * shared with anyone else (and especially that it isn't stored in any routing
2097 * Result: a pointer to the new writable &rte.
2099 static inline rte
* rte_cow(rte
*r
)