]>
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_free_hostcache(rtable
*tab
);
54 static void rt_notify_hostcache(rtable
*tab
, net
*net
);
55 static void rt_update_hostcache(rtable
*tab
);
56 static void rt_next_hop_update(rtable
*tab
);
57 static inline void rt_prune_table(rtable
*tab
);
60 static inline struct ea_list
*
61 make_tmp_attrs(struct rte
*rt
, struct linpool
*pool
)
63 struct ea_list
*(*mta
)(struct rte
*rt
, struct linpool
*pool
);
64 mta
= rt
->attrs
->src
->proto
->make_tmp_attrs
;
65 return mta
? mta(rt
, pool
) : NULL
;
69 /* Like fib_route(), but skips empty net entries */
71 net_route_ip4(rtable
*t
, net_addr_ip4
*n
)
75 while (r
= net_find_valid(t
, (net_addr
*) n
), (!r
) && (n
->pxlen
> 0))
78 ip4_clrbit(&n
->prefix
, n
->pxlen
);
85 net_route_ip6(rtable
*t
, net_addr_ip6
*n
)
89 while (r
= net_find_valid(t
, (net_addr
*) n
), (!r
) && (n
->pxlen
> 0))
92 ip6_clrbit(&n
->prefix
, n
->pxlen
);
99 net_route(rtable
*tab
, const net_addr
*n
)
101 ASSERT(tab
->addr_type
== n
->type
);
103 net_addr
*n0
= alloca(n
->length
);
111 return net_route_ip4(tab
, (net_addr_ip4
*) n0
);
116 return net_route_ip6(tab
, (net_addr_ip6
*) n0
);
125 net_roa_check_ip4(rtable
*tab
, const net_addr_ip4
*px
, u32 asn
)
127 struct net_addr_roa4 n
= NET_ADDR_ROA4(px
->prefix
, px
->pxlen
, 0, 0);
133 for (fn
= fib_get_chain(&tab
->fib
, (net_addr
*) &n
); fn
; fn
= fn
->next
)
135 net_addr_roa4
*roa
= (void *) fn
->addr
;
136 net
*r
= fib_node_to_user(&tab
->fib
, fn
);
138 if (net_equal_prefix_roa4(roa
, &n
) && rte_is_valid(r
->routes
))
141 if (asn
&& (roa
->asn
== asn
) && (roa
->max_pxlen
>= px
->pxlen
))
150 ip4_clrbit(&n
.prefix
, n
.pxlen
);
153 return anything
? ROA_INVALID
: ROA_UNKNOWN
;
157 net_roa_check_ip6(rtable
*tab
, const net_addr_ip6
*px
, u32 asn
)
159 struct net_addr_roa6 n
= NET_ADDR_ROA6(px
->prefix
, px
->pxlen
, 0, 0);
165 for (fn
= fib_get_chain(&tab
->fib
, (net_addr
*) &n
); fn
; fn
= fn
->next
)
167 net_addr_roa6
*roa
= (void *) fn
->addr
;
168 net
*r
= fib_node_to_user(&tab
->fib
, fn
);
170 if (net_equal_prefix_roa6(roa
, &n
) && rte_is_valid(r
->routes
))
173 if (asn
&& (roa
->asn
== asn
) && (roa
->max_pxlen
>= px
->pxlen
))
182 ip6_clrbit(&n
.prefix
, n
.pxlen
);
185 return anything
? ROA_INVALID
: ROA_UNKNOWN
;
189 * roa_check - check validity of route origination in a ROA table
191 * @n: network prefix to check
192 * @asn: AS number of network prefix
194 * Implements RFC 6483 route validation for the given network prefix. The
195 * procedure is to find all candidate ROAs - ROAs whose prefixes cover the given
196 * network prefix. If there is no candidate ROA, return ROA_UNKNOWN. If there is
197 * a candidate ROA with matching ASN and maxlen field greater than or equal to
198 * the given prefix length, return ROA_VALID. Otherwise, return ROA_INVALID. If
199 * caller cannot determine origin AS, 0 could be used (in that case ROA_VALID
200 * cannot happen). Table @tab must have type NET_ROA4 or NET_ROA6, network @n
201 * must have type NET_IP4 or NET_IP6, respectively.
204 net_roa_check(rtable
*tab
, const net_addr
*n
, u32 asn
)
206 if ((tab
->addr_type
== NET_ROA4
) && (n
->type
== NET_IP4
))
207 return net_roa_check_ip4(tab
, (const net_addr_ip4
*) n
, asn
);
208 else if ((tab
->addr_type
== NET_ROA6
) && (n
->type
== NET_IP6
))
209 return net_roa_check_ip6(tab
, (const net_addr_ip6
*) n
, asn
);
211 return ROA_UNKNOWN
; /* Should not happen */
215 * rte_find - find a route
219 * The rte_find() function returns a route for destination @net
220 * which is from route source @src.
223 rte_find(net
*net
, struct rte_src
*src
)
225 rte
*e
= net
->routes
;
227 while (e
&& e
->attrs
->src
!= src
)
233 * rte_get_temp - get a temporary &rte
234 * @a: attributes to assign to the new route (a &rta; in case it's
235 * un-cached, rte_update() will create a cached copy automatically)
237 * Create a temporary &rte and bind it with the attributes @a.
238 * Also set route preference to the default preference set for
244 rte
*e
= sl_alloc(rte_slab
);
255 rte
*e
= sl_alloc(rte_slab
);
257 memcpy(e
, r
, sizeof(rte
));
258 e
->attrs
= rta_clone(r
->attrs
);
264 * rte_cow_rta - get a private writable copy of &rte with writable &rta
265 * @r: a route entry to be copied
266 * @lp: a linpool from which to allocate &rta
268 * rte_cow_rta() takes a &rte and prepares it and associated &rta for
269 * modification. There are three possibilities: First, both &rte and &rta are
270 * private copies, in that case they are returned unchanged. Second, &rte is
271 * private copy, but &rta is cached, in that case &rta is duplicated using
272 * rta_do_cow(). Third, both &rte is shared and &rta is cached, in that case
273 * both structures are duplicated by rte_do_cow() and rta_do_cow().
275 * Note that in the second case, cached &rta loses one reference, while private
276 * copy created by rta_do_cow() is a shallow copy sharing indirect data (eattrs,
277 * nexthops, ...) with it. To work properly, original shared &rta should have
278 * another reference during the life of created private copy.
280 * Result: a pointer to the new writable &rte with writable &rta.
283 rte_cow_rta(rte
*r
, linpool
*lp
)
285 if (!rta_is_cached(r
->attrs
))
289 rta
*a
= rta_do_cow(r
->attrs
, lp
);
295 static int /* Actually better or at least as good as */
296 rte_better(rte
*new, rte
*old
)
298 int (*better
)(rte
*, rte
*);
300 if (!rte_is_valid(old
))
302 if (!rte_is_valid(new))
305 if (new->pref
> old
->pref
)
307 if (new->pref
< old
->pref
)
309 if (new->attrs
->src
->proto
->proto
!= old
->attrs
->src
->proto
->proto
)
312 * If the user has configured protocol preferences, so that two different protocols
313 * have the same preference, try to break the tie by comparing addresses. Not too
314 * useful, but keeps the ordering of routes unambiguous.
316 return new->attrs
->src
->proto
->proto
> old
->attrs
->src
->proto
->proto
;
318 if (better
= new->attrs
->src
->proto
->rte_better
)
319 return better(new, old
);
324 rte_mergable(rte
*pri
, rte
*sec
)
326 int (*mergable
)(rte
*, rte
*);
328 if (!rte_is_valid(pri
) || !rte_is_valid(sec
))
331 if (pri
->pref
!= sec
->pref
)
334 if (pri
->attrs
->src
->proto
->proto
!= sec
->attrs
->src
->proto
->proto
)
337 if (mergable
= pri
->attrs
->src
->proto
->rte_mergable
)
338 return mergable(pri
, sec
);
344 rte_trace(struct proto
*p
, rte
*e
, int dir
, char *msg
)
346 log(L_TRACE
"%s %c %s %N %s", p
->name
, dir
, msg
, e
->net
->n
.addr
, rta_dest_name(e
->attrs
->dest
));
350 rte_trace_in(uint flag
, struct proto
*p
, rte
*e
, char *msg
)
353 rte_trace(p
, e
, '>', msg
);
357 rte_trace_out(uint flag
, struct proto
*p
, rte
*e
, char *msg
)
360 rte_trace(p
, e
, '<', msg
);
364 export_filter_(struct channel
*c
, rte
*rt0
, rte
**rt_free
, ea_list
**tmpa
, linpool
*pool
, int silent
)
366 struct proto
*p
= c
->proto
;
367 struct filter
*filter
= c
->out_filter
;
368 struct proto_stats
*stats
= &c
->stats
;
369 ea_list
*tmpb
= NULL
;
379 *tmpa
= make_tmp_attrs(rt
, pool
);
381 v
= p
->import_control
? p
->import_control(p
, &rt
, tmpa
, pool
) : 0;
387 stats
->exp_updates_rejected
++;
389 rte_trace_out(D_FILTERS
, p
, rt
, "rejected by protocol");
395 rte_trace_out(D_FILTERS
, p
, rt
, "forced accept by protocol");
399 v
= filter
&& ((filter
== FILTER_REJECT
) ||
400 (f_run(filter
, &rt
, tmpa
, pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
));
406 stats
->exp_updates_filtered
++;
407 rte_trace_out(D_FILTERS
, p
, rt
, "filtered out");
417 /* Discard temporary rte */
424 export_filter(struct channel
*c
, rte
*rt0
, rte
**rt_free
, ea_list
**tmpa
, int silent
)
426 return export_filter_(c
, rt0
, rt_free
, tmpa
, rte_update_pool
, silent
);
430 do_rt_notify(struct channel
*c
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
, int refeed
)
432 struct proto
*p
= c
->proto
;
433 struct proto_stats
*stats
= &c
->stats
;
437 * First, apply export limit.
439 * Export route limits has several problems. Because exp_routes
440 * counter is reset before refeed, we don't really know whether
441 * limit is breached and whether the update is new or not. Therefore
442 * the number of really exported routes may exceed the limit
443 * temporarily (routes exported before and new routes in refeed).
445 * Minor advantage is that if the limit is decreased and refeed is
446 * requested, the number of exported routes really decrease.
448 * Second problem is that with export limits, we don't know whether
449 * old was really exported (it might be blocked by limit). When a
450 * withdraw is exported, we announce it even when the previous
451 * update was blocked. This is not a big issue, but the same problem
452 * is in updating exp_routes counter. Therefore, to be consistent in
453 * increases and decreases of exp_routes, we count exported routes
454 * regardless of blocking by limits.
456 * Similar problem is in handling updates - when a new route is
457 * received and blocking is active, the route would be blocked, but
458 * when an update for the route will be received later, the update
459 * would be propagated (as old != NULL). Therefore, we have to block
460 * also non-new updates (contrary to import blocking).
463 struct channel_limit
*l
= &c
->out_limit
;
464 if (l
->action
&& new)
466 if ((!old
|| refeed
) && (stats
->exp_routes
>= l
->limit
))
467 channel_notify_limit(c
, l
, PLD_OUT
, stats
->exp_routes
);
469 if (l
->state
== PLS_BLOCKED
)
471 stats
->exp_routes
++; /* see note above */
472 stats
->exp_updates_rejected
++;
473 rte_trace_out(D_FILTERS
, p
, new, "rejected [limit]");
483 stats
->exp_updates_accepted
++;
485 stats
->exp_withdraws_accepted
++;
487 /* Hack: We do not decrease exp_routes during refeed, we instead
488 reset exp_routes at the start of refeed. */
494 if (p
->debug
& D_ROUTES
)
497 rte_trace_out(D_ROUTES
, p
, new, "replaced");
499 rte_trace_out(D_ROUTES
, p
, new, "added");
501 rte_trace_out(D_ROUTES
, p
, old
, "removed");
504 p
->rt_notify(p
, c
, net
, NULL
, old
, NULL
);
510 t
->next
= new->attrs
->eattrs
;
511 p
->rt_notify(p
, c
, net
, new, old
, tmpa
);
515 p
->rt_notify(p
, c
, net
, new, old
, new->attrs
->eattrs
);
519 rt_notify_basic(struct channel
*c
, net
*net
, rte
*new0
, rte
*old0
, int refeed
)
521 struct proto
*p
= c
->proto
;
525 rte
*new_free
= NULL
;
526 rte
*old_free
= NULL
;
527 ea_list
*tmpa
= NULL
;
530 c
->stats
.exp_updates_received
++;
532 c
->stats
.exp_withdraws_received
++;
535 * This is a tricky part - we don't know whether route 'old' was
536 * exported to protocol 'p' or was filtered by the export filter.
537 * We try to run the export filter to know this to have a correct
538 * value in 'old' argument of rte_update (and proper filter value)
540 * FIXME - this is broken because 'configure soft' may change
541 * filters but keep routes. Refeed is expected to be called after
542 * change of the filters and with old == new, therefore we do not
543 * even try to run the filter on an old route, This may lead to
544 * 'spurious withdraws' but ensure that there are no 'missing
547 * This is not completely safe as there is a window between
548 * reconfiguration and the end of refeed - if a newly filtered
549 * route disappears during this period, proper withdraw is not
550 * sent (because old would be also filtered) and the route is
551 * not refeeded (because it disappeared before that).
555 new = export_filter(c
, new, &new_free
, &tmpa
, 0);
558 old
= export_filter(c
, old
, &old_free
, NULL
, 1);
563 * As mentioned above, 'old' value may be incorrect in some race conditions.
564 * We generally ignore it with the exception of withdraw to pipe protocol.
565 * In that case we rather propagate unfiltered withdraws regardless of
566 * export filters to ensure that when a protocol is flushed, its routes are
567 * removed from all tables. Possible spurious unfiltered withdraws are not
568 * problem here as they are ignored if there is no corresponding route at
569 * the other end of the pipe. We directly call rt_notify() hook instead of
570 * do_rt_notify() to avoid logging and stat counters.
574 if ((p
->proto
== &proto_pipe
) && !new0
&& (p
!= old0
->sender
->proto
))
575 p
->rt_notify(p
, c
, net
, NULL
, old0
, NULL
);
581 do_rt_notify(c
, net
, new, old
, tmpa
, refeed
);
583 /* Discard temporary rte's */
591 rt_notify_accepted(struct channel
*c
, net
*net
, rte
*new_changed
, rte
*old_changed
, rte
*before_old
, int feed
)
593 // struct proto *p = c->proto;
596 rte
*new_best
= NULL
;
597 rte
*old_best
= NULL
;
598 rte
*new_free
= NULL
;
599 rte
*old_free
= NULL
;
600 ea_list
*tmpa
= NULL
;
602 /* Used to track whether we met old_changed position. If before_old is NULL
603 old_changed was the first and we met it implicitly before current best route. */
604 int old_meet
= old_changed
&& !before_old
;
606 /* Note that before_old is either NULL or valid (not rejected) route.
607 If old_changed is valid, before_old have to be too. If old changed route
608 was not valid, caller must use NULL for both old_changed and before_old. */
611 c
->stats
.exp_updates_received
++;
613 c
->stats
.exp_withdraws_received
++;
615 /* First, find the new_best route - first accepted by filters */
616 for (r
=net
->routes
; rte_is_valid(r
); r
=r
->next
)
618 if (new_best
= export_filter(c
, r
, &new_free
, &tmpa
, 0))
621 /* Note if we walked around the position of old_changed route */
627 * Second, handle the feed case. That means we do not care for
628 * old_best. It is NULL for feed, and the new_best for refeed.
629 * For refeed, there is a hack similar to one in rt_notify_basic()
630 * to ensure withdraws in case of changed filters
634 if (feed
== 2) /* refeed */
635 old_best
= new_best
? new_best
:
636 (rte_is_valid(net
->routes
) ? net
->routes
: NULL
);
640 if (!new_best
&& !old_best
)
647 * Now, we find the old_best route. Generally, it is the same as the
648 * new_best, unless new_best is the same as new_changed or
649 * old_changed is accepted before new_best.
651 * There are four cases:
653 * - We would find and accept old_changed before new_best, therefore
654 * old_changed is old_best. In remaining cases we suppose this
657 * - We found no new_best, therefore there is also no old_best and
658 * we ignore this withdraw.
660 * - We found new_best different than new_changed, therefore
661 * old_best is the same as new_best and we ignore this update.
663 * - We found new_best the same as new_changed, therefore it cannot
664 * be old_best and we have to continue search for old_best.
669 if (old_best
= export_filter(c
, old_changed
, &old_free
, NULL
, 1))
676 /* Third case, we use r instead of new_best, because export_filter() could change it */
677 if (r
!= new_changed
)
685 for (r
=r
->next
; rte_is_valid(r
); r
=r
->next
)
687 if (old_best
= export_filter(c
, r
, &old_free
, NULL
, 1))
691 if (old_best
= export_filter(c
, old_changed
, &old_free
, NULL
, 1))
695 /* Implicitly, old_best is NULL and new_best is non-NULL */
698 do_rt_notify(c
, net
, new_best
, old_best
, tmpa
, (feed
== 2));
700 /* Discard temporary rte's */
708 static struct nexthop
*
709 nexthop_merge_rta(struct nexthop
*nhs
, rta
*a
, linpool
*pool
, int max
)
711 return nexthop_merge(nhs
, &(a
->nh
), 1, 0, max
, pool
);
715 rt_export_merged(struct channel
*c
, net
*net
, rte
**rt_free
, ea_list
**tmpa
, linpool
*pool
, int silent
)
717 // struct proto *p = c->proto;
718 struct nexthop
*nhs
= NULL
;
719 rte
*best0
, *best
, *rt0
, *rt
, *tmp
;
724 if (!rte_is_valid(best0
))
727 best
= export_filter_(c
, best0
, rt_free
, tmpa
, pool
, silent
);
729 if (!best
|| !rte_is_reachable(best
))
732 for (rt0
= best0
->next
; rt0
; rt0
= rt0
->next
)
734 if (!rte_mergable(best0
, rt0
))
737 rt
= export_filter_(c
, rt0
, &tmp
, NULL
, pool
, 1);
742 if (rte_is_reachable(rt
))
743 nhs
= nexthop_merge_rta(nhs
, rt
->attrs
, pool
, c
->merge_limit
);
751 nhs
= nexthop_merge_rta(nhs
, best
->attrs
, pool
, c
->merge_limit
);
755 best
= rte_cow_rta(best
, pool
);
756 nexthop_link(best
->attrs
, nhs
);
768 rt_notify_merged(struct channel
*c
, net
*net
, rte
*new_changed
, rte
*old_changed
,
769 rte
*new_best
, rte
*old_best
, int refeed
)
771 // struct proto *p = c->proto;
773 rte
*new_best_free
= NULL
;
774 rte
*old_best_free
= NULL
;
775 rte
*new_changed_free
= NULL
;
776 rte
*old_changed_free
= NULL
;
777 ea_list
*tmpa
= NULL
;
779 /* We assume that all rte arguments are either NULL or rte_is_valid() */
781 /* This check should be done by the caller */
782 if (!new_best
&& !old_best
)
785 /* Check whether the change is relevant to the merged route */
786 if ((new_best
== old_best
) && !refeed
)
788 new_changed
= rte_mergable(new_best
, new_changed
) ?
789 export_filter(c
, new_changed
, &new_changed_free
, NULL
, 1) : NULL
;
791 old_changed
= rte_mergable(old_best
, old_changed
) ?
792 export_filter(c
, old_changed
, &old_changed_free
, NULL
, 1) : NULL
;
794 if (!new_changed
&& !old_changed
)
799 c
->stats
.exp_updates_received
++;
801 c
->stats
.exp_withdraws_received
++;
803 /* Prepare new merged route */
805 new_best
= rt_export_merged(c
, net
, &new_best_free
, &tmpa
, rte_update_pool
, 0);
807 /* Prepare old merged route (without proper merged next hops) */
808 /* There are some issues with running filter on old route - see rt_notify_basic() */
809 if (old_best
&& !refeed
)
810 old_best
= export_filter(c
, old_best
, &old_best_free
, NULL
, 1);
812 if (new_best
|| old_best
)
813 do_rt_notify(c
, net
, new_best
, old_best
, tmpa
, refeed
);
815 /* Discard temporary rte's */
817 rte_free(new_best_free
);
819 rte_free(old_best_free
);
820 if (new_changed_free
)
821 rte_free(new_changed_free
);
822 if (old_changed_free
)
823 rte_free(old_changed_free
);
828 * rte_announce - announce a routing table change
829 * @tab: table the route has been added to
830 * @type: type of route announcement (RA_OPTIMAL or RA_ANY)
831 * @net: network in question
832 * @new: the new route to be announced
833 * @old: the previous route for the same network
834 * @new_best: the new best route for the same network
835 * @old_best: the previous best route for the same network
836 * @before_old: The previous route before @old for the same network.
837 * If @before_old is NULL @old was the first.
839 * This function gets a routing table update and announces it
840 * to all protocols that acccepts given type of route announcement
841 * and are connected to the same table by their announcement hooks.
843 * Route announcement of type %RA_OPTIMAL si generated when optimal
844 * route (in routing table @tab) changes. In that case @old stores the
847 * Route announcement of type %RA_ANY si generated when any route (in
848 * routing table @tab) changes In that case @old stores the old route
849 * from the same protocol.
851 * For each appropriate protocol, we first call its import_control()
852 * hook which performs basic checks on the route (each protocol has a
853 * right to veto or force accept of the route before any filter is
854 * asked) and adds default values of attributes specific to the new
855 * protocol (metrics, tags etc.). Then it consults the protocol's
856 * export filter and if it accepts the route, the rt_notify() hook of
857 * the protocol gets called.
860 rte_announce(rtable
*tab
, unsigned type
, net
*net
, rte
*new, rte
*old
,
861 rte
*new_best
, rte
*old_best
, rte
*before_old
)
863 if (!rte_is_valid(new))
866 if (!rte_is_valid(old
))
867 old
= before_old
= NULL
;
869 if (!rte_is_valid(new_best
))
872 if (!rte_is_valid(old_best
))
878 if ((type
== RA_OPTIMAL
) && tab
->hostcache
)
879 rt_notify_hostcache(tab
, net
);
881 struct channel
*c
; node
*n
;
882 WALK_LIST2(c
, n
, tab
->channels
, table_node
)
884 if (c
->export_state
== ES_DOWN
)
887 if (c
->ra_mode
== type
)
888 if (type
== RA_ACCEPTED
)
889 rt_notify_accepted(c
, net
, new, old
, before_old
, 0);
890 else if (type
== RA_MERGED
)
891 rt_notify_merged(c
, net
, new, old
, new_best
, old_best
, 0);
893 rt_notify_basic(c
, net
, new, old
, 0);
903 if (!net_validate(n
->n
.addr
))
905 log(L_WARN
"Ignoring bogus prefix %N received via %s",
906 n
->n
.addr
, e
->sender
->proto
->name
);
910 c
= net_classify(n
->n
.addr
);
911 if ((c
< 0) || !(c
& IADDR_HOST
) || ((c
& IADDR_SCOPE_MASK
) <= SCOPE_LINK
))
913 log(L_WARN
"Ignoring bogus route %N received via %s",
914 n
->n
.addr
, e
->sender
->proto
->name
);
918 if (net_type_match(n
->n
.addr
, NB_DEST
) == !e
->attrs
->dest
)
920 log(L_WARN
"Ignoring route %N with invalid dest %d received via %s",
921 n
->n
.addr
, e
->attrs
->dest
, e
->sender
->proto
->name
);
925 if ((e
->attrs
->dest
== RTD_UNICAST
) && !nexthop_is_sorted(&(e
->attrs
->nh
)))
927 log(L_WARN
"Ignoring unsorted multipath route %N received via %s",
928 n
->n
.addr
, e
->sender
->proto
->name
);
936 * rte_free - delete a &rte
937 * @e: &rte to be deleted
939 * rte_free() deletes the given &rte from the routing table it's linked to.
944 if (rta_is_cached(e
->attrs
))
946 sl_free(rte_slab
, e
);
950 rte_free_quick(rte
*e
)
953 sl_free(rte_slab
, e
);
957 rte_same(rte
*x
, rte
*y
)
960 x
->attrs
== y
->attrs
&&
961 x
->flags
== y
->flags
&&
962 x
->pflags
== y
->pflags
&&
963 x
->pref
== y
->pref
&&
964 (!x
->attrs
->src
->proto
->rte_same
|| x
->attrs
->src
->proto
->rte_same(x
, y
));
967 static inline int rte_is_ok(rte
*e
) { return e
&& !rte_is_filtered(e
); }
970 rte_recalculate(struct channel
*c
, net
*net
, rte
*new, struct rte_src
*src
)
972 struct proto
*p
= c
->proto
;
973 struct rtable
*table
= c
->table
;
974 struct proto_stats
*stats
= &c
->stats
;
975 static struct tbf rl_pipe
= TBF_DEFAULT_LOG_LIMITS
;
976 rte
*before_old
= NULL
;
977 rte
*old_best
= net
->routes
;
981 k
= &net
->routes
; /* Find and remove original route from the same protocol */
984 if (old
->attrs
->src
== src
)
986 /* If there is the same route in the routing table but from
987 * a different sender, then there are two paths from the
988 * source protocol to this routing table through transparent
989 * pipes, which is not allowed.
991 * We log that and ignore the route. If it is withdraw, we
992 * ignore it completely (there might be 'spurious withdraws',
993 * see FIXME in do_rte_announce())
995 if (old
->sender
->proto
!= p
)
999 log_rl(&rl_pipe
, L_ERR
"Pipe collision detected when sending %N to table %s",
1000 net
->n
.addr
, table
->name
);
1001 rte_free_quick(new);
1006 if (new && rte_same(old
, new))
1008 /* No changes, ignore the new route */
1010 if (!rte_is_filtered(new))
1012 stats
->imp_updates_ignored
++;
1013 rte_trace_in(D_ROUTES
, p
, new, "ignored");
1016 rte_free_quick(new);
1031 stats
->imp_withdraws_ignored
++;
1035 int new_ok
= rte_is_ok(new);
1036 int old_ok
= rte_is_ok(old
);
1038 struct channel_limit
*l
= &c
->rx_limit
;
1039 if (l
->action
&& !old
&& new)
1041 u32 all_routes
= stats
->imp_routes
+ stats
->filt_routes
;
1043 if (all_routes
>= l
->limit
)
1044 channel_notify_limit(c
, l
, PLD_RX
, all_routes
);
1046 if (l
->state
== PLS_BLOCKED
)
1048 /* In receive limit the situation is simple, old is NULL so
1049 we just free new and exit like nothing happened */
1051 stats
->imp_updates_ignored
++;
1052 rte_trace_in(D_FILTERS
, p
, new, "ignored [limit]");
1053 rte_free_quick(new);
1059 if (l
->action
&& !old_ok
&& new_ok
)
1061 if (stats
->imp_routes
>= l
->limit
)
1062 channel_notify_limit(c
, l
, PLD_IN
, stats
->imp_routes
);
1064 if (l
->state
== PLS_BLOCKED
)
1066 /* In import limit the situation is more complicated. We
1067 shouldn't just drop the route, we should handle it like
1068 it was filtered. We also have to continue the route
1069 processing if old or new is non-NULL, but we should exit
1070 if both are NULL as this case is probably assumed to be
1073 stats
->imp_updates_ignored
++;
1074 rte_trace_in(D_FILTERS
, p
, new, "ignored [limit]");
1076 if (c
->in_keep_filtered
)
1077 new->flags
|= REF_FILTERED
;
1079 { rte_free_quick(new); new = NULL
; }
1081 /* Note that old && !new could be possible when
1082 c->in_keep_filtered changed in the recent past. */
1093 stats
->imp_updates_accepted
++;
1095 stats
->imp_withdraws_accepted
++;
1097 stats
->imp_withdraws_ignored
++;
1102 rte_is_filtered(new) ? stats
->filt_routes
++ : stats
->imp_routes
++;
1104 rte_is_filtered(old
) ? stats
->filt_routes
-- : stats
->imp_routes
--;
1106 if (table
->config
->sorted
)
1108 /* If routes are sorted, just insert new route to appropriate position */
1111 if (before_old
&& !rte_better(new, before_old
))
1112 k
= &before_old
->next
;
1116 for (; *k
; k
=&(*k
)->next
)
1117 if (rte_better(new, *k
))
1126 /* If routes are not sorted, find the best route and move it on
1127 the first position. There are several optimized cases. */
1129 if (src
->proto
->rte_recalculate
&& src
->proto
->rte_recalculate(table
, net
, new, old
, old_best
))
1130 goto do_recalculate
;
1132 if (new && rte_better(new, old_best
))
1134 /* The first case - the new route is cleary optimal,
1135 we link it at the first position */
1137 new->next
= net
->routes
;
1140 else if (old
== old_best
)
1142 /* The second case - the old best route disappeared, we add the
1143 new route (if we have any) to the list (we don't care about
1144 position) and then we elect the new optimal route and relink
1145 that route at the first position and announce it. New optimal
1146 route might be NULL if there is no more routes */
1149 /* Add the new route to the list */
1152 new->next
= net
->routes
;
1156 /* Find a new optimal route (if there is any) */
1159 rte
**bp
= &net
->routes
;
1160 for (k
=&(*bp
)->next
; *k
; k
=&(*k
)->next
)
1161 if (rte_better(*k
, *bp
))
1167 best
->next
= net
->routes
;
1173 /* The third case - the new route is not better than the old
1174 best route (therefore old_best != NULL) and the old best
1175 route was not removed (therefore old_best == net->routes).
1176 We just link the new route after the old best route. */
1178 ASSERT(net
->routes
!= NULL
);
1179 new->next
= net
->routes
->next
;
1180 net
->routes
->next
= new;
1182 /* The fourth (empty) case - suboptimal route was removed, nothing to do */
1188 /* Log the route change */
1189 if (p
->debug
& D_ROUTES
)
1192 rte_trace(p
, new, '>', new == net
->routes
? "added [best]" : "added");
1195 if (old
!= old_best
)
1196 rte_trace(p
, old
, '>', "removed");
1197 else if (rte_is_ok(net
->routes
))
1198 rte_trace(p
, old
, '>', "removed [replaced]");
1200 rte_trace(p
, old
, '>', "removed [sole]");
1204 /* Propagate the route change */
1205 rte_announce(table
, RA_ANY
, net
, new, old
, NULL
, NULL
, NULL
);
1206 if (net
->routes
!= old_best
)
1207 rte_announce(table
, RA_OPTIMAL
, net
, net
->routes
, old_best
, NULL
, NULL
, NULL
);
1208 if (table
->config
->sorted
)
1209 rte_announce(table
, RA_ACCEPTED
, net
, new, old
, NULL
, NULL
, before_old
);
1210 rte_announce(table
, RA_MERGED
, net
, new, old
, net
->routes
, old_best
, NULL
);
1213 (table
->gc_counter
++ >= table
->config
->gc_max_ops
) &&
1214 (table
->gc_time
+ table
->config
->gc_min_time
<= now
))
1215 rt_schedule_prune(table
);
1217 if (old_ok
&& p
->rte_remove
)
1218 p
->rte_remove(net
, old
);
1219 if (new_ok
&& p
->rte_insert
)
1220 p
->rte_insert(net
, new);
1223 rte_free_quick(old
);
1226 static int rte_update_nest_cnt
; /* Nesting counter to allow recursive updates */
1229 rte_update_lock(void)
1231 rte_update_nest_cnt
++;
1235 rte_update_unlock(void)
1237 if (!--rte_update_nest_cnt
)
1238 lp_flush(rte_update_pool
);
1242 rte_hide_dummy_routes(net
*net
, rte
**dummy
)
1244 if (net
->routes
&& net
->routes
->attrs
->source
== RTS_DUMMY
)
1246 *dummy
= net
->routes
;
1247 net
->routes
= (*dummy
)->next
;
1252 rte_unhide_dummy_routes(net
*net
, rte
**dummy
)
1256 (*dummy
)->next
= net
->routes
;
1257 net
->routes
= *dummy
;
1262 * rte_update - enter a new update to a routing table
1263 * @table: table to be updated
1264 * @c: channel doing the update
1265 * @net: network node
1266 * @p: protocol submitting the update
1267 * @src: protocol originating the update
1268 * @new: a &rte representing the new route or %NULL for route removal.
1270 * This function is called by the routing protocols whenever they discover
1271 * a new route or wish to update/remove an existing route. The right announcement
1272 * sequence is to build route attributes first (either un-cached with @aflags set
1273 * to zero or a cached one using rta_lookup(); in this case please note that
1274 * you need to increase the use count of the attributes yourself by calling
1275 * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
1276 * the appropriate data and finally submit the new &rte by calling rte_update().
1278 * @src specifies the protocol that originally created the route and the meaning
1279 * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
1280 * same value as @new->attrs->proto. @p specifies the protocol that called
1281 * rte_update(). In most cases it is the same protocol as @src. rte_update()
1282 * stores @p in @new->sender;
1284 * When rte_update() gets any route, it automatically validates it (checks,
1285 * whether the network and next hop address are valid IP addresses and also
1286 * whether a normal routing protocol doesn't try to smuggle a host or link
1287 * scope route to the table), converts all protocol dependent attributes stored
1288 * in the &rte to temporary extended attributes, consults import filters of the
1289 * protocol to see if the route should be accepted and/or its attributes modified,
1290 * stores the temporary attributes back to the &rte.
1292 * Now, having a "public" version of the route, we
1293 * automatically find any old route defined by the protocol @src
1294 * for network @n, replace it by the new one (or removing it if @new is %NULL),
1295 * recalculate the optimal route for this destination and finally broadcast
1296 * the change (if any) to all routing protocols by calling rte_announce().
1298 * All memory used for attribute lists and other temporary allocations is taken
1299 * from a special linear pool @rte_update_pool and freed when rte_update()
1304 rte_update2(struct channel
*c
, const net_addr
*n
, rte
*new, struct rte_src
*src
)
1306 struct proto
*p
= c
->proto
;
1307 struct proto_stats
*stats
= &c
->stats
;
1308 struct filter
*filter
= c
->in_filter
;
1309 ea_list
*tmpa
= NULL
;
1313 ASSERT(c
->channel_state
== CS_UP
);
1318 nn
= net_get(c
->table
, n
);
1324 new->pref
= c
->preference
;
1326 stats
->imp_updates_received
++;
1327 if (!rte_validate(new))
1329 rte_trace_in(D_FILTERS
, p
, new, "invalid");
1330 stats
->imp_updates_invalid
++;
1334 if (filter
== FILTER_REJECT
)
1336 stats
->imp_updates_filtered
++;
1337 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
1339 if (! c
->in_keep_filtered
)
1342 /* new is a private copy, i could modify it */
1343 new->flags
|= REF_FILTERED
;
1347 tmpa
= make_tmp_attrs(new, rte_update_pool
);
1348 if (filter
&& (filter
!= FILTER_REJECT
))
1350 ea_list
*old_tmpa
= tmpa
;
1351 int fr
= f_run(filter
, &new, &tmpa
, rte_update_pool
, 0);
1354 stats
->imp_updates_filtered
++;
1355 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
1357 if (! c
->in_keep_filtered
)
1360 new->flags
|= REF_FILTERED
;
1362 if (tmpa
!= old_tmpa
&& src
->proto
->store_tmp_attrs
)
1363 src
->proto
->store_tmp_attrs(new, tmpa
);
1366 if (!rta_is_cached(new->attrs
)) /* Need to copy attributes */
1367 new->attrs
= rta_lookup(new->attrs
);
1368 new->flags
|= REF_COW
;
1372 stats
->imp_withdraws_received
++;
1374 if (!(nn
= net_find(c
->table
, n
)) || !src
)
1376 stats
->imp_withdraws_ignored
++;
1377 rte_update_unlock();
1383 rte_hide_dummy_routes(nn
, &dummy
);
1384 rte_recalculate(c
, nn
, new, src
);
1385 rte_unhide_dummy_routes(nn
, &dummy
);
1386 rte_update_unlock();
1395 /* Independent call to rte_announce(), used from next hop
1396 recalculation, outside of rte_update(). new must be non-NULL */
1398 rte_announce_i(rtable
*tab
, unsigned type
, net
*net
, rte
*new, rte
*old
,
1399 rte
*new_best
, rte
*old_best
)
1402 rte_announce(tab
, type
, net
, new, old
, new_best
, old_best
, NULL
);
1403 rte_update_unlock();
1407 rte_discard(rte
*old
) /* Non-filtered route deletion, used during garbage collection */
1410 rte_recalculate(old
->sender
, old
->net
, NULL
, old
->attrs
->src
);
1411 rte_update_unlock();
1414 /* Check rtable for best route to given net whether it would be exported do p */
1416 rt_examine(rtable
*t
, net_addr
*a
, struct proto
*p
, struct filter
*filter
)
1418 net
*n
= net_find(t
, a
);
1419 rte
*rt
= n
? n
->routes
: NULL
;
1421 if (!rte_is_valid(rt
))
1426 /* Rest is stripped down export_filter() */
1427 ea_list
*tmpa
= make_tmp_attrs(rt
, rte_update_pool
);
1428 int v
= p
->import_control
? p
->import_control(p
, &rt
, &tmpa
, rte_update_pool
) : 0;
1429 if (v
== RIC_PROCESS
)
1430 v
= (f_run(filter
, &rt
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) <= F_ACCEPT
);
1432 /* Discard temporary rte */
1433 if (rt
!= n
->routes
)
1436 rte_update_unlock();
1443 * rt_refresh_begin - start a refresh cycle
1444 * @t: related routing table
1445 * @c related channel
1447 * This function starts a refresh cycle for given routing table and announce
1448 * hook. The refresh cycle is a sequence where the protocol sends all its valid
1449 * routes to the routing table (by rte_update()). After that, all protocol
1450 * routes (more precisely routes with @c as @sender) not sent during the
1451 * refresh cycle but still in the table from the past are pruned. This is
1452 * implemented by marking all related routes as stale by REF_STALE flag in
1453 * rt_refresh_begin(), then marking all related stale routes with REF_DISCARD
1454 * flag in rt_refresh_end() and then removing such routes in the prune loop.
1457 rt_refresh_begin(rtable
*t
, struct channel
*c
)
1459 FIB_WALK(&t
->fib
, net
, n
)
1462 for (e
= n
->routes
; e
; e
= e
->next
)
1464 e
->flags
|= REF_STALE
;
1470 * rt_refresh_end - end a refresh cycle
1471 * @t: related routing table
1472 * @c: related channel
1474 * This function ends a refresh cycle for given routing table and announce
1475 * hook. See rt_refresh_begin() for description of refresh cycles.
1478 rt_refresh_end(rtable
*t
, struct channel
*c
)
1482 FIB_WALK(&t
->fib
, net
, n
)
1485 for (e
= n
->routes
; e
; e
= e
->next
)
1486 if ((e
->sender
== c
) && (e
->flags
& REF_STALE
))
1488 e
->flags
|= REF_DISCARD
;
1495 rt_schedule_prune(t
);
1500 * rte_dump - dump a route
1501 * @e: &rte to be dumped
1503 * This functions dumps contents of a &rte to debug output.
1509 debug("%-1N ", n
->n
.addr
);
1510 debug("KF=%02x PF=%02x pref=%d lm=%d ", n
->n
.flags
, e
->pflags
, e
->pref
, now
-e
->lastmod
);
1512 if (e
->attrs
->src
->proto
->proto
->dump_attrs
)
1513 e
->attrs
->src
->proto
->proto
->dump_attrs(e
);
1518 * rt_dump - dump a routing table
1519 * @t: routing table to be dumped
1521 * This function dumps contents of a given routing table to debug output.
1526 debug("Dump of routing table <%s>\n", t
->name
);
1530 FIB_WALK(&t
->fib
, net
, n
)
1533 for(e
=n
->routes
; e
; e
=e
->next
)
1541 * rt_dump_all - dump all routing tables
1543 * This function dumps contents of all routing tables to debug output.
1550 WALK_LIST(t
, routing_tables
)
1555 rt_schedule_hcu(rtable
*tab
)
1557 if (tab
->hcu_scheduled
)
1560 tab
->hcu_scheduled
= 1;
1561 ev_schedule(tab
->rt_event
);
1565 rt_schedule_nhu(rtable
*tab
)
1567 if (tab
->nhu_state
== NHU_CLEAN
)
1568 ev_schedule(tab
->rt_event
);
1571 * NHU_CLEAN -> NHU_SCHEDULED
1572 * NHU_RUNNING -> NHU_DIRTY
1574 tab
->nhu_state
|= NHU_SCHEDULED
;
1578 rt_schedule_prune(rtable
*tab
)
1580 if (tab
->prune_state
== 0)
1581 ev_schedule(tab
->rt_event
);
1583 /* state change 0->1, 2->3 */
1584 tab
->prune_state
|= 1;
1595 if (tab
->hcu_scheduled
)
1596 rt_update_hostcache(tab
);
1599 rt_next_hop_update(tab
);
1601 if (tab
->prune_state
)
1602 rt_prune_table(tab
);
1604 rt_unlock_table(tab
);
1608 rt_setup(pool
*p
, rtable
*t
, char *name
, struct rtable_config
*cf
)
1610 bzero(t
, sizeof(*t
));
1613 t
->addr_type
= cf
? cf
->addr_type
: NET_IP4
;
1614 fib_init(&t
->fib
, p
, t
->addr_type
, sizeof(net
), OFFSETOF(net
, n
), 0, NULL
);
1615 init_list(&t
->channels
);
1619 t
->rt_event
= ev_new(p
);
1620 t
->rt_event
->hook
= rt_event
;
1621 t
->rt_event
->data
= t
;
1627 * rt_init - initialize routing tables
1629 * This function is called during BIRD startup. It initializes the
1630 * routing table module.
1636 rt_table_pool
= rp_new(&root_pool
, "Routing tables");
1637 rte_update_pool
= lp_new(rt_table_pool
, 4080);
1638 rte_slab
= sl_new(rt_table_pool
, sizeof(rte
));
1639 init_list(&routing_tables
);
1644 * rt_prune_table - prune a routing table
1646 * The prune loop scans routing tables and removes routes belonging to flushing
1647 * protocols, discarded routes and also stale network entries. It is called from
1648 * rt_event(). The event is rescheduled if the current iteration do not finish
1649 * the table. The pruning is directed by the prune state (@prune_state),
1650 * specifying whether the prune cycle is scheduled or running, and there
1651 * is also a persistent pruning iterator (@prune_fit).
1653 * The prune loop is used also for channel flushing. For this purpose, the
1654 * channels to flush are marked before the iteration and notified after the
1658 rt_prune_table(rtable
*tab
)
1660 struct fib_iterator
*fit
= &tab
->prune_fit
;
1666 DBG("Pruning route table %s\n", tab
->name
);
1668 fib_check(&tab
->fib
);
1671 if (tab
->prune_state
== 0)
1674 if (tab
->prune_state
== 1)
1676 /* Mark channels to flush */
1677 WALK_LIST2(c
, n
, tab
->channels
, table_node
)
1678 if (c
->channel_state
== CS_FLUSHING
)
1679 c
->flush_active
= 1;
1681 FIB_ITERATE_INIT(fit
, &tab
->fib
);
1682 tab
->prune_state
= 2;
1686 FIB_ITERATE_START(&tab
->fib
, fit
, net
, n
)
1691 for (e
=n
->routes
; e
; e
=e
->next
)
1692 if (e
->sender
->flush_active
|| (e
->flags
& REF_DISCARD
))
1696 FIB_ITERATE_PUT(fit
);
1697 ev_schedule(tab
->rt_event
);
1707 if (!n
->routes
) /* Orphaned FIB entry */
1709 FIB_ITERATE_PUT(fit
);
1710 fib_delete(&tab
->fib
, n
);
1717 fib_check(&tab
->fib
);
1720 tab
->gc_counter
= 0;
1723 /* state change 2->0, 3->1 */
1724 tab
->prune_state
&= 1;
1726 if (tab
->prune_state
> 0)
1727 ev_schedule(tab
->rt_event
);
1729 /* FIXME: This should be handled in a better way */
1732 /* Close flushed channels */
1733 WALK_LIST2_DELSAFE(c
, n
, x
, tab
->channels
, table_node
)
1734 if (c
->flush_active
)
1736 c
->flush_active
= 0;
1737 channel_set_state(c
, CS_DOWN
);
1744 rt_preconfig(struct config
*c
)
1746 init_list(&c
->tables
);
1748 rt_new_table(cf_get_symbol("master4"), NET_IP4
);
1749 rt_new_table(cf_get_symbol("master6"), NET_IP6
);
1754 * Some functions for handing internal next hop updates
1755 * triggered by rt_schedule_nhu().
1759 rta_next_hop_outdated(rta
*a
)
1761 struct hostentry
*he
= a
->hostentry
;
1767 return a
->dest
!= RTD_UNREACHABLE
;
1769 return (a
->dest
!= he
->dest
) || (a
->igp_metric
!= he
->igp_metric
) ||
1770 (!he
->nexthop_linkable
) || !nexthop_same(&(a
->nh
), &(he
->src
->nh
));
1774 rta_apply_hostentry(rta
*a
, struct hostentry
*he
, mpls_label_stack
*mls
)
1778 a
->igp_metric
= he
->igp_metric
;
1780 if (a
->dest
!= RTD_UNICAST
)
1784 a
->nh
= (struct nexthop
) {};
1786 { /* Store the label stack for later changes */
1787 a
->nh
.labels_orig
= a
->nh
.labels
= mls
->len
;
1788 memcpy(a
->nh
.label
, mls
->stack
, mls
->len
* sizeof(u32
));
1793 if (((!mls
) || (!mls
->len
)) && he
->nexthop_linkable
)
1794 { /* Just link the nexthop chain, no label append happens. */
1795 memcpy(&(a
->nh
), &(he
->src
->nh
), nexthop_size(&(he
->src
->nh
)));
1799 struct nexthop
*nhp
= NULL
, *nhr
= NULL
;
1800 int skip_nexthop
= 0;
1802 for (struct nexthop
*nh
= &(he
->src
->nh
); nh
; nh
= nh
->next
)
1809 nhp
= (nhp
? (nhp
->next
= lp_allocz(rte_update_pool
, NEXTHOP_MAX_SIZE
)) : &(a
->nh
));
1812 nhp
->iface
= nh
->iface
;
1813 nhp
->weight
= nh
->weight
;
1816 nhp
->labels
= nh
->labels
+ mls
->len
;
1817 nhp
->labels_orig
= mls
->len
;
1818 if (nhp
->labels
<= MPLS_MAX_LABEL_STACK
)
1820 memcpy(nhp
->label
, nh
->label
, nh
->labels
* sizeof(u32
)); /* First the hostentry labels */
1821 memcpy(&(nhp
->label
[nh
->labels
]), mls
->stack
, mls
->len
* sizeof(u32
)); /* Then the bottom labels */
1825 log(L_WARN
"Sum of label stack sizes %d + %d = %d exceedes allowed maximum (%d)",
1826 nh
->labels
, mls
->len
, nhp
->labels
, MPLS_MAX_LABEL_STACK
);
1831 if (ipa_nonzero(nh
->gw
))
1832 nhp
->gw
= nh
->gw
; /* Router nexthop */
1833 else if (ipa_nonzero(he
->link
))
1834 nhp
->gw
= he
->link
; /* Device nexthop with link-local address known */
1836 nhp
->gw
= he
->addr
; /* Device nexthop with link-local address unknown */
1844 a
->dest
= RTD_UNREACHABLE
;
1845 log(L_WARN
"No valid nexthop remaining, setting route unreachable");
1851 rt_next_hop_update_rte(rtable
*tab UNUSED
, rte
*old
)
1853 rta
*a
= alloca(RTA_MAX_SIZE
);
1854 memcpy(a
, old
->attrs
, rta_size(old
->attrs
));
1856 mpls_label_stack mls
= { .len
= a
->nh
.labels_orig
};
1857 memcpy(mls
.stack
, &a
->nh
.label
[a
->nh
.labels
- mls
.len
], mls
.len
* sizeof(u32
));
1859 rta_apply_hostentry(a
, old
->attrs
->hostentry
, &mls
);
1862 rte
*e
= sl_alloc(rte_slab
);
1863 memcpy(e
, old
, sizeof(rte
));
1864 e
->attrs
= rta_lookup(a
);
1870 rt_next_hop_update_net(rtable
*tab
, net
*n
)
1872 rte
**k
, *e
, *new, *old_best
, **new_best
;
1874 int free_old_best
= 0;
1876 old_best
= n
->routes
;
1880 for (k
= &n
->routes
; e
= *k
; k
= &e
->next
)
1881 if (rta_next_hop_outdated(e
->attrs
))
1883 new = rt_next_hop_update_rte(tab
, e
);
1886 rte_announce_i(tab
, RA_ANY
, n
, new, e
, NULL
, NULL
);
1887 rte_trace_in(D_ROUTES
, new->sender
->proto
, new, "updated");
1889 /* Call a pre-comparison hook */
1890 /* Not really an efficient way to compute this */
1891 if (e
->attrs
->src
->proto
->rte_recalculate
)
1892 e
->attrs
->src
->proto
->rte_recalculate(tab
, n
, new, e
, NULL
);
1896 else /* Freeing of the old best rte is postponed */
1906 /* Find the new best route */
1908 for (k
= &n
->routes
; e
= *k
; k
= &e
->next
)
1910 if (!new_best
|| rte_better(e
, *new_best
))
1914 /* Relink the new best route to the first position */
1916 if (new != n
->routes
)
1918 *new_best
= new->next
;
1919 new->next
= n
->routes
;
1923 /* Announce the new best route */
1924 if (new != old_best
)
1926 rte_announce_i(tab
, RA_OPTIMAL
, n
, new, old_best
, NULL
, NULL
);
1927 rte_trace_in(D_ROUTES
, new->sender
->proto
, new, "updated [best]");
1930 /* FIXME: Better announcement of merged routes */
1931 rte_announce_i(tab
, RA_MERGED
, n
, new, old_best
, new, old_best
);
1934 rte_free_quick(old_best
);
1940 rt_next_hop_update(rtable
*tab
)
1942 struct fib_iterator
*fit
= &tab
->nhu_fit
;
1945 if (tab
->nhu_state
== NHU_CLEAN
)
1948 if (tab
->nhu_state
== NHU_SCHEDULED
)
1950 FIB_ITERATE_INIT(fit
, &tab
->fib
);
1951 tab
->nhu_state
= NHU_RUNNING
;
1954 FIB_ITERATE_START(&tab
->fib
, fit
, net
, n
)
1958 FIB_ITERATE_PUT(fit
);
1959 ev_schedule(tab
->rt_event
);
1962 max_feed
-= rt_next_hop_update_net(tab
, n
);
1967 * NHU_DIRTY -> NHU_SCHEDULED
1968 * NHU_RUNNING -> NHU_CLEAN
1970 tab
->nhu_state
&= 1;
1972 if (tab
->nhu_state
!= NHU_CLEAN
)
1973 ev_schedule(tab
->rt_event
);
1977 struct rtable_config
*
1978 rt_new_table(struct symbol
*s
, uint addr_type
)
1980 /* Hack that allows to 'redefine' the master table */
1981 if ((s
->class == SYM_TABLE
) &&
1982 (s
->def
== new_config
->def_tables
[addr_type
]) &&
1983 ((addr_type
== NET_IP4
) || (addr_type
== NET_IP6
)))
1986 struct rtable_config
*c
= cfg_allocz(sizeof(struct rtable_config
));
1988 cf_define_symbol(s
, SYM_TABLE
, c
);
1990 c
->addr_type
= addr_type
;
1991 c
->gc_max_ops
= 1000;
1994 add_tail(&new_config
->tables
, &c
->n
);
1996 /* First table of each type is kept as default */
1997 if (! new_config
->def_tables
[addr_type
])
1998 new_config
->def_tables
[addr_type
] = c
;
2004 * rt_lock_table - lock a routing table
2005 * @r: routing table to be locked
2007 * Lock a routing table, because it's in use by a protocol,
2008 * preventing it from being freed when it gets undefined in a new
2012 rt_lock_table(rtable
*r
)
2018 * rt_unlock_table - unlock a routing table
2019 * @r: routing table to be unlocked
2021 * Unlock a routing table formerly locked by rt_lock_table(),
2022 * that is decrease its use count and delete it if it's scheduled
2023 * for deletion by configuration changes.
2026 rt_unlock_table(rtable
*r
)
2028 if (!--r
->use_count
&& r
->deleted
)
2030 struct config
*conf
= r
->deleted
;
2031 DBG("Deleting routing table %s\n", r
->name
);
2032 r
->config
->table
= NULL
;
2034 rt_free_hostcache(r
);
2039 config_del_obstacle(conf
);
2044 * rt_commit - commit new routing table configuration
2045 * @new: new configuration
2046 * @old: original configuration or %NULL if it's boot time config
2048 * Scan differences between @old and @new configuration and modify
2049 * the routing tables according to these changes. If @new defines a
2050 * previously unknown table, create it, if it omits a table existing
2051 * in @old, schedule it for deletion (it gets deleted when all protocols
2052 * disconnect from it by calling rt_unlock_table()), if it exists
2053 * in both configurations, leave it unchanged.
2056 rt_commit(struct config
*new, struct config
*old
)
2058 struct rtable_config
*o
, *r
;
2060 DBG("rt_commit:\n");
2063 WALK_LIST(o
, old
->tables
)
2065 rtable
*ot
= o
->table
;
2068 struct symbol
*sym
= cf_find_symbol(new, o
->name
);
2069 if (sym
&& sym
->class == SYM_TABLE
&& !new->shutdown
)
2071 DBG("\t%s: same\n", o
->name
);
2076 if (o
->sorted
!= r
->sorted
)
2077 log(L_WARN
"Reconfiguration of rtable sorted flag not implemented");
2081 DBG("\t%s: deleted\n", o
->name
);
2083 config_add_obstacle(old
);
2085 rt_unlock_table(ot
);
2091 WALK_LIST(r
, new->tables
)
2094 rtable
*t
= mb_alloc(rt_table_pool
, sizeof(struct rtable
));
2095 DBG("\t%s: created\n", r
->name
);
2096 rt_setup(rt_table_pool
, t
, r
->name
, r
);
2097 add_tail(&routing_tables
, &t
->n
);
2104 do_feed_channel(struct channel
*c
, net
*n
, rte
*e
)
2107 if (c
->ra_mode
== RA_ACCEPTED
)
2108 rt_notify_accepted(c
, n
, e
, NULL
, NULL
, c
->refeeding
? 2 : 1);
2109 else if (c
->ra_mode
== RA_MERGED
)
2110 rt_notify_merged(c
, n
, NULL
, NULL
, e
, c
->refeeding
? e
: NULL
, c
->refeeding
);
2112 rt_notify_basic(c
, n
, e
, c
->refeeding
? e
: NULL
, c
->refeeding
);
2113 rte_update_unlock();
2117 * rt_feed_channel - advertise all routes to a channel
2118 * @c: channel to be fed
2120 * This function performs one pass of advertisement of routes to a channel that
2121 * is in the ES_FEEDING state. It is called by the protocol code as long as it
2122 * has something to do. (We avoid transferring all the routes in single pass in
2123 * order not to monopolize CPU time.)
2126 rt_feed_channel(struct channel
*c
)
2128 struct fib_iterator
*fit
= &c
->feed_fit
;
2131 ASSERT(c
->export_state
== ES_FEEDING
);
2133 if (!c
->feed_active
)
2135 FIB_ITERATE_INIT(fit
, &c
->table
->fib
);
2139 FIB_ITERATE_START(&c
->table
->fib
, fit
, net
, n
)
2144 FIB_ITERATE_PUT(fit
);
2148 /* FIXME: perhaps we should change feed for RA_ACCEPTED to not use 'new' */
2150 if ((c
->ra_mode
== RA_OPTIMAL
) ||
2151 (c
->ra_mode
== RA_ACCEPTED
) ||
2152 (c
->ra_mode
== RA_MERGED
))
2153 if (rte_is_valid(e
))
2155 /* In the meantime, the protocol may fell down */
2156 if (c
->export_state
!= ES_FEEDING
)
2159 do_feed_channel(c
, n
, e
);
2163 if (c
->ra_mode
== RA_ANY
)
2164 for(e
= n
->routes
; e
; e
= e
->next
)
2166 /* In the meantime, the protocol may fell down */
2167 if (c
->export_state
!= ES_FEEDING
)
2170 if (!rte_is_valid(e
))
2173 do_feed_channel(c
, n
, e
);
2185 * rt_feed_baby_abort - abort protocol feeding
2188 * This function is called by the protocol code when the protocol stops or
2189 * ceases to exist during the feeding.
2192 rt_feed_channel_abort(struct channel
*c
)
2196 /* Unlink the iterator */
2197 fit_get(&c
->table
->fib
, &c
->feed_fit
);
2202 static inline unsigned
2205 uintptr_t p
= (uintptr_t) ptr
;
2206 return p
^ (p
<< 8) ^ (p
>> 16);
2210 hc_hash(ip_addr a
, rtable
*dep
)
2212 return ipa_hash(a
) ^ ptr_hash(dep
);
2216 hc_insert(struct hostcache
*hc
, struct hostentry
*he
)
2218 uint k
= he
->hash_key
>> hc
->hash_shift
;
2219 he
->next
= hc
->hash_table
[k
];
2220 hc
->hash_table
[k
] = he
;
2224 hc_remove(struct hostcache
*hc
, struct hostentry
*he
)
2226 struct hostentry
**hep
;
2227 uint k
= he
->hash_key
>> hc
->hash_shift
;
2229 for (hep
= &hc
->hash_table
[k
]; *hep
!= he
; hep
= &(*hep
)->next
);
2233 #define HC_DEF_ORDER 10
2234 #define HC_HI_MARK *4
2235 #define HC_HI_STEP 2
2236 #define HC_HI_ORDER 16 /* Must be at most 16 */
2237 #define HC_LO_MARK /5
2238 #define HC_LO_STEP 2
2239 #define HC_LO_ORDER 10
2242 hc_alloc_table(struct hostcache
*hc
, unsigned order
)
2244 uint hsize
= 1 << order
;
2245 hc
->hash_order
= order
;
2246 hc
->hash_shift
= 32 - order
;
2247 hc
->hash_max
= (order
>= HC_HI_ORDER
) ? ~0U : (hsize HC_HI_MARK
);
2248 hc
->hash_min
= (order
<= HC_LO_ORDER
) ? 0U : (hsize HC_LO_MARK
);
2250 hc
->hash_table
= mb_allocz(rt_table_pool
, hsize
* sizeof(struct hostentry
*));
2254 hc_resize(struct hostcache
*hc
, unsigned new_order
)
2256 struct hostentry
**old_table
= hc
->hash_table
;
2257 struct hostentry
*he
, *hen
;
2258 uint old_size
= 1 << hc
->hash_order
;
2261 hc_alloc_table(hc
, new_order
);
2262 for (i
= 0; i
< old_size
; i
++)
2263 for (he
= old_table
[i
]; he
!= NULL
; he
=hen
)
2271 static struct hostentry
*
2272 hc_new_hostentry(struct hostcache
*hc
, ip_addr a
, ip_addr ll
, rtable
*dep
, unsigned k
)
2274 struct hostentry
*he
= sl_alloc(hc
->slab
);
2276 *he
= (struct hostentry
) {
2283 add_tail(&hc
->hostentries
, &he
->ln
);
2287 if (hc
->hash_items
> hc
->hash_max
)
2288 hc_resize(hc
, hc
->hash_order
+ HC_HI_STEP
);
2294 hc_delete_hostentry(struct hostcache
*hc
, struct hostentry
*he
)
2300 sl_free(hc
->slab
, he
);
2303 if (hc
->hash_items
< hc
->hash_min
)
2304 hc_resize(hc
, hc
->hash_order
- HC_LO_STEP
);
2308 rt_init_hostcache(rtable
*tab
)
2310 struct hostcache
*hc
= mb_allocz(rt_table_pool
, sizeof(struct hostcache
));
2311 init_list(&hc
->hostentries
);
2314 hc_alloc_table(hc
, HC_DEF_ORDER
);
2315 hc
->slab
= sl_new(rt_table_pool
, sizeof(struct hostentry
));
2317 hc
->lp
= lp_new(rt_table_pool
, 1008);
2318 hc
->trie
= f_new_trie(hc
->lp
, sizeof(struct f_trie_node
));
2320 tab
->hostcache
= hc
;
2324 rt_free_hostcache(rtable
*tab
)
2326 struct hostcache
*hc
= tab
->hostcache
;
2329 WALK_LIST(n
, hc
->hostentries
)
2331 struct hostentry
*he
= SKIP_BACK(struct hostentry
, ln
, n
);
2335 log(L_ERR
"Hostcache is not empty in table %s", tab
->name
);
2340 mb_free(hc
->hash_table
);
2345 rt_notify_hostcache(rtable
*tab
, net
*net
)
2347 if (tab
->hcu_scheduled
)
2350 if (trie_match_net(tab
->hostcache
->trie
, net
->n
.addr
))
2351 rt_schedule_hcu(tab
);
2355 if_local_addr(ip_addr a
, struct iface
*i
)
2359 WALK_LIST(b
, i
->addrs
)
2360 if (ipa_equal(a
, b
->ip
))
2367 rt_get_igp_metric(rte
*rt
)
2369 eattr
*ea
= ea_find(rt
->attrs
->eattrs
, EA_GEN_IGP_METRIC
);
2377 if ((a
->source
== RTS_OSPF
) ||
2378 (a
->source
== RTS_OSPF_IA
) ||
2379 (a
->source
== RTS_OSPF_EXT1
))
2380 return rt
->u
.ospf
.metric1
;
2384 if (a
->source
== RTS_RIP
)
2385 return rt
->u
.rip
.metric
;
2388 if (a
->source
== RTS_DEVICE
)
2391 return IGP_METRIC_UNKNOWN
;
2395 rt_update_hostentry(rtable
*tab
, struct hostentry
*he
)
2397 rta
*old_src
= he
->src
;
2400 /* Reset the hostentry */
2402 he
->nexthop_linkable
= 0;
2403 he
->dest
= RTD_UNREACHABLE
;
2407 net_fill_ip_host(&he_addr
, he
->addr
);
2408 net
*n
= net_route(tab
, &he_addr
);
2413 pxlen
= n
->n
.addr
->pxlen
;
2417 /* Recursive route should not depend on another recursive route */
2418 log(L_WARN
"Next hop address %I resolvable through recursive route for %N",
2419 he
->addr
, n
->n
.addr
);
2424 he
->nexthop_linkable
= 1;
2425 if (he
->dest
== RTD_UNICAST
)
2427 for (struct nexthop
*nh
= &(a
->nh
); nh
; nh
= nh
->next
)
2428 if (ipa_zero(nh
->gw
))
2430 if (if_local_addr(he
->addr
, nh
->iface
))
2432 /* The host address is a local address, this is not valid */
2433 log(L_WARN
"Next hop address %I is a local address of iface %s",
2434 he
->addr
, nh
->iface
->name
);
2438 he
->nexthop_linkable
= 0;
2443 he
->src
= rta_clone(a
);
2444 he
->igp_metric
= rt_get_igp_metric(e
);
2448 /* Add a prefix range to the trie */
2449 trie_add_prefix(tab
->hostcache
->trie
, &he_addr
, pxlen
, he_addr
.pxlen
);
2452 return old_src
!= he
->src
;
2456 rt_update_hostcache(rtable
*tab
)
2458 struct hostcache
*hc
= tab
->hostcache
;
2459 struct hostentry
*he
;
2462 /* Reset the trie */
2464 hc
->trie
= f_new_trie(hc
->lp
, sizeof(struct f_trie_node
));
2466 WALK_LIST_DELSAFE(n
, x
, hc
->hostentries
)
2468 he
= SKIP_BACK(struct hostentry
, ln
, n
);
2471 hc_delete_hostentry(hc
, he
);
2475 if (rt_update_hostentry(tab
, he
))
2476 rt_schedule_nhu(he
->tab
);
2479 tab
->hcu_scheduled
= 0;
2483 rt_get_hostentry(rtable
*tab
, ip_addr a
, ip_addr ll
, rtable
*dep
)
2485 struct hostentry
*he
;
2487 if (!tab
->hostcache
)
2488 rt_init_hostcache(tab
);
2490 u32 k
= hc_hash(a
, dep
);
2491 struct hostcache
*hc
= tab
->hostcache
;
2492 for (he
= hc
->hash_table
[k
>> hc
->hash_shift
]; he
!= NULL
; he
= he
->next
)
2493 if (ipa_equal(he
->addr
, a
) && (he
->tab
== dep
))
2496 he
= hc_new_hostentry(hc
, a
, ipa_zero(ll
) ? a
: ll
, dep
, k
);
2497 rt_update_hostentry(tab
, he
);
2507 rt_show_table(struct cli
*c
, struct rt_show_data
*d
)
2509 /* No table blocks in 'show route count' */
2513 if (d
->last_table
) cli_printf(c
, -1007, "");
2514 cli_printf(c
, -1007, "Table %s:", d
->tab
->table
->name
);
2515 d
->last_table
= d
->tab
;
2519 rt_show_rte(struct cli
*c
, byte
*ia
, rte
*e
, struct rt_show_data
*d
, ea_list
*tmpa
)
2521 byte from
[IPA_MAX_TEXT_LENGTH
+8];
2522 byte tm
[TM_DATETIME_BUFFER_SIZE
], info
[256];
2524 int primary
= (e
->net
->routes
== e
);
2525 int sync_error
= (e
->net
->n
.flags
& KRF_SYNC_ERROR
);
2526 void (*get_route_info
)(struct rte
*, byte
*buf
, struct ea_list
*attrs
);
2529 tm_format_datetime(tm
, &config
->tf_route
, e
->lastmod
);
2530 if (ipa_nonzero(a
->from
) && !ipa_equal(a
->from
, a
->nh
.gw
))
2531 bsprintf(from
, " from %I", a
->from
);
2535 get_route_info
= a
->src
->proto
->proto
->get_route_info
;
2536 if (get_route_info
|| d
->verbose
)
2538 /* Need to normalize the extended attributes */
2540 t
= ea_append(t
, a
->eattrs
);
2541 tmpa
= alloca(ea_scan(t
));
2546 get_route_info(e
, info
, tmpa
);
2548 bsprintf(info
, " (%d)", e
->pref
);
2550 if (d
->last_table
!= d
->tab
)
2551 rt_show_table(c
, d
);
2553 cli_printf(c
, -1007, "%-18s %s [%s %s%s]%s%s", ia
, rta_dest_name(a
->dest
),
2554 a
->src
->proto
->name
, tm
, from
, primary
? (sync_error
? " !" : " *") : "", info
);
2556 if (a
->dest
== RTD_UNICAST
)
2557 for (nh
= &(a
->nh
); nh
; nh
= nh
->next
)
2559 char mpls
[MPLS_MAX_LABEL_STACK
*12 + 5], *lsp
= mpls
;
2563 lsp
+= bsprintf(lsp
, " mpls %d", nh
->label
[0]);
2564 for (int i
=1;i
<nh
->labels
; i
++)
2565 lsp
+= bsprintf(lsp
, "/%d", nh
->label
[i
]);
2570 cli_printf(c
, -1007, "\tvia %I%s on %s weight %d", nh
->gw
, mpls
, nh
->iface
->name
, nh
->weight
+ 1);
2572 cli_printf(c
, -1007, "\tvia %I%s on %s", nh
->gw
, mpls
, nh
->iface
->name
);
2576 rta_show(c
, a
, tmpa
);
2580 rt_show_net(struct cli
*c
, net
*n
, struct rt_show_data
*d
)
2583 byte ia
[NET_MAX_TEXT_LENGTH
+1];
2584 struct ea_list
*tmpa
;
2585 struct channel
*ec
= d
->tab
->export_channel
;
2589 bsnprintf(ia
, sizeof(ia
), "%N", n
->n
.addr
);
2591 for (e
= n
->routes
; e
; e
= e
->next
)
2593 if (rte_is_filtered(e
) != d
->filtered
)
2597 d
->net_counter
+= first
;
2604 rte_update_lock(); /* We use the update buffer for filtering */
2605 tmpa
= make_tmp_attrs(e
, rte_update_pool
);
2607 /* Export channel is down, do not try to export routes to it */
2608 if (ec
&& (ec
->export_state
== ES_DOWN
))
2611 /* Special case for merged export */
2612 if ((d
->export_mode
== RSEM_EXPORT
) && (ec
->ra_mode
== RA_MERGED
))
2615 e
= rt_export_merged(ec
, n
, &rt_free
, &tmpa
, rte_update_pool
, 1);
2619 { e
= ee
; goto skip
; }
2621 else if (d
->export_mode
)
2623 struct proto
*ep
= ec
->proto
;
2624 int ic
= ep
->import_control
? ep
->import_control(ep
, &e
, &tmpa
, rte_update_pool
) : 0;
2626 if (ec
->ra_mode
== RA_OPTIMAL
|| ec
->ra_mode
== RA_MERGED
)
2632 if (d
->export_mode
> RSEM_PREEXPORT
)
2635 * FIXME - This shows what should be exported according to current
2636 * filters, but not what was really exported. 'configure soft'
2637 * command may change the export filter and do not update routes.
2639 int do_export
= (ic
> 0) ||
2640 (f_run(ec
->out_filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) <= F_ACCEPT
);
2642 if (do_export
!= (d
->export_mode
== RSEM_EXPORT
))
2645 if ((d
->export_mode
== RSEM_EXPORT
) && (ec
->ra_mode
== RA_ACCEPTED
))
2650 if (d
->show_protocol
&& (d
->show_protocol
!= e
->attrs
->src
->proto
))
2653 if (f_run(d
->filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
)
2657 rt_show_rte(c
, ia
, e
, d
, tmpa
);
2668 rte_update_unlock();
2670 if (d
->primary_only
)
2676 rt_show_cleanup(struct cli
*c
)
2678 struct rt_show_data
*d
= c
->rover
;
2679 struct rt_show_data_rtable
*tab
;
2681 /* Unlink the iterator */
2683 fit_get(&d
->tab
->table
->fib
, &d
->fit
);
2685 /* Unlock referenced tables */
2686 WALK_LIST(tab
, d
->tables
)
2687 rt_unlock_table(tab
->table
);
2691 rt_show_cont(struct cli
*c
)
2693 struct rt_show_data
*d
= c
->rover
;
2699 struct fib
*fib
= &d
->tab
->table
->fib
;
2700 struct fib_iterator
*it
= &d
->fit
;
2702 if (d
->running_on_config
&& (d
->running_on_config
!= config
))
2704 cli_printf(c
, 8004, "Stopped due to reconfiguration");
2710 FIB_ITERATE_INIT(&d
->fit
, &d
->tab
->table
->fib
);
2714 d
->show_counter_last
= d
->show_counter
;
2715 d
->rt_counter_last
= d
->rt_counter
;
2716 d
->net_counter_last
= d
->net_counter
;
2718 if (d
->tables_defined_by
& RSD_TDB_SET
)
2719 rt_show_table(c
, d
);
2722 FIB_ITERATE_START(fib
, it
, net
, n
)
2726 FIB_ITERATE_PUT(it
);
2729 rt_show_net(c
, n
, d
);
2735 if (d
->last_table
!= d
->tab
)
2736 rt_show_table(c
, d
);
2738 cli_printf(c
, -1007, "%d of %d routes for %d networks in table %s",
2739 d
->show_counter
- d
->show_counter_last
, d
->rt_counter
- d
->rt_counter_last
,
2740 d
->net_counter
- d
->net_counter_last
, d
->tab
->table
->name
);
2744 d
->tab
= NODE_NEXT(d
->tab
);
2746 if (NODE_VALID(d
->tab
))
2749 if (d
->stats
&& (d
->table_counter
> 1))
2751 if (d
->last_table
) cli_printf(c
, -1007, "");
2752 cli_printf(c
, 14, "Total: %d of %d routes for %d networks in %d tables",
2753 d
->show_counter
, d
->rt_counter
, d
->net_counter
, d
->table_counter
);
2756 cli_printf(c
, 0, "");
2760 c
->cont
= c
->cleanup
= NULL
;
2763 struct rt_show_data_rtable
*
2764 rt_show_add_table(struct rt_show_data
*d
, rtable
*t
)
2766 struct rt_show_data_rtable
*tab
= cfg_allocz(sizeof(struct rt_show_data_rtable
));
2768 add_tail(&(d
->tables
), &(tab
->n
));
2773 rt_show_get_default_tables(struct rt_show_data
*d
)
2776 struct rt_show_data_rtable
*tab
;
2778 if (d
->export_channel
)
2780 c
= d
->export_channel
;
2781 tab
= rt_show_add_table(d
, c
->table
);
2782 tab
->export_channel
= c
;
2786 if (d
->export_protocol
)
2788 WALK_LIST(c
, d
->export_protocol
->channels
)
2790 if (c
->export_state
== ES_DOWN
)
2793 tab
= rt_show_add_table(d
, c
->table
);
2794 tab
->export_channel
= c
;
2799 if (d
->show_protocol
)
2801 WALK_LIST(c
, d
->show_protocol
->channels
)
2802 rt_show_add_table(d
, c
->table
);
2806 for (int i
=1; i
<NET_MAX
; i
++)
2807 if (config
->def_tables
[i
])
2808 rt_show_add_table(d
, config
->def_tables
[i
]->table
);
2812 rt_show_prepare_tables(struct rt_show_data
*d
)
2814 struct rt_show_data_rtable
*tab
, *tabx
;
2816 /* Add implicit tables if no table is specified */
2817 if (EMPTY_LIST(d
->tables
))
2818 rt_show_get_default_tables(d
);
2820 WALK_LIST_DELSAFE(tab
, tabx
, d
->tables
)
2822 /* Ensure there is defined export_channel for each table */
2825 if (!tab
->export_channel
&& d
->export_channel
&&
2826 (tab
->table
== d
->export_channel
->table
))
2827 tab
->export_channel
= d
->export_channel
;
2829 if (!tab
->export_channel
&& d
->export_protocol
)
2830 tab
->export_channel
= proto_find_channel_by_table(d
->export_protocol
, tab
->table
);
2832 if (!tab
->export_channel
)
2834 if (d
->tables_defined_by
& RSD_TDB_NMN
)
2835 cf_error("No export channel for table %s", tab
->table
->name
);
2837 rem_node(&(tab
->n
));
2842 /* Ensure specified network is compatible with each table */
2843 if (d
->addr
&& (tab
->table
->addr_type
!= d
->addr
->type
))
2845 if (d
->tables_defined_by
& RSD_TDB_NMN
)
2846 cf_error("Incompatible type of prefix/ip for table %s", tab
->table
->name
);
2848 rem_node(&(tab
->n
));
2853 /* Ensure there is at least one table */
2854 if (EMPTY_LIST(d
->tables
))
2855 cf_error("No valid tables");
2859 rt_show(struct rt_show_data
*d
)
2861 struct rt_show_data_rtable
*tab
;
2864 /* Filtered routes are neither exported nor have sensible ordering */
2865 if (d
->filtered
&& (d
->export_mode
|| d
->primary_only
))
2866 cf_error("Incompatible show route options");
2868 rt_show_prepare_tables(d
);
2872 WALK_LIST(tab
, d
->tables
)
2873 rt_lock_table(tab
->table
);
2875 /* There is at least one table */
2876 d
->tab
= HEAD(d
->tables
);
2877 this_cli
->cont
= rt_show_cont
;
2878 this_cli
->cleanup
= rt_show_cleanup
;
2879 this_cli
->rover
= d
;
2883 WALK_LIST(tab
, d
->tables
)
2888 n
= net_route(tab
->table
, d
->addr
);
2890 n
= net_find(tab
->table
, d
->addr
);
2893 rt_show_net(this_cli
, n
, d
);
2899 cli_msg(8001, "Network not found");
2904 * Documentation for functions declared inline in route.h
2909 * net_find - find a network entry
2910 * @tab: a routing table
2911 * @addr: address of the network
2913 * net_find() looks up the given network in routing table @tab and
2914 * returns a pointer to its &net entry or %NULL if no such network
2917 static inline net
*net_find(rtable
*tab
, net_addr
*addr
)
2921 * net_get - obtain a network entry
2922 * @tab: a routing table
2923 * @addr: address of the network
2925 * net_get() looks up the given network in routing table @tab and
2926 * returns a pointer to its &net entry. If no such entry exists, it's
2929 static inline net
*net_get(rtable
*tab
, net_addr
*addr
)
2933 * rte_cow - copy a route for writing
2934 * @r: a route entry to be copied
2936 * rte_cow() takes a &rte and prepares it for modification. The exact action
2937 * taken depends on the flags of the &rte -- if it's a temporary entry, it's
2938 * just returned unchanged, else a new temporary entry with the same contents
2941 * The primary use of this function is inside the filter machinery -- when
2942 * a filter wants to modify &rte contents (to change the preference or to
2943 * attach another set of attributes), it must ensure that the &rte is not
2944 * shared with anyone else (and especially that it isn't stored in any routing
2947 * Result: a pointer to the new writable &rte.
2949 static inline rte
* rte_cow(rte
*r
)