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
)
54 proto_relink(struct proto
*p
)
58 if (p
->debug
& D_STATES
)
60 char *name
= proto_state_name(p
);
61 if (name
!= p
->last_state_name_announced
)
63 p
->last_state_name_announced
= name
;
64 PD(p
, "State changed to %s", proto_state_name(p
));
68 p
->last_state_name_announced
= NULL
;
70 switch (p
->core_state
)
73 l
= &inactive_proto_list
;
77 l
= &active_proto_list
;
80 l
= &flush_proto_list
;
89 * proto_new - create a new protocol instance
90 * @c: protocol configuration
91 * @size: size of protocol data structure (each protocol instance is represented by
92 * a structure starting with generic part [struct &proto] and continued
93 * with data specific to the protocol)
95 * When a new configuration has been read in, the core code starts
96 * initializing all the protocol instances configured by calling their
97 * init() hooks with the corresponding instance configuration. The initialization
98 * code of the protocol is expected to create a new instance according to the
99 * configuration by calling this function and then modifying the default settings
100 * to values wanted by the protocol.
103 proto_new(struct proto_config
*c
, unsigned size
)
105 struct protocol
*pr
= c
->protocol
;
106 struct proto
*p
= mb_allocz(proto_pool
, size
);
110 p
->mrtdump
= c
->mrtdump
;
112 p
->preference
= c
->preference
;
113 p
->disabled
= c
->disabled
;
115 p
->table
= c
->table
->table
;
116 p
->hash_key
= random_u32();
122 proto_init_instance(struct proto
*p
)
124 /* Here we cannot use p->cf->name since it won't survive reconfiguration */
125 p
->pool
= rp_new(proto_pool
, p
->proto
->name
);
126 p
->attn
= ev_new(p
->pool
);
129 if (! p
->proto
->multitable
)
130 rt_lock_table(p
->table
);
133 extern pool
*rt_table_pool
;
135 * proto_add_announce_hook - connect protocol to a routing table
136 * @p: protocol instance
137 * @t: routing table to connect to
138 * @stats: per-table protocol statistics
140 * This function creates a connection between the protocol instance @p
141 * and the routing table @t, making the protocol hear all changes in
144 * The announce hook is linked in the protocol ahook list and, if the
145 * protocol accepts routes, also in the table ahook list. Announce
146 * hooks are allocated from the routing table resource pool, they are
147 * unlinked from the table ahook list after the protocol went down,
148 * (in proto_schedule_flush()) and they are automatically freed after the
149 * protocol is flushed (in proto_fell_down()).
151 * Unless you want to listen to multiple routing tables (as the Pipe
152 * protocol does), you needn't to worry about this function since the
153 * connection to the protocol's primary routing table is initialized
154 * automatically by the core code.
156 struct announce_hook
*
157 proto_add_announce_hook(struct proto
*p
, struct rtable
*t
, struct proto_stats
*stats
)
159 struct announce_hook
*h
;
161 DBG("Connecting protocol %s to table %s\n", p
->name
, t
->name
);
162 PD(p
, "Connected to table %s", t
->name
);
164 h
= mb_allocz(rt_table_pool
, sizeof(struct announce_hook
));
173 add_tail(&t
->hooks
, &h
->n
);
178 * proto_find_announce_hook - find announce hooks
179 * @p: protocol instance
182 * Returns pointer to announce hook or NULL
184 struct announce_hook
*
185 proto_find_announce_hook(struct proto
*p
, struct rtable
*t
)
187 struct announce_hook
*a
;
189 for (a
= p
->ahooks
; a
; a
= a
->next
)
197 proto_unlink_ahooks(struct proto
*p
)
199 struct announce_hook
*h
;
202 for(h
=p
->ahooks
; h
; h
=h
->next
)
207 proto_free_ahooks(struct proto
*p
)
209 struct announce_hook
*h
, *hn
;
211 for(h
= p
->ahooks
; h
; h
= hn
)
218 p
->main_ahook
= NULL
;
223 * proto_config_new - create a new protocol configuration
224 * @pr: protocol the configuration will belong to
225 * @size: size of the structure including generic data
226 * @class: SYM_PROTO or SYM_TEMPLATE
228 * Whenever the configuration file says that a new instance
229 * of a routing protocol should be created, the parser calls
230 * proto_config_new() to create a configuration entry for this
231 * instance (a structure staring with the &proto_config header
232 * containing all the generic items followed by protocol-specific
233 * ones). Also, the configuration entry gets added to the list
234 * of protocol instances kept in the configuration.
236 * The function is also used to create protocol templates (when class
237 * SYM_TEMPLATE is specified), the only difference is that templates
238 * are not added to the list of protocol instances and therefore not
239 * initialized during protos_commit()).
242 proto_config_new(struct protocol
*pr
, unsigned size
, int class)
244 struct proto_config
*c
= cfg_allocz(size
);
246 if (class == SYM_PROTO
)
247 add_tail(&new_config
->protos
, &c
->n
);
248 c
->global
= new_config
;
251 c
->preference
= pr
->preference
;
253 c
->out_filter
= FILTER_REJECT
;
254 c
->table
= c
->global
->master_rtc
;
255 c
->debug
= new_config
->proto_default_debug
;
256 c
->mrtdump
= new_config
->proto_default_mrtdump
;
261 * proto_copy_config - copy a protocol configuration
262 * @dest: destination protocol configuration
263 * @src: source protocol configuration
265 * Whenever a new instance of a routing protocol is created from the
266 * template, proto_copy_config() is called to copy a content of
267 * the source protocol configuration to the new protocol configuration.
268 * Name, class and a node in protos list of @dest are kept intact.
269 * copy_config() protocol hook is used to copy protocol-specific data.
272 proto_copy_config(struct proto_config
*dest
, struct proto_config
*src
)
278 if (dest
->protocol
!= src
->protocol
)
279 cf_error("Can't copy configuration from a different protocol type");
281 if (dest
->protocol
->copy_config
== NULL
)
282 cf_error("Inheriting configuration for %s is not supported", src
->protocol
->name
);
284 DBG("Copying configuration from %s to %s\n", src
->name
, dest
->name
);
287 * Copy struct proto_config here. Keep original node, class and name.
288 * protocol-specific config copy is handled by protocol copy_config() hook
292 old_class
= dest
->class;
293 old_name
= dest
->name
;
295 memcpy(dest
, src
, sizeof(struct proto_config
));
298 dest
->class = old_class
;
299 dest
->name
= old_name
;
301 dest
->protocol
->copy_config(dest
, src
);
305 * protos_preconfig - pre-configuration processing
306 * @c: new configuration
308 * This function calls the preconfig() hooks of all routing
309 * protocols available to prepare them for reading of the new
313 protos_preconfig(struct config
*c
)
317 init_list(&c
->protos
);
318 DBG("Protocol preconfig:");
319 WALK_LIST(p
, protocol_list
)
330 * protos_postconfig - post-configuration processing
331 * @c: new configuration
333 * This function calls the postconfig() hooks of all protocol
334 * instances specified in configuration @c. The hooks are not
335 * called for protocol templates.
338 protos_postconfig(struct config
*c
)
340 struct proto_config
*x
;
343 DBG("Protocol postconfig:");
344 WALK_LIST(x
, c
->protos
)
355 extern struct protocol proto_unix_iface
;
357 static struct proto
*
358 proto_init(struct proto_config
*c
)
360 struct protocol
*p
= c
->protocol
;
361 struct proto
*q
= p
->init(c
);
363 q
->proto_state
= PS_DOWN
;
364 q
->core_state
= FS_HUNGRY
;
365 q
->last_state_change
= now
;
367 proto_enqueue(&initial_proto_list
, q
);
368 if (p
== &proto_unix_iface
)
369 initial_device_proto
= q
;
371 add_tail(&proto_list
, &q
->glob_node
);
372 PD(q
, "Initializing%s", q
->disabled
? " [disabled]" : "");
376 int proto_reconfig_type
; /* Hack to propagate type info to pipe reconfigure hook */
379 proto_reconfigure(struct proto
*p
, struct proto_config
*oc
, struct proto_config
*nc
, int type
)
381 struct announce_hook
*ah
= p
->main_ahook
;
382 /* If the protocol is DOWN, we just restart it */
383 if (p
->proto_state
== PS_DOWN
)
386 /* If there is a too big change in core attributes, ... */
387 if ((nc
->protocol
!= oc
->protocol
) ||
388 (nc
->disabled
!= p
->disabled
) ||
389 (nc
->table
->table
!= oc
->table
->table
))
392 p
->debug
= nc
->debug
;
393 p
->mrtdump
= nc
->mrtdump
;
394 proto_reconfig_type
= type
;
396 /* Execute protocol specific reconfigure hook */
397 if (! (p
->proto
->reconfigure
&& p
->proto
->reconfigure(p
, nc
)))
400 DBG("\t%s: same\n", oc
->name
);
401 PD(p
, "Reconfigured");
404 p
->preference
= nc
->preference
;
407 /* Multitable protocols handle rest in their reconfigure hooks */
408 if (p
->proto
->multitable
)
411 /* Update filters and limits in the main announce hook
412 Note that this also resets limit state */
415 ah
->in_filter
= nc
->in_filter
;
416 ah
->out_filter
= nc
->out_filter
;
417 ah
->rx_limit
= nc
->rx_limit
;
418 ah
->in_limit
= nc
->in_limit
;
419 ah
->out_limit
= nc
->out_limit
;
420 ah
->in_keep_filtered
= nc
->in_keep_filtered
;
422 if (p
->proto_state
== PS_UP
) /* Recheck export/import/receive limit */
424 struct proto_stats
*stats
= ah
->stats
;
425 struct proto_limit
*l
= ah
->in_limit
;
426 u32 all_routes
= stats
->imp_routes
+ stats
->filt_routes
;
428 if (l
&& (stats
->imp_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_IN
, stats
->imp_routes
);
432 if (l
&& ( all_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_RX
, all_routes
);
436 if (l
&& ( stats
->exp_routes
>= l
->limit
)) proto_notify_limit(ah
, l
, PLD_OUT
, stats
->exp_routes
);
440 /* Update routes when filters changed. If the protocol in not UP,
441 it has no routes and we can ignore such changes */
442 if ((p
->proto_state
!= PS_UP
) || (type
== RECONFIG_SOFT
))
445 int import_changed
= ! filter_same(nc
->in_filter
, oc
->in_filter
);
446 int export_changed
= ! filter_same(nc
->out_filter
, oc
->out_filter
);
448 /* We treat a change in preferences by reimporting routes */
449 if (nc
->preference
!= oc
->preference
)
452 if (import_changed
|| export_changed
)
453 log(L_INFO
"Reloading protocol %s", p
->name
);
455 /* If import filter changed, call reload hook */
456 if (import_changed
&& ! (p
->reload_routes
&& p
->reload_routes(p
)))
458 /* Now, the protocol is reconfigured. But route reload failed
459 and we have to do regular protocol restart. */
460 log(L_INFO
"Restarting protocol %s", p
->name
);
462 p
->down_code
= PDC_CF_RESTART
;
463 proto_rethink_goal(p
);
465 proto_rethink_goal(p
);
470 proto_request_feeding(p
);
476 * protos_commit - commit new protocol configuration
477 * @new: new configuration
478 * @old: old configuration or %NULL if it's boot time config
479 * @force_reconfig: force restart of all protocols (used for example
480 * when the router ID changes)
481 * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
483 * Scan differences between @old and @new configuration and adjust all
484 * protocol instances to conform to the new configuration.
486 * When a protocol exists in the new configuration, but it doesn't in the
487 * original one, it's immediately started. When a collision with the other
488 * running protocol would arise, the new protocol will be temporarily stopped
489 * by the locking mechanism.
491 * When a protocol exists in the old configuration, but it doesn't in the
492 * new one, it's shut down and deleted after the shutdown completes.
494 * When a protocol exists in both configurations, the core decides
495 * whether it's possible to reconfigure it dynamically - it checks all
496 * the core properties of the protocol (changes in filters are ignored
497 * if type is RECONFIG_SOFT) and if they match, it asks the
498 * reconfigure() hook of the protocol to see if the protocol is able
499 * to switch to the new configuration. If it isn't possible, the
500 * protocol is shut down and a new instance is started with the new
501 * configuration after the shutdown is completed.
504 protos_commit(struct config
*new, struct config
*old
, int force_reconfig
, int type
)
506 struct proto_config
*oc
, *nc
;
510 DBG("protos_commit:\n");
513 WALK_LIST(oc
, old
->protos
)
516 sym
= cf_find_symbol(oc
->name
);
517 if (sym
&& sym
->class == SYM_PROTO
&& !new->shutdown
)
519 /* Found match, let's check if we can smoothly switch to new configuration */
520 /* No need to check description */
524 /* We will try to reconfigure protocol p */
525 if (! force_reconfig
&& proto_reconfigure(p
, oc
, nc
, type
))
528 /* Unsuccessful, we will restart it */
529 if (!p
->disabled
&& !nc
->disabled
)
530 log(L_INFO
"Restarting protocol %s", p
->name
);
531 else if (p
->disabled
&& !nc
->disabled
)
532 log(L_INFO
"Enabling protocol %s", p
->name
);
533 else if (!p
->disabled
&& nc
->disabled
)
534 log(L_INFO
"Disabling protocol %s", p
->name
);
536 p
->down_code
= nc
->disabled
? PDC_CF_DISABLE
: PDC_CF_RESTART
;
539 else if (!new->shutdown
)
541 log(L_INFO
"Removing protocol %s", p
->name
);
542 p
->down_code
= PDC_CF_REMOVE
;
545 else /* global shutdown */
547 p
->down_code
= PDC_CMD_SHUTDOWN
;
551 p
->reconfiguring
= 1;
552 config_add_obstacle(old
);
553 proto_rethink_goal(p
);
557 WALK_LIST(nc
, new->protos
)
560 if (old
) /* Not a first-time configuration */
561 log(L_INFO
"Adding protocol %s", nc
->name
);
566 DBG("Protocol start\n");
568 /* Start device protocol first */
569 if (initial_device_proto
)
571 proto_rethink_goal(initial_device_proto
);
572 initial_device_proto
= NULL
;
575 /* Determine router ID for the first time - it has to be here and not in
576 global_commit() because it is postponed after start of device protocol */
577 if (!config
->router_id
)
579 config
->router_id
= if_choose_router_id(config
->router_id_from
, 0);
580 if (!config
->router_id
)
581 die("Cannot determine router ID, please configure it manually");
584 /* Start all other protocols */
585 WALK_LIST_DELSAFE(p
, n
, initial_proto_list
)
586 proto_rethink_goal(p
);
590 proto_rethink_goal(struct proto
*p
)
594 if (p
->reconfiguring
&& p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
596 struct proto_config
*nc
= p
->cf_new
;
597 DBG("%s has shut down for reconfiguration\n", p
->name
);
598 config_del_obstacle(p
->cf
->global
);
600 rem_node(&p
->glob_node
);
607 /* Determine what state we want to reach */
608 if (p
->disabled
|| p
->reconfiguring
)
610 p
->core_goal
= FS_HUNGRY
;
611 if (p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
616 p
->core_goal
= FS_HAPPY
;
617 if (p
->core_state
== FS_HAPPY
&& p
->proto_state
== PS_UP
)
622 if (p
->core_goal
== FS_HAPPY
) /* Going up */
624 if (p
->core_state
== FS_HUNGRY
&& p
->proto_state
== PS_DOWN
)
626 DBG("Kicking %s up\n", p
->name
);
628 proto_init_instance(p
);
629 proto_notify_state(p
, (q
->start
? q
->start(p
) : PS_UP
));
632 else /* Going down */
634 if (p
->proto_state
== PS_START
|| p
->proto_state
== PS_UP
)
636 DBG("Kicking %s down\n", p
->name
);
637 PD(p
, "Shutting down");
638 proto_notify_state(p
, (q
->shutdown
? q
->shutdown(p
) : PS_DOWN
));
644 * protos_dump_all - dump status of all protocols
646 * This function dumps status of all existing protocol instances to the
647 * debug output. It involves printing of general status information
648 * such as protocol states, its position on the protocol lists
649 * and also calling of a dump() hook of the protocol to print
653 protos_dump_all(void)
656 struct announce_hook
*a
;
658 debug("Protocols:\n");
660 WALK_LIST(p
, active_proto_list
)
662 debug(" protocol %s state %s/%s\n", p
->name
,
663 p_states
[p
->proto_state
], c_states
[p
->core_state
]);
664 for (a
= p
->ahooks
; a
; a
= a
->next
)
666 debug("\tTABLE %s\n", a
->table
->name
);
668 debug("\tInput filter: %s\n", filter_name(a
->in_filter
));
669 if (a
->out_filter
!= FILTER_REJECT
)
670 debug("\tOutput filter: %s\n", filter_name(a
->out_filter
));
673 debug("\tDISABLED\n");
674 else if (p
->proto
->dump
)
677 WALK_LIST(p
, inactive_proto_list
)
678 debug(" inactive %s: state %s/%s\n", p
->name
, p_states
[p
->proto_state
], c_states
[p
->core_state
]);
679 WALK_LIST(p
, initial_proto_list
)
680 debug(" initial %s\n", p
->name
);
681 WALK_LIST(p
, flush_proto_list
)
682 debug(" flushing %s\n", p
->name
);
686 * proto_build - make a single protocol available
689 * After the platform specific initialization code uses protos_build()
690 * to add all the standard protocols, it should call proto_build() for
691 * all platform specific protocols to inform the core that they exist.
694 proto_build(struct protocol
*p
)
696 add_tail(&protocol_list
, &p
->n
);
699 ASSERT(!attr_class_to_protocol
[p
->attr_class
]);
700 attr_class_to_protocol
[p
->attr_class
] = p
;
704 /* FIXME: convert this call to some protocol hook */
705 extern void bfd_init_all(void);
708 * protos_build - build a protocol list
710 * This function is called during BIRD startup to insert
711 * all standard protocols to the global protocol list. Insertion
712 * of platform specific protocols (such as the kernel syncer)
713 * is in the domain of competence of the platform dependent
719 init_list(&protocol_list
);
720 init_list(&proto_list
);
721 init_list(&active_proto_list
);
722 init_list(&inactive_proto_list
);
723 init_list(&initial_proto_list
);
724 init_list(&flush_proto_list
);
725 proto_build(&proto_device
);
727 proto_build(&proto_radv
);
730 proto_build(&proto_rip
);
733 proto_build(&proto_static
);
736 proto_build(&proto_ospf
);
739 proto_build(&proto_pipe
);
742 proto_build(&proto_bgp
);
745 proto_build(&proto_bfd
);
749 proto_pool
= rp_new(&root_pool
, "Protocols");
750 proto_flush_event
= ev_new(proto_pool
);
751 proto_flush_event
->hook
= proto_flush_loop
;
752 proto_shutdown_timer
= tm_new(proto_pool
);
753 proto_shutdown_timer
->hook
= proto_shutdown_loop
;
757 proto_fell_down(struct proto
*p
)
759 DBG("Protocol %s down\n", p
->name
);
761 u32 all_routes
= p
->stats
.imp_routes
+ p
->stats
.filt_routes
;
763 log(L_ERR
"Protocol %s is down but still has %d routes", p
->name
, all_routes
);
765 bzero(&p
->stats
, sizeof(struct proto_stats
));
766 proto_free_ahooks(p
);
768 if (! p
->proto
->multitable
)
769 rt_unlock_table(p
->table
);
771 if (p
->proto
->cleanup
)
772 p
->proto
->cleanup(p
);
774 proto_rethink_goal(p
);
778 proto_feed_more(void *P
)
782 if (p
->core_state
!= FS_FEEDING
)
785 DBG("Feeding protocol %s continued\n", p
->name
);
788 p
->core_state
= FS_HAPPY
;
790 DBG("Protocol %s up and running\n", p
->name
);
794 p
->attn
->hook
= proto_feed_more
;
795 ev_schedule(p
->attn
); /* Will continue later... */
800 proto_feed_initial(void *P
)
804 if (p
->core_state
!= FS_FEEDING
)
807 DBG("Feeding protocol %s\n", p
->name
);
814 proto_schedule_feed(struct proto
*p
, int initial
)
816 DBG("%s: Scheduling meal\n", p
->name
);
817 p
->core_state
= FS_FEEDING
;
818 p
->refeeding
= !initial
;
820 /* FIXME: This should be changed for better support of multitable protos */
823 struct announce_hook
*ah
;
824 for (ah
= p
->ahooks
; ah
; ah
= ah
->next
)
825 proto_reset_limit(ah
->out_limit
);
827 /* Hack: reset exp_routes during refeed, and do not decrease it later */
828 p
->stats
.exp_routes
= 0;
831 /* Connect protocol to routing table */
832 if (initial
&& !p
->proto
->multitable
)
834 p
->main_source
= rt_get_source(p
, 0);
835 rt_lock_source(p
->main_source
);
837 p
->main_ahook
= proto_add_announce_hook(p
, p
->table
, &p
->stats
);
838 p
->main_ahook
->in_filter
= p
->cf
->in_filter
;
839 p
->main_ahook
->out_filter
= p
->cf
->out_filter
;
840 p
->main_ahook
->rx_limit
= p
->cf
->rx_limit
;
841 p
->main_ahook
->in_limit
= p
->cf
->in_limit
;
842 p
->main_ahook
->out_limit
= p
->cf
->out_limit
;
843 p
->main_ahook
->in_keep_filtered
= p
->cf
->in_keep_filtered
;
845 proto_reset_limit(p
->main_ahook
->rx_limit
);
846 proto_reset_limit(p
->main_ahook
->in_limit
);
847 proto_reset_limit(p
->main_ahook
->out_limit
);
851 p
->attn
->hook
= initial
? proto_feed_initial
: proto_feed_more
;
852 ev_schedule(p
->attn
);
856 * Flushing loop is responsible for flushing routes and protocols
857 * after they went down. It runs in proto_flush_event. At the start of
858 * one round, protocols waiting to flush are marked in
859 * proto_schedule_flush_loop(). At the end of the round (when routing
860 * table flush is complete), marked protocols are flushed and a next
864 static int flush_loop_state
; /* 1 -> running */
867 proto_schedule_flush_loop(void)
870 struct announce_hook
*h
;
872 if (flush_loop_state
)
874 flush_loop_state
= 1;
876 WALK_LIST(p
, flush_proto_list
)
879 for (h
=p
->ahooks
; h
; h
=h
->next
)
880 h
->table
->prune_state
= 1;
883 ev_schedule(proto_flush_event
);
887 proto_flush_loop(void *unused UNUSED
)
891 if (! rt_prune_loop())
893 /* Rtable pruning is not finished */
894 ev_schedule(proto_flush_event
);
901 WALK_LIST(p
, flush_proto_list
)
904 /* This will flush interfaces in the same manner
905 like rt_prune_all() flushes routes */
906 if (p
->proto
== &proto_unix_iface
)
909 DBG("Flushing protocol %s\n", p
->name
);
911 p
->core_state
= FS_HUNGRY
;
913 if (p
->proto_state
== PS_DOWN
)
918 /* This round finished, perhaps there will be another one */
919 flush_loop_state
= 0;
920 if (!EMPTY_LIST(flush_proto_list
))
921 proto_schedule_flush_loop();
925 proto_schedule_flush(struct proto
*p
)
927 /* Need to abort feeding */
928 if (p
->core_state
== FS_FEEDING
)
929 rt_feed_baby_abort(p
);
931 DBG("%s: Scheduling flush\n", p
->name
);
932 p
->core_state
= FS_FLUSHING
;
934 proto_unlink_ahooks(p
);
935 proto_schedule_flush_loop();
938 /* Temporary hack to propagate restart to BGP */
942 proto_shutdown_loop(struct timer
*t UNUSED
)
944 struct proto
*p
, *p_next
;
946 WALK_LIST_DELSAFE(p
, p_next
, active_proto_list
)
949 proto_restart
= (p
->down_sched
== PDS_RESTART
);
952 proto_rethink_goal(p
);
956 proto_rethink_goal(p
);
962 proto_schedule_down(struct proto
*p
, byte restart
, byte code
)
964 /* Does not work for other states (even PS_START) */
965 ASSERT(p
->proto_state
== PS_UP
);
967 /* Scheduled restart may change to shutdown, but not otherwise */
968 if (p
->down_sched
== PDS_DISABLE
)
971 p
->down_sched
= restart
? PDS_RESTART
: PDS_DISABLE
;
973 tm_start_max(proto_shutdown_timer
, restart
? 2 : 0);
978 * proto_request_feeding - request feeding routes to the protocol
981 * Sometimes it is needed to send again all routes to the
982 * protocol. This is called feeding and can be requested by this
983 * function. This would cause protocol core state transition
984 * to FS_FEEDING (during feeding) and when completed, it will
985 * switch back to FS_HAPPY. This function can be called even
986 * when feeding is already running, in that case it is restarted.
989 proto_request_feeding(struct proto
*p
)
991 ASSERT(p
->proto_state
== PS_UP
);
993 /* If we are already feeding, we want to restart it */
994 if (p
->core_state
== FS_FEEDING
)
996 /* Unless feeding is in initial state */
997 if (p
->attn
->hook
== proto_feed_initial
)
1000 rt_feed_baby_abort(p
);
1003 proto_schedule_feed(p
, 0);
1007 proto_limit_name(struct proto_limit
*l
)
1009 const char *actions
[] = {
1010 [PLA_WARN
] = "warn",
1011 [PLA_BLOCK
] = "block",
1012 [PLA_RESTART
] = "restart",
1013 [PLA_DISABLE
] = "disable",
1016 return actions
[l
->action
];
1020 * proto_notify_limit: notify about limit hit and take appropriate action
1021 * @ah: announce hook
1022 * @l: limit being hit
1023 * @dir: limit direction (PLD_*)
1024 * @rt_count: the number of routes
1026 * The function is called by the route processing core when limit @l
1027 * is breached. It activates the limit and tooks appropriate action
1028 * according to @l->action.
1031 proto_notify_limit(struct announce_hook
*ah
, struct proto_limit
*l
, int dir
, u32 rt_count
)
1033 const char *dir_name
[PLD_MAX
] = { "receive", "import" , "export" };
1034 const byte dir_down
[PLD_MAX
] = { PDC_RX_LIMIT_HIT
, PDC_IN_LIMIT_HIT
, PDC_OUT_LIMIT_HIT
};
1035 struct proto
*p
= ah
->proto
;
1037 if (l
->state
== PLS_BLOCKED
)
1040 /* For warning action, we want the log message every time we hit the limit */
1041 if (!l
->state
|| ((l
->action
== PLA_WARN
) && (rt_count
== l
->limit
)))
1042 log(L_WARN
"Protocol %s hits route %s limit (%d), action: %s",
1043 p
->name
, dir_name
[dir
], l
->limit
, proto_limit_name(l
));
1048 l
->state
= PLS_ACTIVE
;
1052 l
->state
= PLS_BLOCKED
;
1057 l
->state
= PLS_BLOCKED
;
1058 proto_schedule_down(p
, l
->action
== PLA_RESTART
, dir_down
[dir
]);
1064 * proto_notify_state - notify core about protocol state change
1065 * @p: protocol the state of which has changed
1066 * @ps: the new status
1068 * Whenever a state of a protocol changes due to some event internal
1069 * to the protocol (i.e., not inside a start() or shutdown() hook),
1070 * it should immediately notify the core about the change by calling
1071 * proto_notify_state() which will write the new state to the &proto
1072 * structure and take all the actions necessary to adapt to the new
1073 * state. State change to PS_DOWN immediately frees resources of protocol
1074 * and might execute start callback of protocol; therefore,
1075 * it should be used at tail positions of protocol callbacks.
1078 proto_notify_state(struct proto
*p
, unsigned ps
)
1080 unsigned ops
= p
->proto_state
;
1081 unsigned cs
= p
->core_state
;
1083 DBG("%s reporting state transition %s/%s -> */%s\n", p
->name
, c_states
[cs
], p_states
[ops
], p_states
[ps
]);
1087 p
->proto_state
= ps
;
1088 p
->last_state_change
= now
;
1095 if ((cs
== FS_FEEDING
) || (cs
== FS_HAPPY
))
1096 proto_schedule_flush(p
);
1098 if (p
->proto
->multitable
)
1100 rt_unlock_source(p
->main_source
);
1101 p
->main_source
= NULL
;
1104 neigh_prune(); // FIXME convert neighbors to resource?
1108 if (cs
== FS_HUNGRY
) /* Shutdown finished */
1111 return; /* The protocol might have ceased to exist */
1115 ASSERT(ops
== PS_DOWN
);
1116 ASSERT(cs
== FS_HUNGRY
);
1119 ASSERT(ops
== PS_DOWN
|| ops
== PS_START
);
1120 ASSERT(cs
== FS_HUNGRY
);
1121 proto_schedule_feed(p
, 1);
1125 if ((cs
== FS_FEEDING
) || (cs
== FS_HAPPY
))
1126 proto_schedule_flush(p
);
1129 bug("Invalid state transition for %s from %s/%s to */%s", p
->name
, c_states
[cs
], p_states
[ops
], p_states
[ps
]);
1138 proto_state_name(struct proto
*p
)
1140 #define P(x,y) ((x << 4) | y)
1141 switch (P(p
->proto_state
, p
->core_state
))
1143 case P(PS_DOWN
, FS_HUNGRY
): return "down";
1144 case P(PS_START
, FS_HUNGRY
): return "start";
1145 case P(PS_UP
, FS_HUNGRY
):
1146 case P(PS_UP
, FS_FEEDING
): return "feed";
1147 case P(PS_STOP
, FS_HUNGRY
): return "stop";
1148 case P(PS_UP
, FS_HAPPY
): return "up";
1149 case P(PS_STOP
, FS_FLUSHING
):
1150 case P(PS_DOWN
, FS_FLUSHING
): return "flush";
1151 default: return "???";
1157 proto_show_stats(struct proto_stats
*s
, int in_keep_filtered
)
1159 if (in_keep_filtered
)
1160 cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
1161 s
->imp_routes
, s
->filt_routes
, s
->exp_routes
, s
->pref_routes
);
1163 cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
1164 s
->imp_routes
, s
->exp_routes
, s
->pref_routes
);
1166 cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
1167 cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
1168 s
->imp_updates_received
, s
->imp_updates_invalid
,
1169 s
->imp_updates_filtered
, s
->imp_updates_ignored
,
1170 s
->imp_updates_accepted
);
1171 cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
1172 s
->imp_withdraws_received
, s
->imp_withdraws_invalid
,
1173 s
->imp_withdraws_ignored
, s
->imp_withdraws_accepted
);
1174 cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
1175 s
->exp_updates_received
, s
->exp_updates_rejected
,
1176 s
->exp_updates_filtered
, s
->exp_updates_accepted
);
1177 cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
1178 s
->exp_withdraws_received
, s
->exp_withdraws_accepted
);
1182 proto_show_limit(struct proto_limit
*l
, const char *dsc
)
1187 cli_msg(-1006, " %-16s%d%s", dsc
, l
->limit
, l
->state
? " [HIT]" : "");
1188 cli_msg(-1006, " Action: %s", proto_limit_name(l
));
1192 proto_show_basic_info(struct proto
*p
)
1194 // cli_msg(-1006, " Table: %s", p->table->name);
1195 cli_msg(-1006, " Preference: %d", p
->preference
);
1196 cli_msg(-1006, " Input filter: %s", filter_name(p
->cf
->in_filter
));
1197 cli_msg(-1006, " Output filter: %s", filter_name(p
->cf
->out_filter
));
1199 proto_show_limit(p
->cf
->rx_limit
, "Receive limit:");
1200 proto_show_limit(p
->cf
->in_limit
, "Import limit:");
1201 proto_show_limit(p
->cf
->out_limit
, "Export limit:");
1203 if (p
->proto_state
!= PS_DOWN
)
1204 proto_show_stats(&p
->stats
, p
->cf
->in_keep_filtered
);
1208 proto_cmd_show(struct proto
*p
, unsigned int verbose
, int cnt
)
1210 byte buf
[256], tbuf
[TM_DATETIME_BUFFER_SIZE
];
1212 /* First protocol - show header */
1214 cli_msg(-2002, "name proto table state since info");
1217 if (p
->proto
->get_status
)
1218 p
->proto
->get_status(p
, buf
);
1219 tm_format_datetime(tbuf
, &config
->tf_proto
, p
->last_state_change
);
1220 cli_msg(-1002, "%-8s %-8s %-8s %-5s %-10s %s",
1224 proto_state_name(p
),
1230 cli_msg(-1006, " Description: %s", p
->cf
->dsc
);
1231 if (p
->cf
->router_id
)
1232 cli_msg(-1006, " Router ID: %R", p
->cf
->router_id
);
1234 if (p
->proto
->show_proto_info
)
1235 p
->proto
->show_proto_info(p
);
1237 proto_show_basic_info(p
);
1244 proto_cmd_disable(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1248 cli_msg(-8, "%s: already disabled", p
->name
);
1252 log(L_INFO
"Disabling protocol %s", p
->name
);
1254 p
->down_code
= PDC_CMD_DISABLE
;
1255 proto_rethink_goal(p
);
1256 cli_msg(-9, "%s: disabled", p
->name
);
1260 proto_cmd_enable(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1264 cli_msg(-10, "%s: already enabled", p
->name
);
1268 log(L_INFO
"Enabling protocol %s", p
->name
);
1270 proto_rethink_goal(p
);
1271 cli_msg(-11, "%s: enabled", p
->name
);
1275 proto_cmd_restart(struct proto
*p
, unsigned int arg UNUSED
, int cnt UNUSED
)
1279 cli_msg(-8, "%s: already disabled", p
->name
);
1283 log(L_INFO
"Restarting protocol %s", p
->name
);
1285 p
->down_code
= PDC_CMD_RESTART
;
1286 proto_rethink_goal(p
);
1288 proto_rethink_goal(p
);
1289 cli_msg(-12, "%s: restarted", p
->name
);
1293 proto_cmd_reload(struct proto
*p
, unsigned int dir
, int cnt UNUSED
)
1297 cli_msg(-8, "%s: already disabled", p
->name
);
1301 /* If the protocol in not UP, it has no routes */
1302 if (p
->proto_state
!= PS_UP
)
1305 log(L_INFO
"Reloading protocol %s", p
->name
);
1307 /* re-importing routes */
1308 if (dir
!= CMD_RELOAD_OUT
)
1310 if (! (p
->reload_routes
&& p
->reload_routes(p
)))
1312 cli_msg(-8006, "%s: reload failed", p
->name
);
1317 * Should be done before reload_routes() hook?
1318 * Perhaps, but these hooks work asynchronously.
1320 if (!p
->proto
->multitable
)
1322 proto_reset_limit(p
->main_ahook
->rx_limit
);
1323 proto_reset_limit(p
->main_ahook
->in_limit
);
1327 /* re-exporting routes */
1328 if (dir
!= CMD_RELOAD_IN
)
1329 proto_request_feeding(p
);
1331 cli_msg(-15, "%s: reloading", p
->name
);
1335 proto_cmd_debug(struct proto
*p
, unsigned int mask
, int cnt UNUSED
)
1341 proto_cmd_mrtdump(struct proto
*p
, unsigned int mask
, int cnt UNUSED
)
1347 proto_apply_cmd_symbol(struct symbol
*s
, void (* cmd
)(struct proto
*, unsigned int, int), unsigned int arg
)
1349 if (s
->class != SYM_PROTO
)
1351 cli_msg(9002, "%s is not a protocol", s
->name
);
1355 cmd(((struct proto_config
*)s
->def
)->proto
, arg
, 0);
1360 proto_apply_cmd_patt(char *patt
, void (* cmd
)(struct proto
*, unsigned int, int), unsigned int arg
)
1365 WALK_LIST(nn
, proto_list
)
1367 struct proto
*p
= SKIP_BACK(struct proto
, glob_node
, nn
);
1369 if (!patt
|| patmatch(patt
, p
->name
))
1374 cli_msg(8003, "No protocols match");
1380 proto_apply_cmd(struct proto_spec ps
, void (* cmd
)(struct proto
*, unsigned int, int),
1381 int restricted
, unsigned int arg
)
1383 if (restricted
&& cli_access_restricted())
1387 proto_apply_cmd_patt(ps
.ptr
, cmd
, arg
);
1389 proto_apply_cmd_symbol(ps
.ptr
, cmd
, arg
);
1393 proto_get_named(struct symbol
*sym
, struct protocol
*pr
)
1395 struct proto
*p
, *q
;
1399 if (sym
->class != SYM_PROTO
)
1400 cf_error("%s: Not a protocol", sym
->name
);
1401 p
= ((struct proto_config
*)sym
->def
)->proto
;
1402 if (!p
|| p
->proto
!= pr
)
1403 cf_error("%s: Not a %s protocol", sym
->name
, pr
->name
);
1408 WALK_LIST(q
, active_proto_list
)
1412 cf_error("There are multiple %s protocols running", pr
->name
);
1416 cf_error("There is no %s protocol running", pr
->name
);