]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/rt-table.c
2 * BIRD -- Routing Tables
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
12 * Routing tables are probably the most important structures BIRD uses. They
13 * hold all the information about known networks, the associated routes and
16 * There are multiple routing tables (a primary one together with any
17 * number of secondary ones if requested by the configuration). Each table
18 * is basically a FIB containing entries describing the individual
19 * destination networks. For each network (represented by structure &net),
20 * there is a one-way linked list of route entries (&rte), the first entry
21 * on the list being the best one (i.e., the one we currently use
22 * for routing), the order of the other ones is undetermined.
24 * The &rte contains information specific to the route (preference, protocol
25 * metrics, time of last modification etc.) and a pointer to a &rta structure
26 * (see the route attribute module for a precise explanation) holding the
27 * remaining route attributes which are expected to be shared by multiple
28 * routes in order to conserve memory.
33 #include "nest/bird.h"
34 #include "nest/route.h"
35 #include "nest/protocol.h"
37 #include "nest/iface.h"
38 #include "lib/resource.h"
39 #include "lib/event.h"
40 #include "lib/string.h"
41 #include "conf/conf.h"
42 #include "filter/filter.h"
43 #include "lib/string.h"
44 #include "lib/alloca.h"
48 static slab
*rte_slab
;
49 static linpool
*rte_update_pool
;
51 static list routing_tables
;
53 static void rt_format_via(rte
*e
, byte
*via
);
56 rte_init(struct fib_node
*N
)
65 * rte_find - find a route
69 * The rte_find() function returns a route for destination @net
70 * which belongs has been defined by protocol @p.
73 rte_find(net
*net
, struct proto
*p
)
77 while (e
&& e
->attrs
->proto
!= p
)
83 * rte_get_temp - get a temporary &rte
84 * @a: attributes to assign to the new route (a &rta; in case it's
85 * un-cached, rte_update() will create a cached copy automatically)
87 * Create a temporary &rte and bind it with the attributes @a.
88 * Also set route preference to the default preference set for
94 rte
*e
= sl_alloc(rte_slab
);
98 e
->pref
= a
->proto
->preference
;
105 rte
*e
= sl_alloc(rte_slab
);
107 memcpy(e
, r
, sizeof(rte
));
108 e
->attrs
= rta_clone(r
->attrs
);
113 static int /* Actually better or at least as good as */
114 rte_better(rte
*new, rte
*old
)
116 int (*better
)(rte
*, rte
*);
120 if (new->pref
> old
->pref
)
122 if (new->pref
< old
->pref
)
124 if (new->attrs
->proto
->proto
!= old
->attrs
->proto
->proto
)
127 * If the user has configured protocol preferences, so that two different protocols
128 * have the same preference, try to break the tie by comparing addresses. Not too
129 * useful, but keeps the ordering of routes unambiguous.
131 return new->attrs
->proto
->proto
> old
->attrs
->proto
->proto
;
133 if (better
= new->attrs
->proto
->rte_better
)
134 return better(new, old
);
139 rte_trace(struct proto
*p
, rte
*e
, int dir
, char *msg
)
141 byte via
[STD_ADDRESS_P_LENGTH
+32];
143 rt_format_via(e
, via
);
144 log(L_TRACE
"%s %c %s %I/%d %s", p
->name
, dir
, msg
, e
->net
->n
.prefix
, e
->net
->n
.pxlen
, via
);
148 rte_trace_in(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
151 rte_trace(p
, e
, '>', msg
);
155 rte_trace_out(unsigned int flag
, struct proto
*p
, rte
*e
, char *msg
)
158 rte_trace(p
, e
, '<', msg
);
162 do_rte_announce(struct announce_hook
*a
, int type UNUSED
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
, int refeed
)
164 struct proto
*p
= a
->proto
;
165 struct filter
*filter
= p
->out_filter
;
166 struct proto_stats
*stats
= &p
->stats
;
172 /* The secondary direction of the pipe */
173 if (proto_is_pipe(p
) && (p
->table
!= a
->table
))
175 filter
= p
->in_filter
;
176 stats
= pipe_get_peer_stats(p
);
182 stats
->exp_updates_received
++;
184 char *drop_reason
= NULL
;
185 if ((ok
= p
->import_control
? p
->import_control(p
, &new, &tmpa
, rte_update_pool
) : 0) < 0)
187 stats
->exp_updates_rejected
++;
188 drop_reason
= "rejected by protocol";
191 rte_trace_out(D_FILTERS
, p
, new, "forced accept by protocol");
192 else if ((filter
== FILTER_REJECT
) ||
193 (filter
&& f_run(filter
, &new, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
195 stats
->exp_updates_filtered
++;
196 drop_reason
= "filtered out";
200 rte_trace_out(D_FILTERS
, p
, new, drop_reason
);
207 stats
->exp_withdraws_received
++;
210 * This is a tricky part - we don't know whether route 'old' was
211 * exported to protocol 'p' or was filtered by the export filter.
212 * We try tu run the export filter to know this to have a correct
213 * value in 'old' argument of rt_update (and proper filter value)
215 * FIXME - this is broken because 'configure soft' may change
216 * filters but keep routes. Refeed is expected to be called after
217 * change of the filters and with old == new, therefore we do not
218 * even try to run the filter on an old route, This may lead to
219 * 'spurious withdraws' but ensure that there are no 'missing
222 * This is not completely safe as there is a window between
223 * reconfiguration and the end of refeed - if a newly filtered
224 * route disappears during this period, proper withdraw is not
225 * sent (because old would be also filtered) and the route is
226 * not refeeded (because it disappeared before that).
231 if (filter
== FILTER_REJECT
)
235 ea_list
*tmpb
= p
->make_tmp_attrs
? p
->make_tmp_attrs(old
, rte_update_pool
) : NULL
;
236 ok
= p
->import_control
? p
->import_control(p
, &old
, &tmpb
, rte_update_pool
) : 0;
237 if (ok
< 0 || (!ok
&& filter
&& f_run(filter
, &old
, &tmpb
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
246 /* FIXME - This is broken because of incorrect 'old' value (see above) */
251 stats
->exp_updates_accepted
++;
253 stats
->exp_withdraws_accepted
++;
255 /* Hack: We do not decrease exp_routes during refeed, we instead
256 reset exp_routes at the start of refeed. */
262 if (p
->debug
& D_ROUTES
)
265 rte_trace_out(D_ROUTES
, p
, new, "replaced");
267 rte_trace_out(D_ROUTES
, p
, new, "added");
269 rte_trace_out(D_ROUTES
, p
, old
, "removed");
272 p
->rt_notify(p
, a
->table
, net
, NULL
, old
, NULL
);
278 t
->next
= new->attrs
->eattrs
;
279 p
->rt_notify(p
, a
->table
, net
, new, old
, tmpa
);
283 p
->rt_notify(p
, a
->table
, net
, new, old
, new->attrs
->eattrs
);
284 if (new && new != new0
) /* Discard temporary rte's */
286 if (old
&& old
!= old0
)
291 * rte_announce - announce a routing table change
292 * @tab: table the route has been added to
293 * @type: type of route announcement (RA_OPTIMAL or RA_ANY)
294 * @net: network in question
295 * @new: the new route to be announced
296 * @old: the previous route for the same network
297 * @tmpa: a list of temporary attributes belonging to the new route
299 * This function gets a routing table update and announces it
300 * to all protocols that acccepts given type of route announcement
301 * and are connected to the same table by their announcement hooks.
303 * Route announcement of type RA_OPTIMAL si generated when optimal
304 * route (in routing table @tab) changes. In that case @old stores the
307 * Route announcement of type RA_ANY si generated when any route (in
308 * routing table @tab) changes In that case @old stores the old route
309 * from the same protocol.
311 * For each appropriate protocol, we first call its import_control()
312 * hook which performs basic checks on the route (each protocol has a
313 * right to veto or force accept of the route before any filter is
314 * asked) and adds default values of attributes specific to the new
315 * protocol (metrics, tags etc.). Then it consults the protocol's
316 * export filter and if it accepts the route, the rt_notify() hook of
317 * the protocol gets called.
320 rte_announce(rtable
*tab
, unsigned type
, net
*net
, rte
*new, rte
*old
, ea_list
*tmpa
)
322 struct announce_hook
*a
;
324 if (type
== RA_OPTIMAL
)
327 new->attrs
->proto
->stats
.pref_routes
++;
329 old
->attrs
->proto
->stats
.pref_routes
--;
332 WALK_LIST(a
, tab
->hooks
)
334 ASSERT(a
->proto
->core_state
== FS_HAPPY
|| a
->proto
->core_state
== FS_FEEDING
);
335 if (a
->proto
->accept_ra_types
== type
)
336 do_rte_announce(a
, type
, net
, new, old
, tmpa
, 0);
346 if (ipa_nonzero(ipa_and(n
->n
.prefix
, ipa_not(ipa_mkmask(n
->n
.pxlen
)))))
348 log(L_BUG
"Ignoring bogus prefix %I/%d received via %s",
349 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->name
);
353 c
= ipa_classify_net(n
->n
.prefix
);
354 if ((c
< 0) || !(c
& IADDR_HOST
) || ((c
& IADDR_SCOPE_MASK
) <= SCOPE_LINK
))
356 log(L_WARN
"Ignoring bogus route %I/%d received via %s",
357 n
->n
.prefix
, n
->n
.pxlen
, e
->sender
->name
);
365 * rte_free - delete a &rte
366 * @e: &rte to be deleted
368 * rte_free() deletes the given &rte from the routing table it's linked to.
373 if (e
->attrs
->aflags
& RTAF_CACHED
)
375 sl_free(rte_slab
, e
);
379 rte_free_quick(rte
*e
)
382 sl_free(rte_slab
, e
);
386 rte_same(rte
*x
, rte
*y
)
389 x
->attrs
== y
->attrs
&&
390 x
->flags
== y
->flags
&&
391 x
->pflags
== y
->pflags
&&
392 x
->pref
== y
->pref
&&
393 (!x
->attrs
->proto
->rte_same
|| x
->attrs
->proto
->rte_same(x
, y
));
397 rte_recalculate(rtable
*table
, net
*net
, struct proto
*p
, struct proto
*src
, rte
*new, ea_list
*tmpa
)
399 struct proto_stats
*stats
= &p
->stats
;
400 rte
*old_best
= net
->routes
;
405 if (proto_is_pipe(p
) && (p
->table
== table
))
406 stats
= pipe_get_peer_stats(p
);
409 k
= &net
->routes
; /* Find and remove original route from the same protocol */
412 if (old
->attrs
->proto
== src
)
414 /* If there is the same route in the routing table but from
415 * a different sender, then there are two paths from the
416 * source protocol to this routing table through transparent
417 * pipes, which is not allowed.
419 * We log that and ignore the route. If it is withdraw, we
420 * ignore it completely (there might be 'spurious withdraws',
421 * see FIXME in do_rte_announce())
423 if (old
->sender
!= p
)
427 log(L_ERR
"Pipe collision detected when sending %I/%d to table %s",
428 net
->n
.prefix
, net
->n
.pxlen
, table
->name
);
434 if (new && rte_same(old
, new))
436 /* No changes, ignore the new route */
437 stats
->imp_updates_ignored
++;
438 rte_trace_in(D_ROUTES
, p
, new, "ignored");
441 /* lastmod is used internally by RIP as the last time
442 when the route was received. */
443 if (src
->proto
== &proto_rip
)
456 stats
->imp_withdraws_ignored
++;
461 stats
->imp_updates_accepted
++;
463 stats
->imp_withdraws_accepted
++;
470 rte_announce(table
, RA_ANY
, net
, new, old
, tmpa
);
473 if (new && rte_better(new, old_best
))
475 /* The first case - the new route is cleary optimal, we link it
476 at the first position and announce it */
478 rte_trace_in(D_ROUTES
, p
, new, "added [best]");
479 rte_announce(table
, RA_OPTIMAL
, net
, new, old_best
, tmpa
);
480 new->next
= net
->routes
;
483 else if (old
== old_best
)
485 /* The second case - the old best route disappeared, we add the
486 new route (if we have any) to the list (we don't care about
487 position) and then we elect the new optimal route and relink
488 that route at the first position and announce it. New optimal
489 route might be NULL if there is no more routes */
491 /* Add the new route to the list */
494 rte_trace_in(D_ROUTES
, p
, new, "added");
495 new->next
= net
->routes
;
499 /* Find new optimal route */
501 for (s
=net
->routes
; s
; s
=s
->next
)
502 if (rte_better(s
, r
))
505 /* Announce optimal route */
506 rte_announce(table
, RA_OPTIMAL
, net
, r
, old_best
, tmpa
);
508 /* And relink it (if there is any) */
521 r
->next
= net
->routes
;
524 else if (table
->gc_counter
++ >= table
->config
->gc_max_ops
&&
525 table
->gc_time
+ table
->config
->gc_min_time
<= now
)
526 ev_schedule(table
->gc_event
);
530 /* The third case - the new route is not better than the old
531 best route (therefore old_best != NULL) and the old best
532 route was not removed (therefore old_best == net->routes).
533 We just link the new route after the old best route. */
535 ASSERT(net
->routes
!= NULL
);
536 new->next
= net
->routes
->next
;
537 net
->routes
->next
= new;
538 rte_trace_in(D_ROUTES
, p
, new, "added");
541 /* Log the route removal */
542 if (!new && old
&& (p
->debug
& D_ROUTES
))
545 rte_trace_in(D_ROUTES
, p
, old
, "removed");
546 else if (net
->routes
)
547 rte_trace_in(D_ROUTES
, p
, old
, "removed [replaced]");
549 rte_trace_in(D_ROUTES
, p
, old
, "removed [sole]");
555 p
->rte_remove(net
, old
);
562 p
->rte_insert(net
, new);
566 static int rte_update_nest_cnt
; /* Nesting counter to allow recursive updates */
569 rte_update_lock(void)
571 rte_update_nest_cnt
++;
575 rte_update_unlock(void)
577 if (!--rte_update_nest_cnt
)
578 lp_flush(rte_update_pool
);
582 * rte_update - enter a new update to a routing table
583 * @table: table to be updated
585 * @p: protocol submitting the update
586 * @src: protocol originating the update
587 * @new: a &rte representing the new route or %NULL for route removal.
589 * This function is called by the routing protocols whenever they discover
590 * a new route or wish to update/remove an existing route. The right announcement
591 * sequence is to build route attributes first (either un-cached with @aflags set
592 * to zero or a cached one using rta_lookup(); in this case please note that
593 * you need to increase the use count of the attributes yourself by calling
594 * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
595 * the appropriate data and finally submit the new &rte by calling rte_update().
597 * @src specifies the protocol that originally created the route and the meaning
598 * of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
599 * same value as @new->attrs->proto. @p specifies the protocol that called
600 * rte_update(). In most cases it is the same protocol as @src. rte_update()
601 * stores @p in @new->sender;
603 * When rte_update() gets any route, it automatically validates it (checks,
604 * whether the network and next hop address are valid IP addresses and also
605 * whether a normal routing protocol doesn't try to smuggle a host or link
606 * scope route to the table), converts all protocol dependent attributes stored
607 * in the &rte to temporary extended attributes, consults import filters of the
608 * protocol to see if the route should be accepted and/or its attributes modified,
609 * stores the temporary attributes back to the &rte.
611 * Now, having a "public" version of the route, we
612 * automatically find any old route defined by the protocol @src
613 * for network @n, replace it by the new one (or removing it if @new is %NULL),
614 * recalculate the optimal route for this destination and finally broadcast
615 * the change (if any) to all routing protocols by calling rte_announce().
617 * All memory used for attribute lists and other temporary allocations is taken
618 * from a special linear pool @rte_update_pool and freed when rte_update()
623 rte_update(rtable
*table
, net
*net
, struct proto
*p
, struct proto
*src
, rte
*new)
625 ea_list
*tmpa
= NULL
;
626 struct proto_stats
*stats
= &p
->stats
;
629 if (proto_is_pipe(p
) && (p
->table
== table
))
630 stats
= pipe_get_peer_stats(p
);
637 struct filter
*filter
= p
->in_filter
;
639 /* Do not filter routes going through the pipe,
640 they are filtered in the export filter only. */
642 if (proto_is_pipe(p
))
643 filter
= FILTER_ACCEPT
;
646 stats
->imp_updates_received
++;
647 if (!rte_validate(new))
649 rte_trace_in(D_FILTERS
, p
, new, "invalid");
650 stats
->imp_updates_invalid
++;
653 if (filter
== FILTER_REJECT
)
655 stats
->imp_updates_filtered
++;
656 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
659 if (src
->make_tmp_attrs
)
660 tmpa
= src
->make_tmp_attrs(new, rte_update_pool
);
663 ea_list
*old_tmpa
= tmpa
;
664 int fr
= f_run(filter
, &new, &tmpa
, rte_update_pool
, 0);
667 stats
->imp_updates_filtered
++;
668 rte_trace_in(D_FILTERS
, p
, new, "filtered out");
671 if (tmpa
!= old_tmpa
&& src
->store_tmp_attrs
)
672 src
->store_tmp_attrs(new, tmpa
);
674 if (!(new->attrs
->aflags
& RTAF_CACHED
)) /* Need to copy attributes */
675 new->attrs
= rta_lookup(new->attrs
);
676 new->flags
|= REF_COW
;
679 stats
->imp_withdraws_received
++;
681 rte_recalculate(table
, net
, p
, src
, new, tmpa
);
687 rte_recalculate(table
, net
, p
, src
, NULL
, NULL
);
692 rte_discard(rtable
*t
, rte
*old
) /* Non-filtered route deletion, used during garbage collection */
695 rte_recalculate(t
, old
->net
, old
->sender
, old
->attrs
->proto
, NULL
, NULL
);
700 * rte_dump - dump a route
701 * @e: &rte to be dumped
703 * This functions dumps contents of a &rte to debug output.
710 debug("%-1I/%2d ", n
->n
.prefix
, n
->n
.pxlen
);
713 debug("KF=%02x PF=%02x pref=%d lm=%d ", n
->n
.flags
, e
->pflags
, e
->pref
, now
-e
->lastmod
);
715 if (e
->attrs
->proto
->proto
->dump_attrs
)
716 e
->attrs
->proto
->proto
->dump_attrs(e
);
721 * rt_dump - dump a routing table
722 * @t: routing table to be dumped
724 * This function dumps contents of a given routing table to debug output.
731 struct announce_hook
*a
;
733 debug("Dump of routing table <%s>\n", t
->name
);
737 FIB_WALK(&t
->fib
, fn
)
740 for(e
=n
->routes
; e
; e
=e
->next
)
744 WALK_LIST(a
, t
->hooks
)
745 debug("\tAnnounces routes to protocol %s\n", a
->proto
->name
);
750 * rt_dump_all - dump all routing tables
752 * This function dumps contents of all routing tables to debug output.
759 WALK_LIST(t
, routing_tables
)
768 DBG("Entered routing table garbage collector for %s after %d seconds and %d deletes\n",
769 t
->name
, (int)(now
- t
->gc_time
), t
->gc_counter
);
774 rt_setup(pool
*p
, rtable
*t
, char *name
, struct rtable_config
*cf
)
776 bzero(t
, sizeof(*t
));
777 fib_init(&t
->fib
, p
, sizeof(net
), 0, rte_init
);
780 init_list(&t
->hooks
);
783 t
->gc_event
= ev_new(p
);
784 t
->gc_event
->hook
= rt_gc
;
785 t
->gc_event
->data
= t
;
791 * rt_init - initialize routing tables
793 * This function is called during BIRD startup. It initializes the
794 * routing table module.
800 rt_table_pool
= rp_new(&root_pool
, "Routing tables");
801 rte_update_pool
= lp_new(rt_table_pool
, 4080);
802 rte_slab
= sl_new(rt_table_pool
, sizeof(rte
));
803 init_list(&routing_tables
);
807 * rt_prune - prune a routing table
808 * @tab: routing table to be pruned
810 * This function is called whenever a protocol shuts down. It scans
811 * the routing table and removes all routes belonging to inactive
812 * protocols and also stale network entries.
815 rt_prune(rtable
*tab
)
817 struct fib_iterator fit
;
818 int rcnt
= 0, rdel
= 0, ncnt
= 0, ndel
= 0;
820 DBG("Pruning route table %s\n", tab
->name
);
822 fib_check(&tab
->fib
);
824 FIB_ITERATE_INIT(&fit
, &tab
->fib
);
826 FIB_ITERATE_START(&tab
->fib
, &fit
, f
)
832 for (e
=n
->routes
; e
; e
=e
->next
, rcnt
++)
833 if (e
->sender
->core_state
!= FS_HAPPY
&&
834 e
->sender
->core_state
!= FS_FEEDING
)
840 if (!n
->routes
) /* Orphaned FIB entry? */
842 FIB_ITERATE_PUT(&fit
, f
);
843 fib_delete(&tab
->fib
, f
);
849 DBG("Pruned %d of %d routes and %d of %d networks\n", rdel
, rcnt
, ndel
, ncnt
);
851 fib_check(&tab
->fib
);
858 * rt_prune_all - prune all routing tables
860 * This function calls rt_prune() for all known routing tables.
867 WALK_LIST(t
, routing_tables
)
871 struct rtable_config
*
872 rt_new_table(struct symbol
*s
)
874 struct rtable_config
*c
= cfg_allocz(sizeof(struct rtable_config
));
876 cf_define_symbol(s
, SYM_TABLE
, c
);
878 add_tail(&new_config
->tables
, &c
->n
);
879 c
->gc_max_ops
= 1000;
885 rt_preconfig(struct config
*c
)
887 struct symbol
*s
= cf_find_symbol("master");
889 init_list(&c
->tables
);
890 c
->master_rtc
= rt_new_table(s
);
894 * rt_lock_table - lock a routing table
895 * @r: routing table to be locked
897 * Lock a routing table, because it's in use by a protocol,
898 * preventing it from being freed when it gets undefined in a new
902 rt_lock_table(rtable
*r
)
908 * rt_unlock_table - unlock a routing table
909 * @r: routing table to be unlocked
911 * Unlock a routing table formerly locked by rt_lock_table(),
912 * that is decrease its use count and delete it if it's scheduled
913 * for deletion by configuration changes.
916 rt_unlock_table(rtable
*r
)
918 if (!--r
->use_count
&& r
->deleted
)
920 struct config
*conf
= r
->deleted
;
921 DBG("Deleting routing table %s\n", r
->name
);
925 config_del_obstacle(conf
);
930 * rt_commit - commit new routing table configuration
931 * @new: new configuration
932 * @old: original configuration or %NULL if it's boot time config
934 * Scan differences between @old and @new configuration and modify
935 * the routing tables according to these changes. If @new defines a
936 * previously unknown table, create it, if it omits a table existing
937 * in @old, schedule it for deletion (it gets deleted when all protocols
938 * disconnect from it by calling rt_unlock_table()), if it exists
939 * in both configurations, leave it unchanged.
942 rt_commit(struct config
*new, struct config
*old
)
944 struct rtable_config
*o
, *r
;
949 WALK_LIST(o
, old
->tables
)
951 rtable
*ot
= o
->table
;
954 struct symbol
*sym
= cf_find_symbol(o
->name
);
955 if (sym
&& sym
->class == SYM_TABLE
&& !new->shutdown
)
957 DBG("\t%s: same\n", o
->name
);
965 DBG("\t%s: deleted\n", o
->name
);
967 config_add_obstacle(old
);
975 WALK_LIST(r
, new->tables
)
978 rtable
*t
= mb_alloc(rt_table_pool
, sizeof(struct rtable
));
979 DBG("\t%s: created\n", r
->name
);
980 rt_setup(rt_table_pool
, t
, r
->name
, r
);
981 add_tail(&routing_tables
, &t
->n
);
988 do_feed_baby(struct proto
*p
, int type
, struct announce_hook
*h
, net
*n
, rte
*e
)
990 struct proto
*q
= e
->attrs
->proto
;
994 tmpa
= q
->make_tmp_attrs
? q
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
995 do_rte_announce(h
, type
, n
, e
, p
->refeeding
? e
: NULL
, tmpa
, p
->refeeding
);
1000 * rt_feed_baby - advertise routes to a new protocol
1001 * @p: protocol to be fed
1003 * This function performs one pass of advertisement of routes to a newly
1004 * initialized protocol. It's called by the protocol code as long as it
1005 * has something to do. (We avoid transferring all the routes in single
1006 * pass in order not to monopolize CPU time.)
1009 rt_feed_baby(struct proto
*p
)
1011 struct announce_hook
*h
;
1012 struct fib_iterator
*fit
;
1015 if (!p
->feed_ahook
) /* Need to initialize first */
1019 DBG("Announcing routes to new protocol %s\n", p
->name
);
1020 p
->feed_ahook
= p
->ahooks
;
1021 fit
= p
->feed_iterator
= mb_alloc(p
->pool
, sizeof(struct fib_iterator
));
1024 fit
= p
->feed_iterator
;
1028 FIB_ITERATE_START(&h
->table
->fib
, fit
, fn
)
1030 net
*n
= (net
*) fn
;
1034 FIB_ITERATE_PUT(fit
, fn
);
1038 if (p
->accept_ra_types
== RA_OPTIMAL
)
1041 if (p
->core_state
!= FS_FEEDING
)
1042 return 1; /* In the meantime, the protocol fell down. */
1043 do_feed_baby(p
, RA_OPTIMAL
, h
, n
, e
);
1047 if (p
->accept_ra_types
== RA_ANY
)
1048 for(e
= n
->routes
; e
!= NULL
; e
= e
->next
)
1050 if (p
->core_state
!= FS_FEEDING
)
1051 return 1; /* In the meantime, the protocol fell down. */
1052 do_feed_baby(p
, RA_ANY
, h
, n
, e
);
1056 FIB_ITERATE_END(fn
);
1057 p
->feed_ahook
= h
->next
;
1060 mb_free(p
->feed_iterator
);
1061 p
->feed_iterator
= NULL
;
1067 FIB_ITERATE_INIT(fit
, &h
->table
->fib
);
1072 * rt_feed_baby_abort - abort protocol feeding
1075 * This function is called by the protocol code when the protocol
1076 * stops or ceases to exist before the last iteration of rt_feed_baby()
1080 rt_feed_baby_abort(struct proto
*p
)
1084 /* Unlink the iterator and exit */
1085 fit_get(&p
->feed_ahook
->table
->fib
, p
->feed_iterator
);
1086 p
->feed_ahook
= NULL
;
1095 rt_format_via(rte
*e
, byte
*via
)
1101 case RTD_ROUTER
: bsprintf(via
, "via %I on %s", a
->gw
, a
->iface
->name
); break;
1102 case RTD_DEVICE
: bsprintf(via
, "dev %s", a
->iface
->name
); break;
1103 case RTD_BLACKHOLE
: bsprintf(via
, "blackhole"); break;
1104 case RTD_UNREACHABLE
: bsprintf(via
, "unreachable"); break;
1105 case RTD_PROHIBIT
: bsprintf(via
, "prohibited"); break;
1106 default: bsprintf(via
, "???");
1111 rt_show_rte(struct cli
*c
, byte
*ia
, rte
*e
, struct rt_show_data
*d
, ea_list
*tmpa
)
1113 byte via
[STD_ADDRESS_P_LENGTH
+32], from
[STD_ADDRESS_P_LENGTH
+6];
1114 byte tm
[TM_DATETIME_BUFFER_SIZE
], info
[256];
1116 int primary
= (e
->net
->routes
== e
);
1118 rt_format_via(e
, via
);
1119 tm_format_datetime(tm
, &config
->tf_route
, e
->lastmod
);
1120 if (ipa_nonzero(a
->from
) && !ipa_equal(a
->from
, a
->gw
))
1121 bsprintf(from
, " from %I", a
->from
);
1124 if (a
->proto
->proto
->get_route_info
|| d
->verbose
)
1126 /* Need to normalize the extended attributes */
1128 t
= ea_append(t
, a
->eattrs
);
1129 tmpa
= alloca(ea_scan(t
));
1133 if (a
->proto
->proto
->get_route_info
)
1134 a
->proto
->proto
->get_route_info(e
, info
, tmpa
);
1136 bsprintf(info
, " (%d)", e
->pref
);
1137 cli_printf(c
, -1007, "%-18s %s [%s %s%s]%s%s", ia
, via
, a
->proto
->name
,
1138 tm
, from
, primary
? " *" : "", info
);
1140 rta_show(c
, a
, tmpa
);
1144 rt_show_net(struct cli
*c
, net
*n
, struct rt_show_data
*d
)
1147 byte ia
[STD_ADDRESS_P_LENGTH
+8];
1150 bsprintf(ia
, "%I/%d", n
->n
.prefix
, n
->n
.pxlen
);
1153 for(e
=n
->routes
; e
; e
=e
->next
)
1155 struct ea_list
*tmpa
, *old_tmpa
;
1156 struct proto
*p0
= e
->attrs
->proto
;
1157 struct proto
*p1
= d
->export_protocol
;
1158 struct proto
*p2
= d
->show_protocol
;
1161 rte_update_lock(); /* We use the update buffer for filtering */
1162 old_tmpa
= tmpa
= p0
->make_tmp_attrs
? p0
->make_tmp_attrs(e
, rte_update_pool
) : NULL
;
1163 ok
= (d
->filter
== FILTER_ACCEPT
|| f_run(d
->filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) <= F_ACCEPT
);
1164 if (p2
&& p2
!= p0
) ok
= 0;
1165 if (ok
&& d
->export_mode
)
1168 if ((ic
= p1
->import_control
? p1
->import_control(p1
, &e
, &tmpa
, rte_update_pool
) : 0) < 0)
1170 else if (!ic
&& d
->export_mode
> 1)
1172 /* FIXME - this shows what should be exported according
1173 to current filters, but not what was really exported.
1174 'configure soft' command may change the export filter
1175 and do not update routes */
1177 if ((p1
->out_filter
== FILTER_REJECT
) ||
1178 (p1
->out_filter
&& f_run(p1
->out_filter
, &e
, &tmpa
, rte_update_pool
, FF_FORCE_TMPATTR
) > F_ACCEPT
))
1186 rt_show_rte(c
, ia
, e
, d
, tmpa
);
1191 rte_update_unlock();
1192 if (d
->primary_only
)
1198 rt_show_cont(struct cli
*c
)
1200 struct rt_show_data
*d
= c
->rover
;
1206 struct fib
*fib
= &d
->table
->fib
;
1207 struct fib_iterator
*it
= &d
->fit
;
1209 FIB_ITERATE_START(fib
, it
, f
)
1212 if (d
->running_on_config
&& d
->running_on_config
!= config
)
1214 cli_printf(c
, 8004, "Stopped due to reconfiguration");
1217 if (d
->export_protocol
&&
1218 d
->export_protocol
->core_state
!= FS_HAPPY
&&
1219 d
->export_protocol
->core_state
!= FS_FEEDING
)
1221 cli_printf(c
, 8005, "Protocol is down");
1226 FIB_ITERATE_PUT(it
, f
);
1229 rt_show_net(c
, n
, d
);
1233 cli_printf(c
, 14, "%d of %d routes for %d networks", d
->show_counter
, d
->rt_counter
, d
->net_counter
);
1235 cli_printf(c
, 0, "");
1237 c
->cont
= c
->cleanup
= NULL
;
1241 rt_show_cleanup(struct cli
*c
)
1243 struct rt_show_data
*d
= c
->rover
;
1245 /* Unlink the iterator */
1246 fit_get(&d
->table
->fib
, &d
->fit
);
1250 rt_show(struct rt_show_data
*d
)
1254 if (d
->pxlen
== 256)
1256 FIB_ITERATE_INIT(&d
->fit
, &d
->table
->fib
);
1257 this_cli
->cont
= rt_show_cont
;
1258 this_cli
->cleanup
= rt_show_cleanup
;
1259 this_cli
->rover
= d
;
1264 n
= fib_route(&d
->table
->fib
, d
->prefix
, d
->pxlen
);
1266 n
= fib_find(&d
->table
->fib
, &d
->prefix
, d
->pxlen
);
1269 rt_show_net(this_cli
, n
, d
);
1273 cli_msg(8001, "Network not in table");
1278 * Documentation for functions declared inline in route.h
1283 * net_find - find a network entry
1284 * @tab: a routing table
1285 * @addr: address of the network
1286 * @len: length of the network prefix
1288 * net_find() looks up the given network in routing table @tab and
1289 * returns a pointer to its &net entry or %NULL if no such network
1292 static inline net
*net_find(rtable
*tab
, ip_addr addr
, unsigned len
)
1296 * net_get - obtain a network entry
1297 * @tab: a routing table
1298 * @addr: address of the network
1299 * @len: length of the network prefix
1301 * net_get() looks up the given network in routing table @tab and
1302 * returns a pointer to its &net entry. If no such entry exists, it's
1305 static inline net
*net_get(rtable
*tab
, ip_addr addr
, unsigned len
)
1309 * rte_cow - copy a route for writing
1310 * @r: a route entry to be copied
1312 * rte_cow() takes a &rte and prepares it for modification. The exact action
1313 * taken depends on the flags of the &rte -- if it's a temporary entry, it's
1314 * just returned unchanged, else a new temporary entry with the same contents
1317 * The primary use of this function is inside the filter machinery -- when
1318 * a filter wants to modify &rte contents (to change the preference or to
1319 * attach another set of attributes), it must ensure that the &rte is not
1320 * shared with anyone else (and especially that it isn't stored in any routing
1323 * Result: a pointer to the new writable &rte.
1325 static inline rte
* rte_cow(rte
*r
)