]>
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"
46 static slab
*rte_slab
;
47 static linpool
*rte_update_pool
;
49 static pool
*rt_table_pool
;
50 static list routing_tables
;
52 static void rt_format_via(rte
*e
, byte
*via
);
55 rte_init(struct fib_node
*N
)
64 * rte_find - find a route
68 * The rte_find() function returns a route for destination @net
69 * which belongs has been defined by protocol @p.
72 rte_find(net
*net
, struct proto
*p
)
76 while (e
&& e
->attrs
->proto
!= p
)
82 * rte_get_temp - get a temporary &rte
83 * @a: attributes to assign to the new route (a &rta; in case it's
84 * un-cached, rte_update() will create a cached copy automatically)
86 * Create a temporary &rte and bind it with the attributes @a.
87 * Also set route preference to the default preference set for
93 rte
*e
= sl_alloc(rte_slab
);
97 e
->pref
= a
->proto
->preference
;
104 rte
*e
= sl_alloc(rte_slab
);
106 memcpy(e
, r
, sizeof(rte
));
107 e
->attrs
= rta_clone(r
->attrs
);
112 static int /* Actually better or at least as good as */
113 rte_better(rte
*new, rte
*old
)
115 int (*better
)(rte
*, rte
*);
119 if (new->pref
> old
->pref
)
121 if (new->pref
< old
->pref
)
123 if (new->attrs
->proto
->proto
!= old
->attrs
->proto
->proto
)
126 * If the user has configured protocol preferences, so that two different protocols
127 * have the same preference, try to break the tie by comparing addresses. Not too
128 * useful, but keeps the ordering of routes unambiguous.
130 return new->attrs
->proto
->proto
> old
->attrs
->proto
->proto
;
132 if (better
= new->attrs
->proto
->rte_better
)
133 return better(new, old
);
138 rte_trace(struct proto
*p
, rte
*e
, int dir
, char *msg
)
140 byte via
[STD_ADDRESS_P_LENGTH
+32];
142 rt_format_via(e
, via
);
143 log(L_TRACE
"%s %c %s %I/%d %s", p
->name
, dir
, msg
, e
->net
->n
.prefix
, e
->net
->n
.pxlen
, via
);
147 rte_trace_in(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
150 rte_trace(p
, e
, '>', msg
);
154 rte_trace_out(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
157 rte_trace(p
, e
, '<', msg
);
161 do_rte_announce(struct announce_hook
*a
, int type UNUSED
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
, int class, int refeed
)
163 struct proto
*p
= a
->proto
;
164 struct filter
*filter
= p
->out_filter
;
165 struct proto_stats
*stats
= &p
->stats
;
170 int fast_exit_hack
= 0;
173 /* The secondary direction of the pipe */
174 if (proto_is_pipe(p
) && (p
->table
!= a
->table
))
176 filter
= p
->in_filter
;
177 stats
= pipe_get_peer_stats(p
);
183 stats
->exp_updates_received
++;
185 char *drop_reason
= NULL
;
186 if ((class & IADDR_SCOPE_MASK
) < p
->min_scope
)
188 stats
->exp_updates_rejected
++;
189 drop_reason
= "out of scope";
192 else if ((ok
= p
->import_control
? p
->import_control(p
, &new, &tmpa
, rte_update_pool
) : 0) < 0)
194 stats
->exp_updates_rejected
++;
195 drop_reason
= "rejected by protocol";
198 rte_trace_out(D_FILTERS
, p
, new, "forced accept by protocol");
199 else if ((filter
== FILTER_REJECT
) ||
200 (filter
&& f_run(filter
, &new, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
202 stats
->exp_updates_filtered
++;
203 drop_reason
= "filtered out";
207 rte_trace_out(D_FILTERS
, p
, new, drop_reason
);
214 stats
->exp_withdraws_received
++;
216 /* Hack: This is here to prevent 'spurious withdraws'
217 for loopback addresses during reload. */
222 * This is a tricky part - we don't know whether route 'old' was
223 * exported to protocol 'p' or was filtered by the export filter.
224 * We try tu run the export filter to know this to have a correct
225 * value in 'old' argument of rt_update (and proper filter value)
227 * FIXME - this is broken because 'configure soft' may change
228 * filters but keep routes. Refeed is expected to be called after
229 * change of the filters and with old == new, therefore we do not
230 * even try to run the filter on an old route, This may lead to
231 * 'spurious withdraws' but ensure that there are no 'missing
234 * This is not completely safe as there is a window between
235 * reconfiguration and the end of refeed - if a newly filtered
236 * route disappears during this period, proper withdraw is not
237 * sent (because old would be also filtered) and the route is
238 * not refeeded (because it disappeared before that).
243 if (filter
== FILTER_REJECT
)
247 ea_list
*tmpb
= p
->make_tmp_attrs
? p
->make_tmp_attrs(old
, rte_update_pool
) : NULL
;
248 ok
= p
->import_control
? p
->import_control(p
, &old
, &tmpb
, rte_update_pool
) : 0;
249 if (ok
< 0 || (!ok
&& filter
&& f_run(filter
, &old
, &tmpb
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
258 /* FIXME - This is broken because of incorrect 'old' value (see above) */
263 stats
->exp_updates_accepted
++;
265 stats
->exp_withdraws_accepted
++;
267 /* Hack: We do not decrease exp_routes during refeed, we instead
268 reset exp_routes at the start of refeed. */
274 if (p
->debug
& D_ROUTES
)
277 rte_trace_out(D_ROUTES
, p
, new, "replaced");
279 rte_trace_out(D_ROUTES
, p
, new, "added");
281 rte_trace_out(D_ROUTES
, p
, old
, "removed");
284 p
->rt_notify(p
, a
->table
, net
, NULL
, old
, NULL
);
290 t
->next
= new->attrs
->eattrs
;
291 p
->rt_notify(p
, a
->table
, net
, new, old
, tmpa
);
295 p
->rt_notify(p
, a
->table
, net
, new, old
, new->attrs
->eattrs
);
296 if (new && new != new0
) /* Discard temporary rte's */
298 if (old
&& old
!= old0
)
303 * rte_announce - announce a routing table change
304 * @tab: table the route has been added to
305 * @type: type of route announcement (RA_OPTIMAL or RA_ANY)
306 * @net: network in question
307 * @new: the new route to be announced
308 * @old: the previous route for the same network
309 * @tmpa: a list of temporary attributes belonging to the new route
311 * This function gets a routing table update and announces it
312 * to all protocols that acccepts given type of route announcement
313 * and are connected to the same table by their announcement hooks.
315 * Route announcement of type RA_OPTIMAL si generated when optimal
316 * route (in routing table @tab) changes. In that case @old stores the
319 * Route announcement of type RA_ANY si generated when any route (in
320 * routing table @tab) changes In that case @old stores the old route
321 * from the same protocol.
323 * For each appropriate protocol, we first call its import_control()
324 * hook which performs basic checks on the route (each protocol has a
325 * right to veto or force accept of the route before any filter is
326 * asked) and adds default values of attributes specific to the new
327 * protocol (metrics, tags etc.). Then it consults the protocol's
328 * export filter and if it accepts the route, the rt_notify() hook of
329 * the protocol gets called.
332 rte_announce(rtable
*tab
, unsigned type
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
)
334 struct announce_hook
*a
;
335 int class = ipa_classify(net
->n
.prefix
);
337 if (type
== RA_OPTIMAL
)
340 new->attrs
->proto
->stats
.pref_routes
++;
342 old
->attrs
->proto
->stats
.pref_routes
--;
345 WALK_LIST(a
, tab
->hooks
)
347 ASSERT(a
->proto
->core_state
== FS_HAPPY
|| a
->proto
->core_state
== FS_FEEDING
);
348 if (a
->proto
->accept_ra_types
== type
)
349 do_rte_announce(a
, type
, net
, new, old
, tmpa
, class, 0);
359 if (ipa_nonzero(ipa_and(n
->n
.prefix
, ipa_not(ipa_mkmask(n
->n
.pxlen
)))))
361 log(L_BUG
"Ignoring bogus prefix %I/%d received via %s",
362 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->name
);
367 c
= ipa_classify(n
->n
.prefix
);
368 if (c
< 0 || !(c
& IADDR_HOST
))
370 if (!ipa_nonzero(n
->n
.prefix
))
372 /* Various default routes */
374 if (n
->n
.pxlen
== 96)
380 log(L_WARN
"Ignoring bogus route %I/%d received via %s",
381 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->name
);
384 if ((c
& IADDR_SCOPE_MASK
) < e
->sender
->min_scope
)
386 log(L_WARN
"Ignoring %s scope route %I/%d received from %I via %s",
387 ip_scope_text(c
& IADDR_SCOPE_MASK
),
388 n
->n
.prefix
, n
->n
.pxlen
, e
->attrs
->from
, e
->sender
->name
);
396 * rte_free - delete a &rte
397 * @e: &rte to be deleted
399 * rte_free() deletes the given &rte from the routing table it's linked to.
404 if (e
->attrs
->aflags
& RTAF_CACHED
)
406 sl_free(rte_slab
, e
);
410 rte_free_quick(rte
*e
)
413 sl_free(rte_slab
, e
);
417 rte_same(rte
*x
, rte
*y
)
420 x
->attrs
== y
->attrs
&&
421 x
->flags
== y
->flags
&&
422 x
->pflags
== y
->pflags
&&
423 x
->pref
== y
->pref
&&
424 (!x
->attrs
->proto
->rte_same
|| x
->attrs
->proto
->rte_same(x
, y
));
428 rte_recalculate(rtable
*table
, net
*net
, struct proto
*p
, struct proto
*src
, rte
*new, ea_list
*tmpa
)
430 struct proto_stats
*stats
= &p
->stats
;
431 rte
*old_best
= net
->routes
;
436 if (proto_is_pipe(p
) && (p
->table
== table
))
437 stats
= pipe_get_peer_stats(p
);
440 k
= &net
->routes
; /* Find and remove original route from the same protocol */
443 if (old
->attrs
->proto
== src
)
445 /* If there is the same route in the routing table but from
446 * a different sender, then there are two paths from the
447 * source protocol to this routing table through transparent
448 * pipes, which is not allowed.
450 * We log that and ignore the route. If it is withdraw, we
451 * ignore it completely (there might be 'spurious withdraws',
452 * see FIXME in do_rte_announce())
454 if (old
->sender
!= p
)
458 log(L_ERR
"Pipe collision detected when sending %I/%d to table %s",
459 net
->n
.prefix
, net
->n
.pxlen
, table
->name
);
465 if (new && rte_same(old
, new))
467 /* No changes, ignore the new route */
468 stats
->imp_updates_ignored
++;
469 rte_trace_in(D_ROUTES
, p
, new, "ignored");
482 stats
->imp_withdraws_ignored
++;
487 stats
->imp_updates_accepted
++;
489 stats
->imp_withdraws_accepted
++;
496 rte_announce(table
, RA_ANY
, net
, new, old
, tmpa
);
499 if (new && rte_better(new, old_best
))
501 /* The first case - the new route is cleary optimal, we link it
502 at the first position and announce it */
504 rte_trace_in(D_ROUTES
, p
, new, "added [best]");
505 rte_announce(table
, RA_OPTIMAL
, net
, new, old_best
, tmpa
);
506 new->next
= net
->routes
;
509 else if (old
== old_best
)
511 /* The second case - the old best route disappeared, we add the
512 new route (if we have any) to the list (we don't care about
513 position) and then we elect the new optimal route and relink
514 that route at the first position and announce it. New optimal
515 route might be NULL if there is no more routes */
517 /* Add the new route to the list */
520 rte_trace_in(D_ROUTES
, p
, new, "added");
521 new->next
= net
->routes
;
525 /* Find new optimal route */
527 for (s
=net
->routes
; s
; s
=s
->next
)
528 if (rte_better(s
, r
))
531 /* Announce optimal route */
532 rte_announce(table
, RA_OPTIMAL
, net
, r
, old_best
, tmpa
);
534 /* And relink it (if there is any) */
547 r
->next
= net
->routes
;
550 else if (table
->gc_counter
++ >= table
->config
->gc_max_ops
&&
551 table
->gc_time
+ table
->config
->gc_min_time
<= now
)
552 ev_schedule(table
->gc_event
);
556 /* The third case - the new route is not better than the old
557 best route (therefore old_best != NULL) and the old best
558 route was not removed (therefore old_best == net->routes).
559 We just link the new route after the old best route. */
561 ASSERT(net
->routes
!= NULL
);
562 new->next
= net
->routes
->next
;
563 net
->routes
->next
= new;
564 rte_trace_in(D_ROUTES
, p
, new, "added");
567 /* Log the route removal */
568 if (!new && old
&& (p
->debug
& D_ROUTES
))
571 rte_trace_in(D_ROUTES
, p
, old
, "removed");
572 else if (net
->routes
)
573 rte_trace_in(D_ROUTES
, p
, old
, "removed [replaced]");
575 rte_trace_in(D_ROUTES
, p
, old
, "removed [sole]");
581 p
->rte_remove(net
, old
);
588 p
->rte_insert(net
, new);
592 static int rte_update_nest_cnt
; /* Nesting counter to allow recursive updates */
595 rte_update_lock(void)
597 rte_update_nest_cnt
++;
601 rte_update_unlock(void)
603 if (!--rte_update_nest_cnt
)
604 lp_flush(rte_update_pool
);
608 * rte_update - enter a new update to a routing table
609 * @table: table to be updated
611 * @p: protocol submitting the update
612 * @src: protocol originating the update
613 * @new: a &rte representing the new route or %NULL for route removal.
615 * This function is called by the routing protocols whenever they discover
616 * a new route or wish to update/remove an existing route. The right announcement
617 * sequence is to build route attributes first (either un-cached with @aflags set
618 * to zero or a cached one using rta_lookup(); in this case please note that
619 * you need to increase the use count of the attributes yourself by calling
620 * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
621 * the appropriate data and finally submit the new &rte by calling rte_update().
623 * @src specifies the protocol that originally created the route and the meaning
624 * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
625 * same value as @new->attrs->proto. @p specifies the protocol that called
626 * rte_update(). In most cases it is the same protocol as @src. rte_update()
627 * stores @p in @new->sender;
629 * When rte_update() gets any route, it automatically validates it (checks,
630 * whether the network and next hop address are valid IP addresses and also
631 * whether a normal routing protocol doesn't try to smuggle a host or link
632 * scope route to the table), converts all protocol dependent attributes stored
633 * in the &rte to temporary extended attributes, consults import filters of the
634 * protocol to see if the route should be accepted and/or its attributes modified,
635 * stores the temporary attributes back to the &rte.
637 * Now, having a "public" version of the route, we
638 * automatically find any old route defined by the protocol @src
639 * for network @n, replace it by the new one (or removing it if @new is %NULL),
640 * recalculate the optimal route for this destination and finally broadcast
641 * the change (if any) to all routing protocols by calling rte_announce().
643 * All memory used for attribute lists and other temporary allocations is taken
644 * from a special linear pool @rte_update_pool and freed when rte_update()
649 rte_update(rtable
*table
, net
*net
, struct proto
*p
, struct proto
*src
, rte
*new)
651 ea_list
*tmpa
= NULL
;
652 struct proto_stats
*stats
= &p
->stats
;
655 if (proto_is_pipe(p
) && (p
->table
== table
))
656 stats
= pipe_get_peer_stats(p
);
663 struct filter
*filter
= p
->in_filter
;
665 /* Do not filter routes going through the pipe,
666 they are filtered in the export filter only. */
668 if (proto_is_pipe(p
))
669 filter
= FILTER_ACCEPT
;
672 stats
->imp_updates_received
++;
673 if (!rte_validate(new))
675 rte_trace_in(D_FILTERS
, p
, new, "invalid");
676 stats
->imp_updates_invalid
++;
679 if (filter
== FILTER_REJECT
)
681 stats
->imp_updates_filtered
++;
682 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
685 if (src
->make_tmp_attrs
)
686 tmpa
= src
->make_tmp_attrs(new, rte_update_pool
);
689 ea_list
*old_tmpa
= tmpa
;
690 int fr
= f_run(filter
, &new, &tmpa
, rte_update_pool
, 0);
693 stats
->imp_updates_filtered
++;
694 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
697 if (tmpa
!= old_tmpa
&& src
->store_tmp_attrs
)
698 src
->store_tmp_attrs(new, tmpa
);
700 if (!(new->attrs
->aflags
& RTAF_CACHED
)) /* Need to copy attributes */
701 new->attrs
= rta_lookup(new->attrs
);
702 new->flags
|= REF_COW
;
705 stats
->imp_withdraws_received
++;
707 rte_recalculate(table
, net
, p
, src
, new, tmpa
);
713 rte_recalculate(table
, net
, p
, src
, NULL
, NULL
);
718 rte_discard(rtable
*t
, rte
*old
) /* Non-filtered route deletion, used during garbage collection */
721 rte_recalculate(t
, old
->net
, old
->sender
, old
->attrs
->proto
, NULL
, NULL
);
726 * rte_dump - dump a route
727 * @e: &rte to be dumped
729 * This functions dumps contents of a &rte to debug output.
736 debug("%-1I/%2d ", n
->n
.prefix
, n
->n
.pxlen
);
739 debug("KF=%02x PF=%02x pref=%d lm=%d ", n
->n
.flags
, e
->pflags
, e
->pref
, now
-e
->lastmod
);
741 if (e
->attrs
->proto
->proto
->dump_attrs
)
742 e
->attrs
->proto
->proto
->dump_attrs(e
);
747 * rt_dump - dump a routing table
748 * @t: routing table to be dumped
750 * This function dumps contents of a given routing table to debug output.
757 struct announce_hook
*a
;
759 debug("Dump of routing table <%s>\n", t
->name
);
763 FIB_WALK(&t
->fib
, fn
)
766 for(e
=n
->routes
; e
; e
=e
->next
)
770 WALK_LIST(a
, t
->hooks
)
771 debug("\tAnnounces routes to protocol %s\n", a
->proto
->name
);
776 * rt_dump_all - dump all routing tables
778 * This function dumps contents of all routing tables to debug output.
785 WALK_LIST(t
, routing_tables
)
794 DBG("Entered routing table garbage collector for %s after %d seconds and %d deletes\n",
795 t
->name
, (int)(now
- t
->gc_time
), t
->gc_counter
);
800 rt_setup(pool
*p
, rtable
*t
, char *name
, struct rtable_config
*cf
)
802 bzero(t
, sizeof(*t
));
803 fib_init(&t
->fib
, p
, sizeof(net
), 0, rte_init
);
806 init_list(&t
->hooks
);
809 t
->gc_event
= ev_new(p
);
810 t
->gc_event
->hook
= rt_gc
;
811 t
->gc_event
->data
= t
;
817 * rt_init - initialize routing tables
819 * This function is called during BIRD startup. It initializes the
820 * routing table module.
826 rt_table_pool
= rp_new(&root_pool
, "Routing tables");
827 rte_update_pool
= lp_new(rt_table_pool
, 4080);
828 rte_slab
= sl_new(rt_table_pool
, sizeof(rte
));
829 init_list(&routing_tables
);
833 * rt_prune - prune a routing table
834 * @tab: routing table to be pruned
836 * This function is called whenever a protocol shuts down. It scans
837 * the routing table and removes all routes belonging to inactive
838 * protocols and also stale network entries.
841 rt_prune(rtable
*tab
)
843 struct fib_iterator fit
;
844 int rcnt
= 0, rdel
= 0, ncnt
= 0, ndel
= 0;
846 DBG("Pruning route table %s\n", tab
->name
);
848 fib_check(&tab
->fib
);
850 FIB_ITERATE_INIT(&fit
, &tab
->fib
);
852 FIB_ITERATE_START(&tab
->fib
, &fit
, f
)
858 for (e
=n
->routes
; e
; e
=e
->next
, rcnt
++)
859 if (e
->sender
->core_state
!= FS_HAPPY
&&
860 e
->sender
->core_state
!= FS_FEEDING
)
866 if (!n
->routes
) /* Orphaned FIB entry? */
868 FIB_ITERATE_PUT(&fit
, f
);
869 fib_delete(&tab
->fib
, f
);
875 DBG("Pruned %d of %d routes and %d of %d networks\n", rdel
, rcnt
, ndel
, ncnt
);
877 fib_check(&tab
->fib
);
884 * rt_prune_all - prune all routing tables
886 * This function calls rt_prune() for all known routing tables.
893 WALK_LIST(t
, routing_tables
)
897 struct rtable_config
*
898 rt_new_table(struct symbol
*s
)
900 struct rtable_config
*c
= cfg_allocz(sizeof(struct rtable_config
));
902 cf_define_symbol(s
, SYM_TABLE
, c
);
904 add_tail(&new_config
->tables
, &c
->n
);
905 c
->gc_max_ops
= 1000;
911 rt_preconfig(struct config
*c
)
913 struct symbol
*s
= cf_find_symbol("master");
915 init_list(&c
->tables
);
916 c
->master_rtc
= rt_new_table(s
);
920 * rt_lock_table - lock a routing table
921 * @r: routing table to be locked
923 * Lock a routing table, because it's in use by a protocol,
924 * preventing it from being freed when it gets undefined in a new
928 rt_lock_table(rtable
*r
)
934 * rt_unlock_table - unlock a routing table
935 * @r: routing table to be unlocked
937 * Unlock a routing table formerly locked by rt_lock_table(),
938 * that is decrease its use count and delete it if it's scheduled
939 * for deletion by configuration changes.
942 rt_unlock_table(rtable
*r
)
944 if (!--r
->use_count
&& r
->deleted
)
946 struct config
*conf
= r
->deleted
;
947 DBG("Deleting routing table %s\n", r
->name
);
951 config_del_obstacle(conf
);
956 * rt_commit - commit new routing table configuration
957 * @new: new configuration
958 * @old: original configuration or %NULL if it's boot time config
960 * Scan differences between @old and @new configuration and modify
961 * the routing tables according to these changes. If @new defines a
962 * previously unknown table, create it, if it omits a table existing
963 * in @old, schedule it for deletion (it gets deleted when all protocols
964 * disconnect from it by calling rt_unlock_table()), if it exists
965 * in both configurations, leave it unchanged.
968 rt_commit(struct config
*new, struct config
*old
)
970 struct rtable_config
*o
, *r
;
975 WALK_LIST(o
, old
->tables
)
977 rtable
*ot
= o
->table
;
980 struct symbol
*sym
= cf_find_symbol(o
->name
);
981 if (sym
&& sym
->class == SYM_TABLE
&& !new->shutdown
)
983 DBG("\t%s: same\n", o
->name
);
991 DBG("\t%s: deleted\n", o
->name
);
993 config_add_obstacle(old
);
1001 WALK_LIST(r
, new->tables
)
1004 rtable
*t
= mb_alloc(rt_table_pool
, sizeof(struct rtable
));
1005 DBG("\t%s: created\n", r
->name
);
1006 rt_setup(rt_table_pool
, t
, r
->name
, r
);
1007 add_tail(&routing_tables
, &t
->n
);
1014 do_feed_baby(struct proto
*p
, int type
, struct announce_hook
*h
, net
*n
, rte
*e
)
1016 struct proto
*q
= e
->attrs
->proto
;
1020 tmpa
= q
->make_tmp_attrs
? q
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
1021 do_rte_announce(h
, type
, n
, e
, p
->refeeding
? e
: NULL
, tmpa
, ipa_classify(n
->n
.prefix
), p
->refeeding
);
1022 rte_update_unlock();
1026 * rt_feed_baby - advertise routes to a new protocol
1027 * @p: protocol to be fed
1029 * This function performs one pass of advertisement of routes to a newly
1030 * initialized protocol. It's called by the protocol code as long as it
1031 * has something to do. (We avoid transferring all the routes in single
1032 * pass in order not to monopolize CPU time.)
1035 rt_feed_baby(struct proto
*p
)
1037 struct announce_hook
*h
;
1038 struct fib_iterator
*fit
;
1041 if (!p
->feed_ahook
) /* Need to initialize first */
1045 DBG("Announcing routes to new protocol %s\n", p
->name
);
1046 p
->feed_ahook
= p
->ahooks
;
1047 fit
= p
->feed_iterator
= mb_alloc(p
->pool
, sizeof(struct fib_iterator
));
1050 fit
= p
->feed_iterator
;
1054 FIB_ITERATE_START(&h
->table
->fib
, fit
, fn
)
1056 net
*n
= (net
*) fn
;
1060 FIB_ITERATE_PUT(fit
, fn
);
1064 if (p
->accept_ra_types
== RA_OPTIMAL
)
1067 if (p
->core_state
!= FS_FEEDING
)
1068 return 1; /* In the meantime, the protocol fell down. */
1069 do_feed_baby(p
, RA_OPTIMAL
, h
, n
, e
);
1073 if (p
->accept_ra_types
== RA_ANY
)
1074 for(e
= n
->routes
; e
!= NULL
; e
= e
->next
)
1076 if (p
->core_state
!= FS_FEEDING
)
1077 return 1; /* In the meantime, the protocol fell down. */
1078 do_feed_baby(p
, RA_ANY
, h
, n
, e
);
1082 FIB_ITERATE_END(fn
);
1083 p
->feed_ahook
= h
->next
;
1086 mb_free(p
->feed_iterator
);
1087 p
->feed_iterator
= NULL
;
1093 FIB_ITERATE_INIT(fit
, &h
->table
->fib
);
1098 * rt_feed_baby_abort - abort protocol feeding
1101 * This function is called by the protocol code when the protocol
1102 * stops or ceases to exist before the last iteration of rt_feed_baby()
1106 rt_feed_baby_abort(struct proto
*p
)
1110 /* Unlink the iterator and exit */
1111 fit_get(&p
->feed_ahook
->table
->fib
, p
->feed_iterator
);
1112 p
->feed_ahook
= NULL
;
1121 rt_format_via(rte
*e
, byte
*via
)
1127 case RTD_ROUTER
: bsprintf(via
, "via %I on %s", a
->gw
, a
->iface
->name
); break;
1128 case RTD_DEVICE
: bsprintf(via
, "dev %s", a
->iface
->name
); break;
1129 case RTD_BLACKHOLE
: bsprintf(via
, "blackhole"); break;
1130 case RTD_UNREACHABLE
: bsprintf(via
, "unreachable"); break;
1131 case RTD_PROHIBIT
: bsprintf(via
, "prohibited"); break;
1132 default: bsprintf(via
, "???");
1137 rt_show_rte(struct cli
*c
, byte
*ia
, rte
*e
, struct rt_show_data
*d
, ea_list
*tmpa
)
1139 byte via
[STD_ADDRESS_P_LENGTH
+32], from
[STD_ADDRESS_P_LENGTH
+6];
1140 byte tm
[TM_DATETIME_BUFFER_SIZE
], info
[256];
1142 int primary
= (e
->net
->routes
== e
);
1144 rt_format_via(e
, via
);
1145 tm_format_datetime(tm
, &config
->tf_route
, e
->lastmod
);
1146 if (ipa_nonzero(a
->from
) && !ipa_equal(a
->from
, a
->gw
))
1147 bsprintf(from
, " from %I", a
->from
);
1150 if (a
->proto
->proto
->get_route_info
|| d
->verbose
)
1152 /* Need to normalize the extended attributes */
1154 t
= ea_append(t
, a
->eattrs
);
1155 tmpa
= alloca(ea_scan(t
));
1159 if (a
->proto
->proto
->get_route_info
)
1160 a
->proto
->proto
->get_route_info(e
, info
, tmpa
);
1162 bsprintf(info
, " (%d)", e
->pref
);
1163 cli_printf(c
, -1007, "%-18s %s [%s %s%s]%s%s", ia
, via
, a
->proto
->name
,
1164 tm
, from
, primary
? " *" : "", info
);
1166 rta_show(c
, a
, tmpa
);
1170 rt_show_net(struct cli
*c
, net
*n
, struct rt_show_data
*d
)
1173 byte ia
[STD_ADDRESS_P_LENGTH
+8];
1176 bsprintf(ia
, "%I/%d", n
->n
.prefix
, n
->n
.pxlen
);
1179 for(e
=n
->routes
; e
; e
=e
->next
)
1181 struct ea_list
*tmpa
, *old_tmpa
;
1182 struct proto
*p0
= e
->attrs
->proto
;
1183 struct proto
*p1
= d
->export_protocol
;
1184 struct proto
*p2
= d
->show_protocol
;
1187 rte_update_lock(); /* We use the update buffer for filtering */
1188 old_tmpa
= tmpa
= p0
->make_tmp_attrs
? p0
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
1189 ok
= (d
->filter
== FILTER_ACCEPT
|| f_run(d
->filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) <= F_ACCEPT
);
1190 if (p2
&& p2
!= p0
) ok
= 0;
1191 if (ok
&& d
->export_mode
)
1193 int class = ipa_classify(n
->n
.prefix
);
1195 if ((class & IADDR_SCOPE_MASK
) < p1
->min_scope
)
1197 else if ((ic
= p1
->import_control
? p1
->import_control(p1
, &e
, &tmpa
, rte_update_pool
) : 0) < 0)
1199 else if (!ic
&& d
->export_mode
> 1)
1201 /* FIXME - this shows what should be exported according
1202 to current filters, but not what was really exported.
1203 'configure soft' command may change the export filter
1204 and do not update routes */
1206 if ((p1
->out_filter
== FILTER_REJECT
) ||
1207 (p1
->out_filter
&& f_run(p1
->out_filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
1215 rt_show_rte(c
, ia
, e
, d
, tmpa
);
1220 rte_update_unlock();
1221 if (d
->primary_only
)
1227 rt_show_cont(struct cli
*c
)
1229 struct rt_show_data
*d
= c
->rover
;
1235 struct fib
*fib
= &d
->table
->fib
;
1236 struct fib_iterator
*it
= &d
->fit
;
1238 FIB_ITERATE_START(fib
, it
, f
)
1241 if (d
->running_on_config
&& d
->running_on_config
!= config
)
1243 cli_printf(c
, 8004, "Stopped due to reconfiguration");
1246 if (d
->export_protocol
&&
1247 d
->export_protocol
->core_state
!= FS_HAPPY
&&
1248 d
->export_protocol
->core_state
!= FS_FEEDING
)
1250 cli_printf(c
, 8005, "Protocol is down");
1255 FIB_ITERATE_PUT(it
, f
);
1258 rt_show_net(c
, n
, d
);
1262 cli_printf(c
, 14, "%d of %d routes for %d networks", d
->show_counter
, d
->rt_counter
, d
->net_counter
);
1264 cli_printf(c
, 0, "");
1266 c
->cont
= c
->cleanup
= NULL
;
1270 rt_show_cleanup(struct cli
*c
)
1272 struct rt_show_data
*d
= c
->rover
;
1274 /* Unlink the iterator */
1275 fit_get(&d
->table
->fib
, &d
->fit
);
1279 rt_show(struct rt_show_data
*d
)
1283 if (d
->pxlen
== 256)
1285 FIB_ITERATE_INIT(&d
->fit
, &d
->table
->fib
);
1286 this_cli
->cont
= rt_show_cont
;
1287 this_cli
->cleanup
= rt_show_cleanup
;
1288 this_cli
->rover
= d
;
1293 n
= fib_route(&d
->table
->fib
, d
->prefix
, d
->pxlen
);
1295 n
= fib_find(&d
->table
->fib
, &d
->prefix
, d
->pxlen
);
1298 rt_show_net(this_cli
, n
, d
);
1302 cli_msg(8001, "Network not in table");
1307 * Documentation for functions declared inline in route.h
1312 * net_find - find a network entry
1313 * @tab: a routing table
1314 * @addr: address of the network
1315 * @len: length of the network prefix
1317 * net_find() looks up the given network in routing table @tab and
1318 * returns a pointer to its &net entry or %NULL if no such network
1321 static inline net
*net_find(rtable
*tab
, ip_addr addr
, unsigned len
)
1325 * net_get - obtain a network entry
1326 * @tab: a routing table
1327 * @addr: address of the network
1328 * @len: length of the network prefix
1330 * net_get() looks up the given network in routing table @tab and
1331 * returns a pointer to its &net entry. If no such entry exists, it's
1334 static inline net
*net_get(rtable
*tab
, ip_addr addr
, unsigned len
)
1338 * rte_cow - copy a route for writing
1339 * @r: a route entry to be copied
1341 * rte_cow() takes a &rte and prepares it for modification. The exact action
1342 * taken depends on the flags of the &rte -- if it's a temporary entry, it's
1343 * just returned unchanged, else a new temporary entry with the same contents
1346 * The primary use of this function is inside the filter machinery -- when
1347 * a filter wants to modify &rte contents (to change the preference or to
1348 * attach another set of attributes), it must ensure that the &rte is not
1349 * shared with anyone else (and especially that it isn't stored in any routing
1352 * Result: a pointer to the new writable &rte.
1354 static inline rte
* rte_cow(rte
*r
)