4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
11 #include "nest/bird.h"
12 #include "nest/protocol.h"
13 #include "lib/resource.h"
14 #include "lib/lists.h"
15 #include "lib/event.h"
16 #include "lib/string.h"
17 #include "conf/conf.h"
18 #include "nest/route.h"
19 #include "nest/iface.h"
21 #include "filter/filter.h"
25 static list protocol_list
;
26 static list proto_list
;
28 #define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0)
30 list active_proto_list
;
31 static list inactive_proto_list
;
32 static list initial_proto_list
;
33 static list flush_proto_list
;
34 static struct proto
*initial_device_proto
;
36 static event
*proto_flush_event
;
37 static timer
*proto_shutdown_timer
;
39 static char *p_states
[] = { "DOWN", "START", "UP", "STOP" };
40 static char *c_states
[] = { "HUNGRY", "FEEDING", "HAPPY", "FLUSHING" };
42 static void proto_flush_loop(void *);
43 static void proto_shutdown_loop(struct timer
*);
44 static void proto_rethink_goal(struct proto
*p
);
45 static char *proto_state_name(struct proto
*p
);
48 proto_enqueue(list
*l
, struct proto
*p
)
51 p
->last_state_change
= now
;
55 proto_relink(struct proto
*p
)
59 if (p
->debug
& D_STATES
)
61 char *name
= proto_state_name(p
);
62 if (name
!= p
->last_state_name_announced
)
64 p
->last_state_name_announced
= name
;
65 PD(p
, "State changed to %s", proto_state_name(p
));
69 p
->last_state_name_announced
= NULL
;
71 switch (p
->core_state
)
74 l
= &inactive_proto_list
;
78 l
= &active_proto_list
;
81 l
= &flush_proto_list
;
90 * proto_new - create a new protocol instance
91 * @c: protocol configuration
92 * @size: size of protocol data structure (each protocol instance is represented by
93 * a structure starting with generic part [struct &proto] and continued
94 * with data specific to the protocol)
96 * When a new configuration has been read in, the core code starts
97 * initializing all the protocol instances configured by calling their
98 * init() hooks with the corresponding instance configuration. The initialization
99 * code of the protocol is expected to create a new instance according to the
100 * configuration by calling this function and then modifying the default settings
101 * to values wanted by the protocol.
104 proto_new(struct proto_config
*c
, unsigned size
)
106 struct protocol
*pr
= c
->protocol
;
107 struct proto
*p
= mb_allocz(proto_pool
, size
);
111 p
->mrtdump
= c
->mrtdump
;
113 p
->preference
= c
->preference
;
114 p
->disabled
= c
->disabled
;
116 p
->table
= c
->table
->table
;
117 p
->hash_key
= random_u32();
123 proto_init_instance(struct proto
*p
)
125 /* Here we cannot use p->cf->name since it won't survive reconfiguration */
126 p
->pool
= rp_new(proto_pool
, p
->proto
->name
);
127 p
->attn
= ev_new(p
->pool
);
130 if (! p
->proto
->multitable
)
131 rt_lock_table(p
->table
);
134 extern pool
*rt_table_pool
;
136 * proto_add_announce_hook - connect protocol to a routing table
137 * @p: protocol instance
138 * @t: routing table to connect to
139 * @stats: per-table protocol statistics
141 * This function creates a connection between the protocol instance @p
142 * and the routing table @t, making the protocol hear all changes in
145 * The announce hook is linked in the protocol ahook list and, if the
146 * protocol accepts routes, also in the table ahook list. Announce
147 * hooks are allocated from the routing table resource pool, they are
148 * unlinked from the table ahook list after the protocol went down,
149 * (in proto_schedule_flush()) and they are automatically freed after the
150 * protocol is flushed (in proto_fell_down()).
152 * Unless you want to listen to multiple routing tables (as the Pipe
153 * protocol does), you needn't to worry about this function since the
154 * connection to the protocol's primary routing table is initialized
155 * automatically by the core code.
157 struct announce_hook
*
158 proto_add_announce_hook(struct proto
*p
, struct rtable
*t
, struct proto_stats
*stats
)
160 struct announce_hook
*h
;
162 DBG("Connecting protocol %s to table %s\n", p
->name
, t
->name
);
163 PD(p
, "Connected to table %s", t
->name
);
165 h
= mb_allocz(rt_table_pool
, sizeof(struct announce_hook
));
174 add_tail(&t
->hooks
, &h
->n
);
179 * proto_find_announce_hook - find announce hooks
180 * @p: protocol instance
183 * Returns pointer to announce hook or NULL
185 struct announce_hook
*
186 proto_find_announce_hook(struct proto
*p
, struct rtable
*t
)
188 struct announce_hook
*a
;
190 for (a
= p
->ahooks
; a
; a
= a
->next
)
198 proto_unlink_ahooks(struct proto
*p
)
200 struct announce_hook
*h
;
203 for(h
=p
->ahooks
; h
; h
=h
->next
)
208 proto_free_ahooks(struct proto
*p
)
210 struct announce_hook
*h
, *hn
;
212 for(h
= p
->ahooks
; h
; h
= hn
)
219 p
->main_ahook
= NULL
;
224 * proto_config_new - create a new protocol configuration
225 * @pr: protocol the configuration will belong to
226 * @size: size of the structure including generic data
227 * @class: SYM_PROTO or SYM_TEMPLATE
229 * Whenever the configuration file says that a new instance
230 * of a routing protocol should be created, the parser calls
231 * proto_config_new() to create a configuration entry for this
232 * instance (a structure staring with the &proto_config header
233 * containing all the generic items followed by protocol-specific
234 * ones). Also, the configuration entry gets added to the list
235 * of protocol instances kept in the configuration.
237 * The function is also used to create protocol templates (when class
238 * SYM_TEMPLATE is specified), the only difference is that templates
239 * are not added to the list of protocol instances and therefore not
240 * initialized during protos_commit()).
243 proto_config_new(struct protocol
*pr
, unsigned size
, int class)
245 struct proto_config
*c
= cfg_allocz(size
);
247 if (class == SYM_PROTO
)
248 add_tail(&new_config
->protos
, &c
->n
);
249 c
->global
= new_config
;
252 c
->preference
= pr
->preference
;
254 c
->out_filter
= FILTER_REJECT
;
255 c
->table
= c
->global
->master_rtc
;
256 c
->debug
= new_config
->proto_default_debug
;
257 c
->mrtdump
= new_config
->proto_default_mrtdump
;
262 * proto_copy_config - copy a protocol configuration
263 * @dest: destination protocol configuration
264 * @src: source protocol configuration
266 * Whenever a new instance of a routing protocol is created from the
267 * template, proto_copy_config() is called to copy a content of
268 * the source protocol configuration to the new protocol configuration.
269 * Name, class and a node in protos list of @dest are kept intact.
270 * copy_config() protocol hook is used to copy protocol-specific data.
273 proto_copy_config(struct proto_config
*dest
, struct proto_config
*src
)
279 if (dest
->protocol
!= src
->protocol
)
280 cf_error("Can't copy configuration from a different protocol type");
282 if (dest
->protocol
->copy_config
== NULL
)
283 cf_error("Inheriting configuration for %s is not supported", src
->protocol
->name
);
285 DBG("Copying configuration from %s to %s\n", src
->name
, dest
->name
);
288 * Copy struct proto_config here. Keep original node, class and name.
289 * protocol-specific config copy is handled by protocol copy_config() hook
293 old_class
= dest
->class;
294 old_name
= dest
->name
;
296 memcpy(dest
, src
, sizeof(struct proto_config
));
299 dest
->class = old_class
;
300 dest
->name
= old_name
;
302 dest
->protocol
->copy_config(dest
, src
);
306 * protos_preconfig - pre-configuration processing
307 * @c: new configuration
309 * This function calls the preconfig() hooks of all routing
310 * protocols available to prepare them for reading of the new
314 protos_preconfig(struct config
*c
)
318 init_list(&c
->protos
);
319 DBG("Protocol preconfig:");
320 WALK_LIST(p
, protocol_list
)
331 * protos_postconfig - post-configuration processing
332 * @c: new configuration
334 * This function calls the postconfig() hooks of all protocol
335 * instances specified in configuration @c. The hooks are not
336 * called for protocol templates.
339 protos_postconfig(struct config
*c
)
341 struct proto_config
*x
;
344 DBG("Protocol postconfig:");
345 WALK_LIST(x
, c
->protos
)
356 extern struct protocol proto_unix_iface
;
358 static struct proto
*
359 proto_init(struct proto_config
*c
)
361 struct protocol
*p
= c
->protocol
;
362 struct proto
*q
= p
->init(c
);
364 q
->proto_state
= PS_DOWN
;
365 q
->core_state
= FS_HUNGRY
;
366 proto_enqueue(&initial_proto_list
, q
);
367 if (p
== &proto_unix_iface
)
368 initial_device_proto
= q
;
370 add_tail(&proto_list
, &q
->glob_node
);
371 PD(q
, "Initializing%s", q
->disabled
? " [disabled]" : "");
375 int proto_reconfig_type
; /* Hack to propagate type info to pipe reconfigure hook */
378 proto_reconfigure(struct proto
*p
, struct proto_config
*oc
, struct proto_config
*nc
, int type
)
380 struct announce_hook
*ah
= p
->main_ahook
;
381 /* If the protocol is DOWN, we just restart it */
382 if (p
->proto_state
== PS_DOWN
)
385 /* If there is a too big change in core attributes, ... */
386 if ((nc
->protocol
!= oc
->protocol
) ||
387 (nc
->disabled
!= p
->disabled
) ||
388 (nc
->table
->table
!= oc
->table
->table
))
391 p
->debug
= nc
->debug
;
392 p
->mrtdump
= nc
->mrtdump
;
393 proto_reconfig_type
= type
;
395 /* Execute protocol specific reconfigure hook */
396 if (! (p
->proto
->reconfigure
&& p
->proto
->reconfigure(p
, nc
)))
399 DBG("\t%s: same\n", oc
->name
);
400 PD(p
, "Reconfigured");
403 p
->preference
= nc
->preference
;
406 /* Multitable protocols handle rest in their reconfigure hooks */
407 if (p
->proto
->multitable
)
410 /* Update filters and limits in the main announce hook
411 Note that this also resets limit state */
414 ah
->in_filter
= nc
->in_filter
;
415 ah
->out_filter
= nc
->out_filter
;
416 ah
->rx_limit
= nc
->rx_limit
;
417 ah
->in_limit
= nc
->in_limit
;
418 ah
->out_limit
= nc
->out_limit
;
419 ah
->in_keep_filtered
= nc
->in_keep_filtered
;
421 if (p
->proto_state
== PS_UP
) /* Recheck export/import/receive limit */
423 struct proto_stats
*stats
= ah
->stats
;
424 struct proto_limit
*l
= ah
->in_limit
;
425 u32 all_routes
= stats
->imp_routes
+ stats
->filt_routes
;
427 if (l
&& (stats
->imp_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_IN
, stats
->imp_routes
);
431 if (l
&& ( all_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_RX
, all_routes
);
435 if (l
&& ( stats
->exp_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_OUT
, stats
->exp_routes
);
439 /* Update routes when filters changed. If the protocol in not UP,
440 it has no routes and we can ignore such changes */
441 if ((p
->proto_state
!= PS_UP
) || (type
== RECONFIG_SOFT
))
444 int import_changed
= ! filter_same(nc
->in_filter
, oc
->in_filter
);
445 int export_changed
= ! filter_same(nc
->out_filter
, oc
->out_filter
);
447 /* We treat a change in preferences by reimporting routes */
448 if (nc
->preference
!= oc
->preference
)
451 if (import_changed
|| export_changed
)
452 log(L_INFO
"Reloading protocol %s", p
->name
);
454 /* If import filter changed, call reload hook */
455 if (import_changed
&& ! (p
->reload_routes
&& p
->reload_routes(p
)))
457 /* Now, the protocol is reconfigured. But route reload failed
458 and we have to do regular protocol restart. */
459 log(L_INFO
"Restarting protocol %s", p
->name
);
461 p
->down_code
= PDC_CF_RESTART
;
462 proto_rethink_goal(p
);
464 proto_rethink_goal(p
);
469 proto_request_feeding(p
);
475 * protos_commit - commit new protocol configuration
476 * @new: new configuration
477 * @old: old configuration or %NULL if it's boot time config
478 * @force_reconfig: force restart of all protocols (used for example
479 * when the router ID changes)
480 * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
482 * Scan differences between @old and @new configuration and adjust all
483 * protocol instances to conform to the new configuration.
485 * When a protocol exists in the new configuration, but it doesn't in the
486 * original one, it's immediately started. When a collision with the other
487 * running protocol would arise, the new protocol will be temporarily stopped
488 * by the locking mechanism.
490 * When a protocol exists in the old configuration, but it doesn't in the
491 * new one, it's shut down and deleted after the shutdown completes.
493 * When a protocol exists in both configurations, the core decides
494 * whether it's possible to reconfigure it dynamically - it checks all
495 * the core properties of the protocol (changes in filters are ignored
496 * if type is RECONFIG_SOFT) and if they match, it asks the
497 * reconfigure() hook of the protocol to see if the protocol is able
498 * to switch to the new configuration. If it isn't possible, the
499 * protocol is shut down and a new instance is started with the new
500 * configuration after the shutdown is completed.
503 protos_commit(struct config
*new, struct config
*old
, int force_reconfig
, int type
)
505 struct proto_config
*oc
, *nc
;
509 DBG("protos_commit:\n");
512 WALK_LIST(oc
, old
->protos
)
515 sym
= cf_find_symbol(oc
->name
);
516 if (sym
&& sym
->class == SYM_PROTO
&& !new->shutdown
)
518 /* Found match, let's check if we can smoothly switch to new configuration */
519 /* No need to check description */
523 /* We will try to reconfigure protocol p */
524 if (! force_reconfig
&& proto_reconfigure(p
, oc
, nc
, type
))
527 /* Unsuccessful, we will restart it */
528 if (!p
->disabled
&& !nc
->disabled
)
529 log(L_INFO
"Restarting protocol %s", p
->name
);
530 else if (p
->disabled
&& !nc
->disabled
)
531 log(L_INFO
"Enabling protocol %s", p
->name
);
532 else if (!p
->disabled
&& nc
->disabled
)
533 log(L_INFO
"Disabling protocol %s", p
->name
);
535 p
->down_code
= nc
->disabled
? PDC_CF_DISABLE
: PDC_CF_RESTART
;
538 else if (!new->shutdown
)
540 log(L_INFO
"Removing protocol %s", p
->name
);
541 p
->down_code
= PDC_CF_REMOVE
;
544 else /* global shutdown */
546 p
->down_code
= PDC_CMD_SHUTDOWN
;
550 p
->reconfiguring
= 1;
551 config_add_obstacle(old
);
552 proto_rethink_goal(p
);
556 WALK_LIST(nc
, new->protos
)
559 if (old
) /* Not a first-time configuration */
560 log(L_INFO
"Adding protocol %s", nc
->name
);
565 DBG("Protocol start\n");
567 /* Start device protocol first */
568 if (initial_device_proto
)
570 proto_rethink_goal(initial_device_proto
);
571 initial_device_proto
= NULL
;
574 /* Determine router ID for the first time - it has to be here and not in
575 global_commit() because it is postponed after start of device protocol */
576 if (!config
->router_id
)
578 config
->router_id
= if_choose_router_id(config
->router_id_from
, 0);
579 if (!config
->router_id
)
580 die("Cannot determine router ID, please configure it manually");
583 /* Start all other protocols */
584 WALK_LIST_DELSAFE(p
, n
, initial_proto_list
)
585 proto_rethink_goal(p
);
589 proto_rethink_goal(struct proto
*p
)
593 if (p
->reconfiguring
&& p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
595 struct proto_config
*nc
= p
->cf_new
;
596 DBG("%s has shut down for reconfiguration\n", p
->name
);
597 config_del_obstacle(p
->cf
->global
);
599 rem_node(&p
->glob_node
);
606 /* Determine what state we want to reach */
607 if (p
->disabled
|| p
->reconfiguring
)
609 p
->core_goal
= FS_HUNGRY
;
610 if (p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
615 p
->core_goal
= FS_HAPPY
;
616 if (p
->core_state
== FS_HAPPY
&& p
->proto_state
== PS_UP
)
621 if (p
->core_goal
== FS_HAPPY
) /* Going up */
623 if (p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
625 DBG("Kicking %s up\n", p
->name
);
627 proto_init_instance(p
);
628 proto_notify_state(p
, (q
->start
? q
->start(p
) : PS_UP
));
631 else /* Going down */
633 if (p
->proto_state
== PS_START
|| p
->proto_state
== PS_UP
)
635 DBG("Kicking %s down\n", p
->name
);
636 PD(p
, "Shutting down");
637 proto_notify_state(p
, (q
->shutdown
? q
->shutdown(p
) : PS_DOWN
));
643 * protos_dump_all - dump status of all protocols
645 * This function dumps status of all existing protocol instances to the
646 * debug output. It involves printing of general status information
647 * such as protocol states, its position on the protocol lists
648 * and also calling of a dump() hook of the protocol to print
652 protos_dump_all(void)
655 struct announce_hook
*a
;
657 debug("Protocols:\n");
659 WALK_LIST(p
, active_proto_list
)
661 debug(" protocol %s state %s/%s\n", p
->name
,
662 p_states
[p
->proto_state
], c_states
[p
->core_state
]);
663 for (a
= p
->ahooks
; a
; a
= a
->next
)
665 debug("\tTABLE %s\n", a
->table
->name
);
667 debug("\tInput filter: %s\n", filter_name(a
->in_filter
));
668 if (a
->out_filter
!= FILTER_REJECT
)
669 debug("\tOutput filter: %s\n", filter_name(a
->out_filter
));
672 debug("\tDISABLED\n");
673 else if (p
->proto
->dump
)
676 WALK_LIST(p
, inactive_proto_list
)
677 debug(" inactive %s: state %s/%s\n", p
->name
, p_states
[p
->proto_state
], c_states
[p
->core_state
]);
678 WALK_LIST(p
, initial_proto_list
)
679 debug(" initial %s\n", p
->name
);
680 WALK_LIST(p
, flush_proto_list
)
681 debug(" flushing %s\n", p
->name
);
685 * proto_build - make a single protocol available
688 * After the platform specific initialization code uses protos_build()
689 * to add all the standard protocols, it should call proto_build() for
690 * all platform specific protocols to inform the core that they exist.
693 proto_build(struct protocol
*p
)
695 add_tail(&protocol_list
, &p
->n
);
698 ASSERT(!attr_class_to_protocol
[p
->attr_class
]);
699 attr_class_to_protocol
[p
->attr_class
] = p
;
703 /* FIXME: convert this call to some protocol hook */
704 extern void bfd_init_all(void);
707 * protos_build - build a protocol list
709 * This function is called during BIRD startup to insert
710 * all standard protocols to the global protocol list. Insertion
711 * of platform specific protocols (such as the kernel syncer)
712 * is in the domain of competence of the platform dependent
718 init_list(&protocol_list
);
719 init_list(&proto_list
);
720 init_list(&active_proto_list
);
721 init_list(&inactive_proto_list
);
722 init_list(&initial_proto_list
);
723 init_list(&flush_proto_list
);
724 proto_build(&proto_device
);
726 proto_build(&proto_radv
);
729 proto_build(&proto_rip
);
732 proto_build(&proto_static
);
735 proto_build(&proto_ospf
);
738 proto_build(&proto_pipe
);
741 proto_build(&proto_bgp
);
744 proto_build(&proto_bfd
);
748 proto_pool
= rp_new(&root_pool
, "Protocols");
749 proto_flush_event
= ev_new(proto_pool
);
750 proto_flush_event
->hook
= proto_flush_loop
;
751 proto_shutdown_timer
= tm_new(proto_pool
);
752 proto_shutdown_timer
->hook
= proto_shutdown_loop
;
756 proto_fell_down(struct proto
*p
)
758 DBG("Protocol %s down\n", p
->name
);
760 u32 all_routes
= p
->stats
.imp_routes
+ p
->stats
.filt_routes
;
762 log(L_ERR
"Protocol %s is down but still has %d routes", p
->name
, all_routes
);
764 bzero(&p
->stats
, sizeof(struct proto_stats
));
765 proto_free_ahooks(p
);
767 if (! p
->proto
->multitable
)
768 rt_unlock_table(p
->table
);
770 if (p
->proto
->cleanup
)
771 p
->proto
->cleanup(p
);
773 proto_rethink_goal(p
);
777 proto_feed_more(void *P
)
781 if (p
->core_state
!= FS_FEEDING
)
784 DBG("Feeding protocol %s continued\n", p
->name
);
787 p
->core_state
= FS_HAPPY
;
789 DBG("Protocol %s up and running\n", p
->name
);
793 p
->attn
->hook
= proto_feed_more
;
794 ev_schedule(p
->attn
); /* Will continue later... */
799 proto_feed_initial(void *P
)
803 if (p
->core_state
!= FS_FEEDING
)
806 DBG("Feeding protocol %s\n", p
->name
);
813 proto_schedule_feed(struct proto
*p
, int initial
)
815 DBG("%s: Scheduling meal\n", p
->name
);
816 p
->core_state
= FS_FEEDING
;
817 p
->refeeding
= !initial
;
819 /* FIXME: This should be changed for better support of multitable protos */
822 struct announce_hook
*ah
;
823 for (ah
= p
->ahooks
; ah
; ah
= ah
->next
)
824 proto_reset_limit(ah
->out_limit
);
826 /* Hack: reset exp_routes during refeed, and do not decrease it later */
827 p
->stats
.exp_routes
= 0;
830 /* Connect protocol to routing table */
831 if (initial
&& !p
->proto
->multitable
)
833 p
->main_source
= rt_get_source(p
, 0);
834 rt_lock_source(p
->main_source
);
836 p
->main_ahook
= proto_add_announce_hook(p
, p
->table
, &p
->stats
);
837 p
->main_ahook
->in_filter
= p
->cf
->in_filter
;
838 p
->main_ahook
->out_filter
= p
->cf
->out_filter
;
839 p
->main_ahook
->rx_limit
= p
->cf
->rx_limit
;
840 p
->main_ahook
->in_limit
= p
->cf
->in_limit
;
841 p
->main_ahook
->out_limit
= p
->cf
->out_limit
;
842 p
->main_ahook
->in_keep_filtered
= p
->cf
->in_keep_filtered
;
844 proto_reset_limit(p
->main_ahook
->rx_limit
);
845 proto_reset_limit(p
->main_ahook
->in_limit
);
846 proto_reset_limit(p
->main_ahook
->out_limit
);
850 p
->attn
->hook
= initial
? proto_feed_initial
: proto_feed_more
;
851 ev_schedule(p
->attn
);
855 * Flushing loop is responsible for flushing routes and protocols
856 * after they went down. It runs in proto_flush_event. At the start of
857 * one round, protocols waiting to flush are marked in
858 * proto_schedule_flush_loop(). At the end of the round (when routing
859 * table flush is complete), marked protocols are flushed and a next
863 static int flush_loop_state
; /* 1 -> running */
866 proto_schedule_flush_loop(void)
869 struct announce_hook
*h
;
871 if (flush_loop_state
)
873 flush_loop_state
= 1;
875 WALK_LIST(p
, flush_proto_list
)
878 for (h
=p
->ahooks
; h
; h
=h
->next
)
879 h
->table
->prune_state
= 1;
882 ev_schedule(proto_flush_event
);
886 proto_flush_loop(void *unused UNUSED
)
890 if (! rt_prune_loop())
892 /* Rtable pruning is not finished */
893 ev_schedule(proto_flush_event
);
900 WALK_LIST(p
, flush_proto_list
)
903 /* This will flush interfaces in the same manner
904 like rt_prune_all() flushes routes */
905 if (p
->proto
== &proto_unix_iface
)
908 DBG("Flushing protocol %s\n", p
->name
);
910 p
->core_state
= FS_HUNGRY
;
912 if (p
->proto_state
== PS_DOWN
)
917 /* This round finished, perhaps there will be another one */
918 flush_loop_state
= 0;
919 if (!EMPTY_LIST(flush_proto_list
))
920 proto_schedule_flush_loop();
924 proto_schedule_flush(struct proto
*p
)
926 /* Need to abort feeding */
927 if (p
->core_state
== FS_FEEDING
)
928 rt_feed_baby_abort(p
);
930 DBG("%s: Scheduling flush\n", p
->name
);
931 p
->core_state
= FS_FLUSHING
;
933 proto_unlink_ahooks(p
);
934 proto_schedule_flush_loop();
937 /* Temporary hack to propagate restart to BGP */
941 proto_shutdown_loop(struct timer
*t UNUSED
)
943 struct proto
*p
, *p_next
;
945 WALK_LIST_DELSAFE(p
, p_next
, active_proto_list
)
948 proto_restart
= (p
->down_sched
== PDS_RESTART
);
951 proto_rethink_goal(p
);
955 proto_rethink_goal(p
);
961 proto_schedule_down(struct proto
*p
, byte restart
, byte code
)
963 /* Does not work for other states (even PS_START) */
964 ASSERT(p
->proto_state
== PS_UP
);
966 /* Scheduled restart may change to shutdown, but not otherwise */
967 if (p
->down_sched
== PDS_DISABLE
)
970 p
->down_sched
= restart
? PDS_RESTART
: PDS_DISABLE
;
972 tm_start_max(proto_shutdown_timer
, restart
? 2 : 0);
977 * proto_request_feeding - request feeding routes to the protocol
980 * Sometimes it is needed to send again all routes to the
981 * protocol. This is called feeding and can be requested by this
982 * function. This would cause protocol core state transition
983 * to FS_FEEDING (during feeding) and when completed, it will
984 * switch back to FS_HAPPY. This function can be called even
985 * when feeding is already running, in that case it is restarted.
988 proto_request_feeding(struct proto
*p
)
990 ASSERT(p
->proto_state
== PS_UP
);
992 /* If we are already feeding, we want to restart it */
993 if (p
->core_state
== FS_FEEDING
)
995 /* Unless feeding is in initial state */
996 if (p
->attn
->hook
== proto_feed_initial
)
999 rt_feed_baby_abort(p
);
1002 proto_schedule_feed(p
, 0);
1006 proto_limit_name(struct proto_limit
*l
)
1008 const char *actions
[] = {
1009 [PLA_WARN
] = "warn",
1010 [PLA_BLOCK
] = "block",
1011 [PLA_RESTART
] = "restart",
1012 [PLA_DISABLE
] = "disable",
1015 return actions
[l
->action
];
1019 * proto_notify_limit: notify about limit hit and take appropriate action
1020 * @ah: announce hook
1021 * @l: limit being hit
1022 * @dir: limit direction (PLD_*)
1023 * @rt_count: the number of routes
1025 * The function is called by the route processing core when limit @l
1026 * is breached. It activates the limit and tooks appropriate action
1027 * according to @l->action.
1030 proto_notify_limit(struct announce_hook
*ah
, struct proto_limit
*l
, int dir
, u32 rt_count
)
1032 const char *dir_name
[PLD_MAX
] = { "receive", "import" , "export" };
1033 const byte dir_down
[PLD_MAX
] = { PDC_RX_LIMIT_HIT
, PDC_IN_LIMIT_HIT
, PDC_OUT_LIMIT_HIT
};
1034 struct proto
*p
= ah
->proto
;
1036 if (l
->state
== PLS_BLOCKED
)
1039 /* For warning action, we want the log message every time we hit the limit */
1040 if (!l
->state
|| ((l
->action
== PLA_WARN
) && (rt_count
== l
->limit
)))
1041 log(L_WARN
"Protocol %s hits route %s limit (%d), action: %s",
1042 p
->name
, dir_name
[dir
], l
->limit
, proto_limit_name(l
));
1047 l
->state
= PLS_ACTIVE
;
1051 l
->state
= PLS_BLOCKED
;
1056 l
->state
= PLS_BLOCKED
;
1057 proto_schedule_down(p
, l
->action
== PLA_RESTART
, dir_down
[dir
]);
1063 * proto_notify_state - notify core about protocol state change
1064 * @p: protocol the state of which has changed
1065 * @ps: the new status
1067 * Whenever a state of a protocol changes due to some event internal
1068 * to the protocol (i.e., not inside a start() or shutdown() hook),
1069 * it should immediately notify the core about the change by calling
1070 * proto_notify_state() which will write the new state to the &proto
1071 * structure and take all the actions necessary to adapt to the new
1072 * state. State change to PS_DOWN immediately frees resources of protocol
1073 * and might execute start callback of protocol; therefore,
1074 * it should be used at tail positions of protocol callbacks.
1077 proto_notify_state(struct proto
*p
, unsigned ps
)
1079 unsigned ops
= p
->proto_state
;
1080 unsigned cs
= p
->core_state
;
1082 DBG("%s reporting state transition %s/%s -> */%s\n", p
->name
, c_states
[cs
], p_states
[ops
], p_states
[ps
]);
1086 p
->proto_state
= ps
;
1093 if ((cs
== FS_FEEDING
) || (cs
== FS_HAPPY
))
1094 proto_schedule_flush(p
);
1096 if (p
->proto
->multitable
)
1098 rt_unlock_source(p
->main_source
);
1099 p
->main_source
= NULL
;
1102 neigh_prune(); // FIXME convert neighbors to resource?
1106 if (cs
== FS_HUNGRY
) /* Shutdown finished */
1109 return; /* The protocol might have ceased to exist */
1113 ASSERT(ops
== PS_DOWN
);
1114 ASSERT(cs
== FS_HUNGRY
);
1117 ASSERT(ops
== PS_DOWN
|| ops
== PS_START
);
1118 ASSERT(cs
== FS_HUNGRY
);
1119 proto_schedule_feed(p
, 1);
1123 if ((cs
== FS_FEEDING
) || (cs
== FS_HAPPY
))
1124 proto_schedule_flush(p
);
1127 bug("Invalid state transition for %s from %s/%s to */%s", p
->name
, c_states
[cs
], p_states
[ops
], p_states
[ps
]);
1136 proto_state_name(struct proto
*p
)
1138 #define P(x,y) ((x << 4) | y)
1139 switch (P(p
->proto_state
, p
->core_state
))
1141 case P(PS_DOWN
, FS_HUNGRY
): return "down";
1142 case P(PS_START
, FS_HUNGRY
): return "start";
1143 case P(PS_UP
, FS_HUNGRY
):
1144 case P(PS_UP
, FS_FEEDING
): return "feed";
1145 case P(PS_STOP
, FS_HUNGRY
): return "stop";
1146 case P(PS_UP
, FS_HAPPY
): return "up";
1147 case P(PS_STOP
, FS_FLUSHING
):
1148 case P(PS_DOWN
, FS_FLUSHING
): return "flush";
1149 default: return "???";
1155 proto_show_stats(struct proto_stats
*s
, int in_keep_filtered
)
1157 if (in_keep_filtered
)
1158 cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
1159 s
->imp_routes
, s
->filt_routes
, s
->exp_routes
, s
->pref_routes
);
1161 cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
1162 s
->imp_routes
, s
->exp_routes
, s
->pref_routes
);
1164 cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
1165 cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
1166 s
->imp_updates_received
, s
->imp_updates_invalid
,
1167 s
->imp_updates_filtered
, s
->imp_updates_ignored
,
1168 s
->imp_updates_accepted
);
1169 cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
1170 s
->imp_withdraws_received
, s
->imp_withdraws_invalid
,
1171 s
->imp_withdraws_ignored
, s
->imp_withdraws_accepted
);
1172 cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
1173 s
->exp_updates_received
, s
->exp_updates_rejected
,
1174 s
->exp_updates_filtered
, s
->exp_updates_accepted
);
1175 cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
1176 s
->exp_withdraws_received
, s
->exp_withdraws_accepted
);
1180 proto_show_limit(struct proto_limit
*l
, const char *dsc
)
1185 cli_msg(-1006, " %-16s%d%s", dsc
, l
->limit
, l
->state
? " [HIT]" : "");
1186 cli_msg(-1006, " Action: %s", proto_limit_name(l
));
1190 proto_show_basic_info(struct proto
*p
)
1192 // cli_msg(-1006, " Table: %s", p->table->name);
1193 cli_msg(-1006, " Preference: %d", p
->preference
);
1194 cli_msg(-1006, " Input filter: %s", filter_name(p
->cf
->in_filter
));
1195 cli_msg(-1006, " Output filter: %s", filter_name(p
->cf
->out_filter
));
1197 proto_show_limit(p
->cf
->rx_limit
, "Receive limit:");
1198 proto_show_limit(p
->cf
->in_limit
, "Import limit:");
1199 proto_show_limit(p
->cf
->out_limit
, "Export limit:");
1201 if (p
->proto_state
!= PS_DOWN
)
1202 proto_show_stats(&p
->stats
, p
->cf
->in_keep_filtered
);
1206 proto_cmd_show(struct proto
*p
, unsigned int verbose
, int cnt
)
1208 byte buf
[256], tbuf
[TM_DATETIME_BUFFER_SIZE
];
1210 /* First protocol - show header */
1212 cli_msg(-2002, "name proto table state since info");
1215 if (p
->proto
->get_status
)
1216 p
->proto
->get_status(p
, buf
);
1217 tm_format_datetime(tbuf
, &config
->tf_proto
, p
->last_state_change
);
1218 cli_msg(-1002, "%-8s %-8s %-8s %-5s %-10s %s",
1222 proto_state_name(p
),
1228 cli_msg(-1006, " Description: %s", p
->cf
->dsc
);
1229 if (p
->cf
->router_id
)
1230 cli_msg(-1006, " Router ID: %R", p
->cf
->router_id
);
1232 if (p
->proto
->show_proto_info
)
1233 p
->proto
->show_proto_info(p
);
1235 proto_show_basic_info(p
);
1242 proto_cmd_disable(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1246 cli_msg(-8, "%s: already disabled", p
->name
);
1250 log(L_INFO
"Disabling protocol %s", p
->name
);
1252 p
->down_code
= PDC_CMD_DISABLE
;
1253 proto_rethink_goal(p
);
1254 cli_msg(-9, "%s: disabled", p
->name
);
1258 proto_cmd_enable(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1262 cli_msg(-10, "%s: already enabled", p
->name
);
1266 log(L_INFO
"Enabling protocol %s", p
->name
);
1268 proto_rethink_goal(p
);
1269 cli_msg(-11, "%s: enabled", p
->name
);
1273 proto_cmd_restart(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1277 cli_msg(-8, "%s: already disabled", p
->name
);
1281 log(L_INFO
"Restarting protocol %s", p
->name
);
1283 p
->down_code
= PDC_CMD_RESTART
;
1284 proto_rethink_goal(p
);
1286 proto_rethink_goal(p
);
1287 cli_msg(-12, "%s: restarted", p
->name
);
1291 proto_cmd_reload(struct proto
*p
, unsigned int dir
, int cnt UNUSED
)
1295 cli_msg(-8, "%s: already disabled", p
->name
);
1299 /* If the protocol in not UP, it has no routes */
1300 if (p
->proto_state
!= PS_UP
)
1303 log(L_INFO
"Reloading protocol %s", p
->name
);
1305 /* re-importing routes */
1306 if (dir
!= CMD_RELOAD_OUT
)
1308 if (! (p
->reload_routes
&& p
->reload_routes(p
)))
1310 cli_msg(-8006, "%s: reload failed", p
->name
);
1315 * Should be done before reload_routes() hook?
1316 * Perhaps, but these hooks work asynchronously.
1318 if (!p
->proto
->multitable
)
1320 proto_reset_limit(p
->main_ahook
->rx_limit
);
1321 proto_reset_limit(p
->main_ahook
->in_limit
);
1325 /* re-exporting routes */
1326 if (dir
!= CMD_RELOAD_IN
)
1327 proto_request_feeding(p
);
1329 cli_msg(-15, "%s: reloading", p
->name
);
1333 proto_cmd_debug(struct proto
*p
, unsigned int mask
, int cnt UNUSED
)
1339 proto_cmd_mrtdump(struct proto
*p
, unsigned int mask
, int cnt UNUSED
)
1345 proto_apply_cmd_symbol(struct symbol
*s
, void (* cmd
)(struct proto
*, unsigned int, int), unsigned int arg
)
1347 if (s
->class != SYM_PROTO
)
1349 cli_msg(9002, "%s is not a protocol", s
->name
);
1353 cmd(((struct proto_config
*)s
->def
)->proto
, arg
, 0);
1358 proto_apply_cmd_patt(char *patt
, void (* cmd
)(struct proto
*, unsigned int, int), unsigned int arg
)
1363 WALK_LIST(nn
, proto_list
)
1365 struct proto
*p
= SKIP_BACK(struct proto
, glob_node
, nn
);
1367 if (!patt
|| patmatch(patt
, p
->name
))
1372 cli_msg(8003, "No protocols match");
1378 proto_apply_cmd(struct proto_spec ps
, void (* cmd
)(struct proto
*, unsigned int, int),
1379 int restricted
, unsigned int arg
)
1381 if (restricted
&& cli_access_restricted())
1385 proto_apply_cmd_patt(ps
.ptr
, cmd
, arg
);
1387 proto_apply_cmd_symbol(ps
.ptr
, cmd
, arg
);
1391 proto_get_named(struct symbol
*sym
, struct protocol
*pr
)
1393 struct proto
*p
, *q
;
1397 if (sym
->class != SYM_PROTO
)
1398 cf_error("%s: Not a protocol", sym
->name
);
1399 p
= ((struct proto_config
*)sym
->def
)->proto
;
1400 if (!p
|| p
->proto
!= pr
)
1401 cf_error("%s: Not a %s protocol", sym
->name
, pr
->name
);
1406 WALK_LIST(q
, active_proto_list
)
1410 cf_error("There are multiple %s protocols running", pr
->name
);
1414 cf_error("There is no %s protocol running", pr
->name
);