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/timer.h"
17 #include "lib/string.h"
18 #include "conf/conf.h"
19 #include "nest/route.h"
20 #include "nest/iface.h"
22 #include "filter/filter.h"
27 static list protocol_list
;
28 struct protocol
*class_to_protocol
[PROTOCOL__MAX
];
30 #define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0)
32 static timer
*proto_shutdown_timer
;
33 static timer
*gr_wait_timer
;
40 static int graceful_restart_state
;
41 static u32 graceful_restart_locks
;
43 static char *p_states
[] = { "DOWN", "START", "UP", "STOP" };
44 static char *c_states
[] = { "DOWN", "START", "UP", "FLUSHING" };
46 extern struct protocol proto_unix_iface
;
48 static void proto_shutdown_loop(timer
*);
49 static void proto_rethink_goal(struct proto
*p
);
50 static char *proto_state_name(struct proto
*p
);
51 static void channel_verify_limits(struct channel
*c
);
52 static inline void channel_reset_limit(struct channel_limit
*l
);
55 static inline int proto_is_done(struct proto
*p
)
56 { return (p
->proto_state
== PS_DOWN
) && (p
->active_channels
== 0); }
58 static inline int channel_is_active(struct channel
*c
)
59 { return (c
->channel_state
== CS_START
) || (c
->channel_state
== CS_UP
); }
62 proto_log_state_change(struct proto
*p
)
64 if (p
->debug
& D_STATES
)
66 char *name
= proto_state_name(p
);
67 if (name
!= p
->last_state_name_announced
)
69 p
->last_state_name_announced
= name
;
70 PD(p
, "State changed to %s", proto_state_name(p
));
74 p
->last_state_name_announced
= NULL
;
78 struct channel_config
*
79 proto_cf_find_channel(struct proto_config
*pc
, uint net_type
)
81 struct channel_config
*cc
;
83 WALK_LIST(cc
, pc
->channels
)
84 if (cc
->net_type
== net_type
)
91 * proto_find_channel_by_table - find channel connected to a routing table
92 * @p: protocol instance
95 * Returns pointer to channel or NULL
98 proto_find_channel_by_table(struct proto
*p
, struct rtable
*t
)
102 WALK_LIST(c
, p
->channels
)
110 * proto_find_channel_by_name - find channel by its name
111 * @p: protocol instance
114 * Returns pointer to channel or NULL
117 proto_find_channel_by_name(struct proto
*p
, const char *n
)
121 WALK_LIST(c
, p
->channels
)
122 if (!strcmp(c
->name
, n
))
129 * proto_add_channel - connect protocol to a routing table
130 * @p: protocol instance
131 * @cf: channel configuration
133 * This function creates a channel between the protocol instance @p and the
134 * routing table specified in the configuration @cf, making the protocol hear
135 * all changes in the table and allowing the protocol to update routes in the
138 * The channel is linked in the protocol channel list and when active also in
139 * the table channel list. Channels are allocated from the global resource pool
140 * (@proto_pool) and they are automatically freed when the protocol is removed.
144 proto_add_channel(struct proto
*p
, struct channel_config
*cf
)
146 struct channel
*c
= mb_allocz(proto_pool
, cf
->channel
->channel_size
);
149 c
->channel
= cf
->channel
;
151 c
->table
= cf
->table
->table
;
153 c
->in_filter
= cf
->in_filter
;
154 c
->out_filter
= cf
->out_filter
;
155 c
->rx_limit
= cf
->rx_limit
;
156 c
->in_limit
= cf
->in_limit
;
157 c
->out_limit
= cf
->out_limit
;
159 c
->net_type
= cf
->net_type
;
160 c
->ra_mode
= cf
->ra_mode
;
161 c
->preference
= cf
->preference
;
162 c
->merge_limit
= cf
->merge_limit
;
163 c
->in_keep_filtered
= cf
->in_keep_filtered
;
165 c
->channel_state
= CS_DOWN
;
166 c
->export_state
= ES_DOWN
;
167 c
->last_state_change
= current_time();
168 c
->last_tx_filter_change
= current_time();
171 CALL(c
->channel
->init
, c
, cf
);
173 add_tail(&p
->channels
, &c
->n
);
175 PD(p
, "Channel %s connected to table %s", c
->name
, c
->table
->name
);
181 proto_remove_channel(struct proto
*p
, struct channel
*c
)
183 ASSERT(c
->channel_state
== CS_DOWN
);
185 PD(p
, "Channel %s removed", c
->name
);
193 proto_start_channels(struct proto
*p
)
196 WALK_LIST(c
, p
->channels
)
198 channel_set_state(c
, CS_UP
);
202 proto_pause_channels(struct proto
*p
)
205 WALK_LIST(c
, p
->channels
)
206 if (!c
->disabled
&& channel_is_active(c
))
207 channel_set_state(c
, CS_START
);
211 proto_stop_channels(struct proto
*p
)
214 WALK_LIST(c
, p
->channels
)
215 if (!c
->disabled
&& channel_is_active(c
))
216 channel_set_state(c
, CS_FLUSHING
);
220 proto_remove_channels(struct proto
*p
)
223 WALK_LIST_FIRST(c
, p
->channels
)
224 proto_remove_channel(p
, c
);
228 channel_schedule_feed(struct channel
*c
, int initial
)
230 // DBG("%s: Scheduling meal\n", p->name);
231 ASSERT(c
->channel_state
== CS_UP
);
233 c
->export_state
= ES_FEEDING
;
234 c
->refeeding
= !initial
;
236 ev_schedule(c
->feed_event
);
240 channel_feed_loop(void *ptr
)
242 struct channel
*c
= ptr
;
244 if (c
->export_state
!= ES_FEEDING
)
248 if (c
->proto
->feed_begin
)
249 c
->proto
->feed_begin(c
, !c
->refeeding
);
251 // DBG("Feeding protocol %s continued\n", p->name);
252 if (!rt_feed_channel(c
))
254 ev_schedule(c
->feed_event
);
258 /* Reset export limit if the feed ended with acceptable number of exported routes */
259 struct channel_limit
*l
= &c
->out_limit
;
261 (l
->state
== PLS_BLOCKED
) &&
262 (c
->refeed_count
<= l
->limit
) &&
263 (c
->stats
.exp_routes
<= l
->limit
))
265 log(L_INFO
"Protocol %s resets route export limit (%u)", c
->proto
->name
, l
->limit
);
266 channel_reset_limit(&c
->out_limit
);
268 /* Continue in feed - it will process routing table again from beginning */
270 ev_schedule(c
->feed_event
);
274 // DBG("Feeding protocol %s finished\n", p->name);
275 c
->export_state
= ES_READY
;
276 // proto_log_state_change(p);
278 if (c
->proto
->feed_end
)
279 c
->proto
->feed_end(c
);
284 channel_start_export(struct channel
*c
)
286 ASSERT(c
->channel_state
== CS_UP
);
287 ASSERT(c
->export_state
== ES_DOWN
);
289 channel_schedule_feed(c
, 1); /* Sets ES_FEEDING */
293 channel_stop_export(struct channel
*c
)
295 /* Need to abort feeding */
296 if (c
->export_state
== ES_FEEDING
)
297 rt_feed_channel_abort(c
);
299 c
->export_state
= ES_DOWN
;
300 c
->stats
.exp_routes
= 0;
301 bmap_reset(&c
->export_map
, 1024);
305 /* Called by protocol for reload from in_table */
307 channel_schedule_reload(struct channel
*c
)
309 ASSERT(c
->channel_state
== CS_UP
);
311 rt_reload_channel_abort(c
);
312 ev_schedule(c
->reload_event
);
316 channel_reload_loop(void *ptr
)
318 struct channel
*c
= ptr
;
320 if (!rt_reload_channel(c
))
322 ev_schedule(c
->reload_event
);
328 channel_reset_import(struct channel
*c
)
330 /* Need to abort feeding */
331 ev_postpone(c
->reload_event
);
332 rt_reload_channel_abort(c
);
334 rt_prune_sync(c
->in_table
, 1);
338 channel_reset_export(struct channel
*c
)
340 /* Just free the routes */
341 rt_prune_sync(c
->out_table
, 1);
344 /* Called by protocol to activate in_table */
346 channel_setup_in_table(struct channel
*c
)
348 struct rtable_config
*cf
= mb_allocz(c
->proto
->pool
, sizeof(struct rtable_config
));
350 cf
->addr_type
= c
->net_type
;
352 c
->in_table
= mb_allocz(c
->proto
->pool
, sizeof(struct rtable
));
353 rt_setup(c
->proto
->pool
, c
->in_table
, cf
);
355 c
->reload_event
= ev_new_init(c
->proto
->pool
, channel_reload_loop
, c
);
358 /* Called by protocol to activate out_table */
360 channel_setup_out_table(struct channel
*c
)
362 struct rtable_config
*cf
= mb_allocz(c
->proto
->pool
, sizeof(struct rtable_config
));
364 cf
->addr_type
= c
->net_type
;
366 c
->out_table
= mb_allocz(c
->proto
->pool
, sizeof(struct rtable
));
367 rt_setup(c
->proto
->pool
, c
->out_table
, cf
);
372 channel_do_start(struct channel
*c
)
374 rt_lock_table(c
->table
);
375 add_tail(&c
->table
->channels
, &c
->table_node
);
376 c
->proto
->active_channels
++;
378 c
->feed_event
= ev_new_init(c
->proto
->pool
, channel_feed_loop
, c
);
380 bmap_init(&c
->export_map
, c
->proto
->pool
, 1024);
381 memset(&c
->stats
, 0, sizeof(struct proto_stats
));
383 channel_reset_limit(&c
->rx_limit
);
384 channel_reset_limit(&c
->in_limit
);
385 channel_reset_limit(&c
->out_limit
);
387 CALL(c
->channel
->start
, c
);
391 channel_do_flush(struct channel
*c
)
393 rt_schedule_prune(c
->table
);
397 channel_graceful_restart_unlock(c
);
399 CALL(c
->channel
->shutdown
, c
);
401 /* This have to be done in here, as channel pool is freed before channel_do_down() */
402 bmap_free(&c
->export_map
);
404 c
->reload_event
= NULL
;
409 channel_do_down(struct channel
*c
)
411 ASSERT(!c
->feed_active
&& !c
->reload_active
);
413 rem_node(&c
->table_node
);
414 rt_unlock_table(c
->table
);
415 c
->proto
->active_channels
--;
417 if ((c
->stats
.imp_routes
+ c
->stats
.filt_routes
) != 0)
418 log(L_ERR
"%s: Channel %s is down but still has some routes", c
->proto
->name
, c
->name
);
420 // bmap_free(&c->export_map);
421 memset(&c
->stats
, 0, sizeof(struct proto_stats
));
424 c
->reload_event
= NULL
;
427 CALL(c
->channel
->cleanup
, c
);
429 /* Schedule protocol shutddown */
430 if (proto_is_done(c
->proto
))
431 ev_schedule(c
->proto
->event
);
435 channel_set_state(struct channel
*c
, uint state
)
437 uint cs
= c
->channel_state
;
438 uint es
= c
->export_state
;
440 DBG("%s reporting channel %s state transition %s -> %s\n", c
->proto
->name
, c
->name
, c_states
[cs
], c_states
[state
]);
444 c
->channel_state
= state
;
445 c
->last_state_change
= current_time();
450 ASSERT(cs
== CS_DOWN
|| cs
== CS_UP
);
456 channel_stop_export(c
);
458 if (c
->in_table
&& (cs
== CS_UP
))
459 channel_reset_import(c
);
461 if (c
->out_table
&& (cs
== CS_UP
))
462 channel_reset_export(c
);
467 ASSERT(cs
== CS_DOWN
|| cs
== CS_START
);
472 if (!c
->gr_wait
&& c
->proto
->rt_notify
)
473 channel_start_export(c
);
478 ASSERT(cs
== CS_START
|| cs
== CS_UP
);
481 channel_stop_export(c
);
483 if (c
->in_table
&& (cs
== CS_UP
))
484 channel_reset_import(c
);
486 if (c
->out_table
&& (cs
== CS_UP
))
487 channel_reset_export(c
);
493 ASSERT(cs
== CS_FLUSHING
);
501 // XXXX proto_log_state_change(c);
505 * channel_request_feeding - request feeding routes to the channel
508 * Sometimes it is needed to send again all routes to the channel. This is
509 * called feeding and can be requested by this function. This would cause
510 * channel export state transition to ES_FEEDING (during feeding) and when
511 * completed, it will switch back to ES_READY. This function can be called
512 * even when feeding is already running, in that case it is restarted.
515 channel_request_feeding(struct channel
*c
)
517 ASSERT(c
->channel_state
== CS_UP
);
519 /* Do nothing if we are still waiting for feeding */
520 if (c
->export_state
== ES_DOWN
)
523 /* If we are already feeding, we want to restart it */
524 if (c
->export_state
== ES_FEEDING
)
526 /* Unless feeding is in initial state */
530 rt_feed_channel_abort(c
);
533 /* Track number of exported routes during refeed */
536 channel_schedule_feed(c
, 0); /* Sets ES_FEEDING */
537 // proto_log_state_change(c);
541 channel_reloadable(struct channel
*c
)
543 return c
->proto
->reload_routes
&& c
->reloadable
;
547 channel_request_reload(struct channel
*c
)
549 ASSERT(c
->channel_state
== CS_UP
);
550 ASSERT(channel_reloadable(c
));
552 c
->proto
->reload_routes(c
);
555 * Should this be done before reload_routes() hook?
556 * Perhaps, but routes are updated asynchronously.
558 channel_reset_limit(&c
->rx_limit
);
559 channel_reset_limit(&c
->in_limit
);
562 const struct channel_class channel_basic
= {
563 .channel_size
= sizeof(struct channel
),
564 .config_size
= sizeof(struct channel_config
)
568 channel_config_new(const struct channel_class
*cc
, const char *name
, uint net_type
, struct proto_config
*proto
)
570 struct channel_config
*cf
= NULL
;
571 struct rtable_config
*tab
= NULL
;
575 if (!net_val_match(net_type
, proto
->protocol
->channel_mask
))
576 cf_error("Unsupported channel type");
578 if (proto
->net_type
&& (net_type
!= proto
->net_type
))
579 cf_error("Different channel type");
581 tab
= new_config
->def_tables
[net_type
];
587 cf
= cfg_allocz(cc
->config_size
);
592 cf
->out_filter
= FILTER_REJECT
;
594 cf
->net_type
= net_type
;
595 cf
->ra_mode
= RA_OPTIMAL
;
596 cf
->preference
= proto
->protocol
->preference
;
598 add_tail(&proto
->channels
, &cf
->n
);
604 channel_config_get(const struct channel_class
*cc
, const char *name
, uint net_type
, struct proto_config
*proto
)
606 struct channel_config
*cf
;
608 /* We are using name as token, so no strcmp() */
609 WALK_LIST(cf
, proto
->channels
)
610 if (cf
->name
== name
)
612 /* Allow to redefine channel only if inherited from template */
613 if (cf
->parent
== proto
)
614 cf_error("Multiple %s channels", name
);
620 return channel_config_new(cc
, name
, net_type
, proto
);
623 struct channel_config
*
624 channel_copy_config(struct channel_config
*src
, struct proto_config
*proto
)
626 struct channel_config
*dst
= cfg_alloc(src
->channel
->config_size
);
628 memcpy(dst
, src
, src
->channel
->config_size
);
629 add_tail(&proto
->channels
, &dst
->n
);
630 CALL(src
->channel
->copy_config
, dst
, src
);
636 static int reconfigure_type
; /* Hack to propagate type info to channel_reconfigure() */
639 channel_reconfigure(struct channel
*c
, struct channel_config
*cf
)
641 /* FIXME: better handle these changes, also handle in_keep_filtered */
642 if ((c
->table
!= cf
->table
->table
) || (cf
->ra_mode
&& (c
->ra_mode
!= cf
->ra_mode
)))
645 /* Note that filter_same() requires arguments in (new, old) order */
646 int import_changed
= !filter_same(cf
->in_filter
, c
->in_filter
);
647 int export_changed
= !filter_same(cf
->out_filter
, c
->out_filter
);
649 if (c
->preference
!= cf
->preference
)
652 if (c
->merge_limit
!= cf
->merge_limit
)
655 /* Reconfigure channel fields */
656 c
->in_filter
= cf
->in_filter
;
657 c
->out_filter
= cf
->out_filter
;
658 c
->rx_limit
= cf
->rx_limit
;
659 c
->in_limit
= cf
->in_limit
;
660 c
->out_limit
= cf
->out_limit
;
662 // c->ra_mode = cf->ra_mode;
663 c
->merge_limit
= cf
->merge_limit
;
664 c
->preference
= cf
->preference
;
665 c
->in_keep_filtered
= cf
->in_keep_filtered
;
667 channel_verify_limits(c
);
670 c
->last_tx_filter_change
= current_time();
672 /* Execute channel-specific reconfigure hook */
673 if (c
->channel
->reconfigure
&& !c
->channel
->reconfigure(c
, cf
, &import_changed
, &export_changed
))
676 /* If the channel is not open, it has no routes and we cannot reload it anyways */
677 if (c
->channel_state
!= CS_UP
)
680 if (reconfigure_type
== RECONFIG_SOFT
)
683 log(L_INFO
"Channel %s.%s changed import", c
->proto
->name
, c
->name
);
686 log(L_INFO
"Channel %s.%s changed export", c
->proto
->name
, c
->name
);
691 /* Route reload may be not supported */
692 if (import_changed
&& !channel_reloadable(c
))
695 if (import_changed
|| export_changed
)
696 log(L_INFO
"Reloading channel %s.%s", c
->proto
->name
, c
->name
);
699 channel_request_reload(c
);
702 channel_request_feeding(c
);
709 proto_configure_channel(struct proto
*p
, struct channel
**pc
, struct channel_config
*cf
)
711 struct channel
*c
= *pc
;
715 /* We could add the channel, but currently it would just stay in down state
716 until protocol is restarted, so it is better to force restart anyways. */
717 if (p
->proto_state
!= PS_DOWN
)
719 log(L_INFO
"Cannot add channel %s.%s", p
->name
, cf
->name
);
723 *pc
= proto_add_channel(p
, cf
);
727 if (c
->channel_state
!= CS_DOWN
)
729 log(L_INFO
"Cannot remove channel %s.%s", c
->proto
->name
, c
->name
);
733 proto_remove_channel(p
, c
);
738 if (!channel_reconfigure(c
, cf
))
740 log(L_INFO
"Cannot reconfigure channel %s.%s", c
->proto
->name
, c
->name
);
750 proto_event(void *ptr
)
752 struct proto
*p
= ptr
;
762 if (p
->proto
== &proto_unix_iface
)
767 if (proto_is_done(p
))
769 if (p
->proto
->cleanup
)
770 p
->proto
->cleanup(p
);
773 proto_log_state_change(p
);
774 proto_rethink_goal(p
);
780 * proto_new - create a new protocol instance
781 * @c: protocol configuration
783 * When a new configuration has been read in, the core code starts
784 * initializing all the protocol instances configured by calling their
785 * init() hooks with the corresponding instance configuration. The initialization
786 * code of the protocol is expected to create a new instance according to the
787 * configuration by calling this function and then modifying the default settings
788 * to values wanted by the protocol.
791 proto_new(struct proto_config
*cf
)
793 struct proto
*p
= mb_allocz(proto_pool
, cf
->protocol
->proto_size
);
796 p
->debug
= cf
->debug
;
797 p
->mrtdump
= cf
->mrtdump
;
799 p
->proto
= cf
->protocol
;
800 p
->net_type
= cf
->net_type
;
801 p
->disabled
= cf
->disabled
;
802 p
->hash_key
= random_u32();
805 init_list(&p
->channels
);
810 static struct proto
*
811 proto_init(struct proto_config
*c
, node
*n
)
813 struct protocol
*pr
= c
->protocol
;
814 struct proto
*p
= pr
->init(c
);
816 p
->proto_state
= PS_DOWN
;
817 p
->last_state_change
= current_time();
819 p
->vrf_set
= c
->vrf_set
;
820 insert_node(&p
->n
, n
);
822 p
->event
= ev_new_init(proto_pool
, proto_event
, p
);
824 PD(p
, "Initializing%s", p
->disabled
? " [disabled]" : "");
830 proto_start(struct proto
*p
)
832 /* Here we cannot use p->cf->name since it won't survive reconfiguration */
833 p
->pool
= rp_new(proto_pool
, p
->proto
->name
);
835 if (graceful_restart_state
== GRS_INIT
)
841 * proto_config_new - create a new protocol configuration
842 * @pr: protocol the configuration will belong to
843 * @class: SYM_PROTO or SYM_TEMPLATE
845 * Whenever the configuration file says that a new instance
846 * of a routing protocol should be created, the parser calls
847 * proto_config_new() to create a configuration entry for this
848 * instance (a structure staring with the &proto_config header
849 * containing all the generic items followed by protocol-specific
850 * ones). Also, the configuration entry gets added to the list
851 * of protocol instances kept in the configuration.
853 * The function is also used to create protocol templates (when class
854 * SYM_TEMPLATE is specified), the only difference is that templates
855 * are not added to the list of protocol instances and therefore not
856 * initialized during protos_commit()).
859 proto_config_new(struct protocol
*pr
, int class)
861 struct proto_config
*cf
= cfg_allocz(pr
->config_size
);
863 if (class == SYM_PROTO
)
864 add_tail(&new_config
->protos
, &cf
->n
);
866 cf
->global
= new_config
;
870 cf
->debug
= new_config
->proto_default_debug
;
871 cf
->mrtdump
= new_config
->proto_default_mrtdump
;
873 init_list(&cf
->channels
);
880 * proto_copy_config - copy a protocol configuration
881 * @dest: destination protocol configuration
882 * @src: source protocol configuration
884 * Whenever a new instance of a routing protocol is created from the
885 * template, proto_copy_config() is called to copy a content of
886 * the source protocol configuration to the new protocol configuration.
887 * Name, class and a node in protos list of @dest are kept intact.
888 * copy_config() protocol hook is used to copy protocol-specific data.
891 proto_copy_config(struct proto_config
*dest
, struct proto_config
*src
)
893 struct channel_config
*cc
;
898 if (dest
->protocol
!= src
->protocol
)
899 cf_error("Can't copy configuration from a different protocol type");
901 if (dest
->protocol
->copy_config
== NULL
)
902 cf_error("Inheriting configuration for %s is not supported", src
->protocol
->name
);
904 DBG("Copying configuration from %s to %s\n", src
->name
, dest
->name
);
907 * Copy struct proto_config here. Keep original node, class and name.
908 * protocol-specific config copy is handled by protocol copy_config() hook
912 old_class
= dest
->class;
913 old_name
= dest
->name
;
915 memcpy(dest
, src
, src
->protocol
->config_size
);
918 dest
->class = old_class
;
919 dest
->name
= old_name
;
920 init_list(&dest
->channels
);
922 WALK_LIST(cc
, src
->channels
)
923 channel_copy_config(cc
, dest
);
925 /* FIXME: allow for undefined copy_config */
926 dest
->protocol
->copy_config(dest
, src
);
930 proto_clone_config(struct symbol
*sym
, struct proto_config
*parent
)
932 struct proto_config
*cf
= proto_config_new(parent
->protocol
, SYM_PROTO
);
933 proto_copy_config(cf
, parent
);
934 cf
->name
= sym
->name
;
938 sym
->class = cf
->class;
943 proto_undef_clone(struct symbol
*sym
, struct proto_config
*cf
)
947 sym
->class = SYM_VOID
;
952 * protos_preconfig - pre-configuration processing
953 * @c: new configuration
955 * This function calls the preconfig() hooks of all routing
956 * protocols available to prepare them for reading of the new
960 protos_preconfig(struct config
*c
)
964 init_list(&c
->protos
);
965 DBG("Protocol preconfig:");
966 WALK_LIST(p
, protocol_list
)
977 proto_reconfigure(struct proto
*p
, struct proto_config
*oc
, struct proto_config
*nc
, int type
)
979 /* If the protocol is DOWN, we just restart it */
980 if (p
->proto_state
== PS_DOWN
)
983 /* If there is a too big change in core attributes, ... */
984 if ((nc
->protocol
!= oc
->protocol
) ||
985 (nc
->net_type
!= oc
->net_type
) ||
986 (nc
->disabled
!= p
->disabled
) ||
987 (nc
->vrf
!= oc
->vrf
) ||
988 (nc
->vrf_set
!= oc
->vrf_set
))
992 p
->debug
= nc
->debug
;
993 p
->mrtdump
= nc
->mrtdump
;
994 reconfigure_type
= type
;
996 /* Execute protocol specific reconfigure hook */
997 if (!p
->proto
->reconfigure
|| !p
->proto
->reconfigure(p
, nc
))
1000 DBG("\t%s: same\n", oc
->name
);
1001 PD(p
, "Reconfigured");
1008 * protos_commit - commit new protocol configuration
1009 * @new: new configuration
1010 * @old: old configuration or %NULL if it's boot time config
1011 * @force_reconfig: force restart of all protocols (used for example
1012 * when the router ID changes)
1013 * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
1015 * Scan differences between @old and @new configuration and adjust all
1016 * protocol instances to conform to the new configuration.
1018 * When a protocol exists in the new configuration, but it doesn't in the
1019 * original one, it's immediately started. When a collision with the other
1020 * running protocol would arise, the new protocol will be temporarily stopped
1021 * by the locking mechanism.
1023 * When a protocol exists in the old configuration, but it doesn't in the
1024 * new one, it's shut down and deleted after the shutdown completes.
1026 * When a protocol exists in both configurations, the core decides
1027 * whether it's possible to reconfigure it dynamically - it checks all
1028 * the core properties of the protocol (changes in filters are ignored
1029 * if type is RECONFIG_SOFT) and if they match, it asks the
1030 * reconfigure() hook of the protocol to see if the protocol is able
1031 * to switch to the new configuration. If it isn't possible, the
1032 * protocol is shut down and a new instance is started with the new
1033 * configuration after the shutdown is completed.
1036 protos_commit(struct config
*new, struct config
*old
, int force_reconfig
, int type
)
1038 struct proto_config
*oc
, *nc
;
1044 DBG("protos_commit:\n");
1047 WALK_LIST(oc
, old
->protos
)
1050 sym
= cf_find_symbol(new, oc
->name
);
1052 /* Handle dynamic protocols */
1053 if (!sym
&& oc
->parent
&& !new->shutdown
)
1055 struct symbol
*parsym
= cf_find_symbol(new, oc
->parent
->name
);
1056 if (parsym
&& parsym
->class == SYM_PROTO
)
1058 /* This is hack, we would like to share config, but we need to copy it now */
1061 conf_this_scope
= new->root_scope
;
1062 sym
= cf_get_symbol(oc
->name
);
1063 proto_clone_config(sym
, parsym
->proto
);
1069 if (sym
&& sym
->class == SYM_PROTO
&& !new->shutdown
)
1071 /* Found match, let's check if we can smoothly switch to new configuration */
1072 /* No need to check description */
1076 /* We will try to reconfigure protocol p */
1077 if (! force_reconfig
&& proto_reconfigure(p
, oc
, nc
, type
))
1082 proto_undef_clone(sym
, nc
);
1086 /* Unsuccessful, we will restart it */
1087 if (!p
->disabled
&& !nc
->disabled
)
1088 log(L_INFO
"Restarting protocol %s", p
->name
);
1089 else if (p
->disabled
&& !nc
->disabled
)
1090 log(L_INFO
"Enabling protocol %s", p
->name
);
1091 else if (!p
->disabled
&& nc
->disabled
)
1092 log(L_INFO
"Disabling protocol %s", p
->name
);
1094 p
->down_code
= nc
->disabled
? PDC_CF_DISABLE
: PDC_CF_RESTART
;
1097 else if (!new->shutdown
)
1100 log(L_INFO
"Removing protocol %s", p
->name
);
1101 p
->down_code
= PDC_CF_REMOVE
;
1104 else if (new->gr_down
)
1106 p
->down_code
= PDC_CMD_GR_DOWN
;
1109 else /* global shutdown */
1111 p
->down_code
= PDC_CMD_SHUTDOWN
;
1115 p
->reconfiguring
= 1;
1116 config_add_obstacle(old
);
1117 proto_rethink_goal(p
);
1121 struct proto
*first_dev_proto
= NULL
;
1123 n
= NODE
&(proto_list
.head
);
1124 WALK_LIST(nc
, new->protos
)
1127 /* Not a first-time configuration */
1129 log(L_INFO
"Adding protocol %s", nc
->name
);
1131 p
= proto_init(nc
, n
);
1134 if (p
->proto
== &proto_unix_iface
)
1135 first_dev_proto
= p
;
1140 DBG("Protocol start\n");
1142 /* Start device protocol first */
1143 if (first_dev_proto
)
1144 proto_rethink_goal(first_dev_proto
);
1146 /* Determine router ID for the first time - it has to be here and not in
1147 global_commit() because it is postponed after start of device protocol */
1148 if (!config
->router_id
)
1150 config
->router_id
= if_choose_router_id(config
->router_id_from
, 0);
1151 if (!config
->router_id
)
1152 die("Cannot determine router ID, please configure it manually");
1155 /* Start all new protocols */
1156 WALK_LIST_DELSAFE(p
, n
, proto_list
)
1157 proto_rethink_goal(p
);
1161 proto_rethink_goal(struct proto
*p
)
1166 if (p
->reconfiguring
&& !p
->active
)
1168 struct proto_config
*nc
= p
->cf_new
;
1169 node
*n
= p
->n
.prev
;
1170 DBG("%s has shut down for reconfiguration\n", p
->name
);
1171 p
->cf
->proto
= NULL
;
1172 config_del_obstacle(p
->cf
->global
);
1173 proto_remove_channels(p
);
1176 mb_free(p
->message
);
1180 p
= proto_init(nc
, n
);
1183 /* Determine what state we want to reach */
1184 if (p
->disabled
|| p
->reconfiguring
)
1195 DBG("Kicking %s up\n", p
->name
);
1198 proto_notify_state(p
, (q
->start
? q
->start(p
) : PS_UP
));
1203 if (p
->proto_state
== PS_START
|| p
->proto_state
== PS_UP
)
1206 DBG("Kicking %s down\n", p
->name
);
1207 PD(p
, "Shutting down");
1208 proto_notify_state(p
, (q
->shutdown
? q
->shutdown(p
) : PS_DOWN
));
1214 proto_spawn(struct proto_config
*cf
, uint disabled
)
1216 struct proto
*p
= proto_init(cf
, TAIL(proto_list
));
1217 p
->disabled
= disabled
;
1218 proto_rethink_goal(p
);
1224 * DOC: Graceful restart recovery
1226 * Graceful restart of a router is a process when the routing plane (e.g. BIRD)
1227 * restarts but both the forwarding plane (e.g kernel routing table) and routing
1228 * neighbors keep proper routes, and therefore uninterrupted packet forwarding
1231 * BIRD implements graceful restart recovery by deferring export of routes to
1232 * protocols until routing tables are refilled with the expected content. After
1233 * start, protocols generate routes as usual, but routes are not propagated to
1234 * them, until protocols report that they generated all routes. After that,
1235 * graceful restart recovery is finished and the export (and the initial feed)
1236 * to protocols is enabled.
1238 * When graceful restart recovery need is detected during initialization, then
1239 * enabled protocols are marked with @gr_recovery flag before start. Such
1240 * protocols then decide how to proceed with graceful restart, participation is
1241 * voluntary. Protocols could lock the recovery for each channel by function
1242 * channel_graceful_restart_lock() (state stored in @gr_lock flag), which means
1243 * that they want to postpone the end of the recovery until they converge and
1244 * then unlock it. They also could set @gr_wait before advancing to %PS_UP,
1245 * which means that the core should defer route export to that channel until
1246 * the end of the recovery. This should be done by protocols that expect their
1247 * neigbors to keep the proper routes (kernel table, BGP sessions with BGP
1248 * graceful restart capability).
1250 * The graceful restart recovery is finished when either all graceful restart
1251 * locks are unlocked or when graceful restart wait timer fires.
1255 static void graceful_restart_done(timer
*t
);
1258 * graceful_restart_recovery - request initial graceful restart recovery
1260 * Called by the platform initialization code if the need for recovery
1261 * after graceful restart is detected during boot. Have to be called
1262 * before protos_commit().
1265 graceful_restart_recovery(void)
1267 graceful_restart_state
= GRS_INIT
;
1271 * graceful_restart_init - initialize graceful restart
1273 * When graceful restart recovery was requested, the function starts an active
1274 * phase of the recovery and initializes graceful restart wait timer. The
1275 * function have to be called after protos_commit().
1278 graceful_restart_init(void)
1280 if (!graceful_restart_state
)
1283 log(L_INFO
"Graceful restart started");
1285 if (!graceful_restart_locks
)
1287 graceful_restart_done(NULL
);
1291 graceful_restart_state
= GRS_ACTIVE
;
1292 gr_wait_timer
= tm_new_init(proto_pool
, graceful_restart_done
, NULL
, 0, 0);
1293 tm_start(gr_wait_timer
, config
->gr_wait S
);
1297 * graceful_restart_done - finalize graceful restart
1300 * When there are no locks on graceful restart, the functions finalizes the
1301 * graceful restart recovery. Protocols postponing route export until the end of
1302 * the recovery are awakened and the export to them is enabled. All other
1303 * related state is cleared. The function is also called when the graceful
1304 * restart wait timer fires (but there are still some locks).
1307 graceful_restart_done(timer
*t UNUSED
)
1309 log(L_INFO
"Graceful restart done");
1310 graceful_restart_state
= GRS_DONE
;
1313 WALK_LIST(p
, proto_list
)
1315 if (!p
->gr_recovery
)
1319 WALK_LIST(c
, p
->channels
)
1321 /* Resume postponed export of routes */
1322 if ((c
->channel_state
== CS_UP
) && c
->gr_wait
&& c
->proto
->rt_notify
)
1323 channel_start_export(c
);
1333 graceful_restart_locks
= 0;
1337 graceful_restart_show_status(void)
1339 if (graceful_restart_state
!= GRS_ACTIVE
)
1342 cli_msg(-24, "Graceful restart recovery in progress");
1343 cli_msg(-24, " Waiting for %d channels to recover", graceful_restart_locks
);
1344 cli_msg(-24, " Wait timer is %t/%u", tm_remains(gr_wait_timer
), config
->gr_wait
);
1348 * channel_graceful_restart_lock - lock graceful restart by channel
1349 * @p: channel instance
1351 * This function allows a protocol to postpone the end of graceful restart
1352 * recovery until it converges. The lock is removed when the protocol calls
1353 * channel_graceful_restart_unlock() or when the channel is closed.
1355 * The function have to be called during the initial phase of graceful restart
1356 * recovery and only for protocols that are part of graceful restart (i.e. their
1357 * @gr_recovery is set), which means it should be called from protocol start
1361 channel_graceful_restart_lock(struct channel
*c
)
1363 ASSERT(graceful_restart_state
== GRS_INIT
);
1364 ASSERT(c
->proto
->gr_recovery
);
1370 graceful_restart_locks
++;
1374 * channel_graceful_restart_unlock - unlock graceful restart by channel
1375 * @p: channel instance
1377 * This function unlocks a lock from channel_graceful_restart_lock(). It is also
1378 * automatically called when the lock holding protocol went down.
1381 channel_graceful_restart_unlock(struct channel
*c
)
1387 graceful_restart_locks
--;
1389 if ((graceful_restart_state
== GRS_ACTIVE
) && !graceful_restart_locks
)
1390 tm_start(gr_wait_timer
, 0);
1396 * protos_dump_all - dump status of all protocols
1398 * This function dumps status of all existing protocol instances to the
1399 * debug output. It involves printing of general status information
1400 * such as protocol states, its position on the protocol lists
1401 * and also calling of a dump() hook of the protocol to print
1405 protos_dump_all(void)
1407 debug("Protocols:\n");
1410 WALK_LIST(p
, proto_list
)
1412 debug(" protocol %s state %s\n", p
->name
, p_states
[p
->proto_state
]);
1415 WALK_LIST(c
, p
->channels
)
1417 debug("\tTABLE %s\n", c
->table
->name
);
1419 debug("\tInput filter: %s\n", filter_name(c
->in_filter
));
1421 debug("\tOutput filter: %s\n", filter_name(c
->out_filter
));
1424 if (p
->proto
->dump
&& (p
->proto_state
!= PS_DOWN
))
1430 * proto_build - make a single protocol available
1433 * After the platform specific initialization code uses protos_build()
1434 * to add all the standard protocols, it should call proto_build() for
1435 * all platform specific protocols to inform the core that they exist.
1438 proto_build(struct protocol
*p
)
1440 add_tail(&protocol_list
, &p
->n
);
1442 ASSERT(!class_to_protocol
[p
->class]);
1443 class_to_protocol
[p
->class] = p
;
1446 /* FIXME: convert this call to some protocol hook */
1447 extern void bfd_init_all(void);
1450 * protos_build - build a protocol list
1452 * This function is called during BIRD startup to insert
1453 * all standard protocols to the global protocol list. Insertion
1454 * of platform specific protocols (such as the kernel syncer)
1455 * is in the domain of competence of the platform dependent
1461 init_list(&proto_list
);
1462 init_list(&protocol_list
);
1464 proto_build(&proto_device
);
1466 proto_build(&proto_radv
);
1469 proto_build(&proto_rip
);
1471 #ifdef CONFIG_STATIC
1472 proto_build(&proto_static
);
1475 proto_build(&proto_mrt
);
1478 proto_build(&proto_ospf
);
1481 proto_build(&proto_pipe
);
1484 proto_build(&proto_bgp
);
1487 proto_build(&proto_bfd
);
1491 proto_build(&proto_babel
);
1494 proto_build(&proto_rpki
);
1497 proto_build(&proto_perf
);
1500 proto_pool
= rp_new(&root_pool
, "Protocols");
1501 proto_shutdown_timer
= tm_new(proto_pool
);
1502 proto_shutdown_timer
->hook
= proto_shutdown_loop
;
1506 /* Temporary hack to propagate restart to BGP */
1510 proto_shutdown_loop(timer
*t UNUSED
)
1512 struct proto
*p
, *p_next
;
1514 WALK_LIST_DELSAFE(p
, p_next
, proto_list
)
1517 proto_restart
= (p
->down_sched
== PDS_RESTART
);
1520 proto_rethink_goal(p
);
1524 proto_rethink_goal(p
);
1530 proto_schedule_down(struct proto
*p
, byte restart
, byte code
)
1532 /* Does not work for other states (even PS_START) */
1533 ASSERT(p
->proto_state
== PS_UP
);
1535 /* Scheduled restart may change to shutdown, but not otherwise */
1536 if (p
->down_sched
== PDS_DISABLE
)
1539 p
->down_sched
= restart
? PDS_RESTART
: PDS_DISABLE
;
1540 p
->down_code
= code
;
1541 tm_start_max(proto_shutdown_timer
, restart
? 250 MS
: 0);
1545 * proto_set_message - set administrative message to protocol
1548 * @len: message length (-1 for NULL-terminated string)
1550 * The function sets administrative message (string) related to protocol state
1551 * change. It is called by the nest code for manual enable/disable/restart
1552 * commands all routes to the protocol, and by protocol-specific code when the
1553 * protocol state change is initiated by the protocol. Using NULL message clears
1554 * the last message. The message string may be either NULL-terminated or with an
1558 proto_set_message(struct proto
*p
, char *msg
, int len
)
1560 mb_free(p
->message
);
1572 p
->message
= mb_alloc(proto_pool
, len
+ 1);
1573 memcpy(p
->message
, msg
, len
);
1574 p
->message
[len
] = 0;
1579 channel_limit_name(struct channel_limit
*l
)
1581 const char *actions
[] = {
1582 [PLA_WARN
] = "warn",
1583 [PLA_BLOCK
] = "block",
1584 [PLA_RESTART
] = "restart",
1585 [PLA_DISABLE
] = "disable",
1588 return actions
[l
->action
];
1592 * channel_notify_limit: notify about limit hit and take appropriate action
1594 * @l: limit being hit
1595 * @dir: limit direction (PLD_*)
1596 * @rt_count: the number of routes
1598 * The function is called by the route processing core when limit @l
1599 * is breached. It activates the limit and tooks appropriate action
1600 * according to @l->action.
1603 channel_notify_limit(struct channel
*c
, struct channel_limit
*l
, int dir
, u32 rt_count
)
1605 const char *dir_name
[PLD_MAX
] = { "receive", "import" , "export" };
1606 const byte dir_down
[PLD_MAX
] = { PDC_RX_LIMIT_HIT
, PDC_IN_LIMIT_HIT
, PDC_OUT_LIMIT_HIT
};
1607 struct proto
*p
= c
->proto
;
1609 if (l
->state
== PLS_BLOCKED
)
1612 /* For warning action, we want the log message every time we hit the limit */
1613 if (!l
->state
|| ((l
->action
== PLA_WARN
) && (rt_count
== l
->limit
)))
1614 log(L_WARN
"Protocol %s hits route %s limit (%d), action: %s",
1615 p
->name
, dir_name
[dir
], l
->limit
, channel_limit_name(l
));
1620 l
->state
= PLS_ACTIVE
;
1624 l
->state
= PLS_BLOCKED
;
1629 l
->state
= PLS_BLOCKED
;
1630 if (p
->proto_state
== PS_UP
)
1631 proto_schedule_down(p
, l
->action
== PLA_RESTART
, dir_down
[dir
]);
1637 channel_verify_limits(struct channel
*c
)
1639 struct channel_limit
*l
;
1640 u32 all_routes
= c
->stats
.imp_routes
+ c
->stats
.filt_routes
;
1643 if (l
->action
&& (all_routes
> l
->limit
))
1644 channel_notify_limit(c
, l
, PLD_RX
, all_routes
);
1647 if (l
->action
&& (c
->stats
.imp_routes
> l
->limit
))
1648 channel_notify_limit(c
, l
, PLD_IN
, c
->stats
.imp_routes
);
1651 if (l
->action
&& (c
->stats
.exp_routes
> l
->limit
))
1652 channel_notify_limit(c
, l
, PLD_OUT
, c
->stats
.exp_routes
);
1656 channel_reset_limit(struct channel_limit
*l
)
1659 l
->state
= PLS_INITIAL
;
1663 proto_do_start(struct proto
*p
)
1667 ev_schedule(p
->event
);
1671 proto_do_up(struct proto
*p
)
1673 if (!p
->main_source
)
1675 p
->main_source
= rt_get_source(p
, 0);
1676 rt_lock_source(p
->main_source
);
1679 proto_start_channels(p
);
1683 proto_do_pause(struct proto
*p
)
1685 proto_pause_channels(p
);
1689 proto_do_stop(struct proto
*p
)
1695 ev_schedule(p
->event
);
1699 rt_unlock_source(p
->main_source
);
1700 p
->main_source
= NULL
;
1703 proto_stop_channels(p
);
1707 proto_do_down(struct proto
*p
)
1714 /* Shutdown is finished in the protocol event */
1715 if (proto_is_done(p
))
1716 ev_schedule(p
->event
);
1722 * proto_notify_state - notify core about protocol state change
1723 * @p: protocol the state of which has changed
1724 * @ps: the new status
1726 * Whenever a state of a protocol changes due to some event internal
1727 * to the protocol (i.e., not inside a start() or shutdown() hook),
1728 * it should immediately notify the core about the change by calling
1729 * proto_notify_state() which will write the new state to the &proto
1730 * structure and take all the actions necessary to adapt to the new
1731 * state. State change to PS_DOWN immediately frees resources of protocol
1732 * and might execute start callback of protocol; therefore,
1733 * it should be used at tail positions of protocol callbacks.
1736 proto_notify_state(struct proto
*p
, uint state
)
1738 uint ps
= p
->proto_state
;
1740 DBG("%s reporting state transition %s -> %s\n", p
->name
, p_states
[ps
], p_states
[state
]);
1744 p
->proto_state
= state
;
1745 p
->last_state_change
= current_time();
1750 ASSERT(ps
== PS_DOWN
|| ps
== PS_UP
);
1759 ASSERT(ps
== PS_DOWN
|| ps
== PS_START
);
1768 ASSERT(ps
== PS_START
|| ps
== PS_UP
);
1781 bug("%s: Invalid state %d", p
->name
, ps
);
1784 proto_log_state_change(p
);
1792 proto_state_name(struct proto
*p
)
1794 switch (p
->proto_state
)
1796 case PS_DOWN
: return p
->active
? "flush" : "down";
1797 case PS_START
: return "start";
1798 case PS_UP
: return "up";
1799 case PS_STOP
: return "stop";
1800 default: return "???";
1805 channel_show_stats(struct channel
*c
)
1807 struct proto_stats
*s
= &c
->stats
;
1809 if (c
->in_keep_filtered
)
1810 cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
1811 s
->imp_routes
, s
->filt_routes
, s
->exp_routes
, s
->pref_routes
);
1813 cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
1814 s
->imp_routes
, s
->exp_routes
, s
->pref_routes
);
1816 cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
1817 cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
1818 s
->imp_updates_received
, s
->imp_updates_invalid
,
1819 s
->imp_updates_filtered
, s
->imp_updates_ignored
,
1820 s
->imp_updates_accepted
);
1821 cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
1822 s
->imp_withdraws_received
, s
->imp_withdraws_invalid
,
1823 s
->imp_withdraws_ignored
, s
->imp_withdraws_accepted
);
1824 cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
1825 s
->exp_updates_received
, s
->exp_updates_rejected
,
1826 s
->exp_updates_filtered
, s
->exp_updates_accepted
);
1827 cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
1828 s
->exp_withdraws_received
, s
->exp_withdraws_accepted
);
1832 channel_show_limit(struct channel_limit
*l
, const char *dsc
)
1837 cli_msg(-1006, " %-16s%d%s", dsc
, l
->limit
, l
->state
? " [HIT]" : "");
1838 cli_msg(-1006, " Action: %s", channel_limit_name(l
));
1842 channel_show_info(struct channel
*c
)
1844 cli_msg(-1006, " Channel %s", c
->name
);
1845 cli_msg(-1006, " State: %s", c_states
[c
->channel_state
]);
1846 cli_msg(-1006, " Table: %s", c
->table
->name
);
1847 cli_msg(-1006, " Preference: %d", c
->preference
);
1848 cli_msg(-1006, " Input filter: %s", filter_name(c
->in_filter
));
1849 cli_msg(-1006, " Output filter: %s", filter_name(c
->out_filter
));
1851 if (graceful_restart_state
== GRS_ACTIVE
)
1852 cli_msg(-1006, " GR recovery: %s%s",
1853 c
->gr_lock
? " pending" : "",
1854 c
->gr_wait
? " waiting" : "");
1856 channel_show_limit(&c
->rx_limit
, "Receive limit:");
1857 channel_show_limit(&c
->in_limit
, "Import limit:");
1858 channel_show_limit(&c
->out_limit
, "Export limit:");
1860 if (c
->channel_state
!= CS_DOWN
)
1861 channel_show_stats(c
);
1865 proto_cmd_show(struct proto
*p
, uintptr_t verbose
, int cnt
)
1867 byte buf
[256], tbuf
[TM_DATETIME_BUFFER_SIZE
];
1869 /* First protocol - show header */
1871 cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
1872 "Name", "Proto", "Table", "State", "Since", "Info");
1875 if (p
->proto
->get_status
)
1876 p
->proto
->get_status(p
, buf
);
1877 tm_format_time(tbuf
, &config
->tf_proto
, p
->last_state_change
);
1878 cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
1881 p
->main_channel
? p
->main_channel
->table
->name
: "---",
1882 proto_state_name(p
),
1889 cli_msg(-1006, " Description: %s", p
->cf
->dsc
);
1891 cli_msg(-1006, " Message: %s", p
->message
);
1892 if (p
->cf
->router_id
)
1893 cli_msg(-1006, " Router ID: %R", p
->cf
->router_id
);
1895 cli_msg(-1006, " VRF: %s", p
->vrf
? p
->vrf
->name
: "default");
1897 if (p
->proto
->show_proto_info
)
1898 p
->proto
->show_proto_info(p
);
1902 WALK_LIST(c
, p
->channels
)
1903 channel_show_info(c
);
1911 proto_cmd_disable(struct proto
*p
, uintptr_t arg
, int cnt UNUSED
)
1915 cli_msg(-8, "%s: already disabled", p
->name
);
1919 log(L_INFO
"Disabling protocol %s", p
->name
);
1921 p
->down_code
= PDC_CMD_DISABLE
;
1922 proto_set_message(p
, (char *) arg
, -1);
1923 proto_rethink_goal(p
);
1924 cli_msg(-9, "%s: disabled", p
->name
);
1928 proto_cmd_enable(struct proto
*p
, uintptr_t arg
, int cnt UNUSED
)
1932 cli_msg(-10, "%s: already enabled", p
->name
);
1936 log(L_INFO
"Enabling protocol %s", p
->name
);
1938 proto_set_message(p
, (char *) arg
, -1);
1939 proto_rethink_goal(p
);
1940 cli_msg(-11, "%s: enabled", p
->name
);
1944 proto_cmd_restart(struct proto
*p
, uintptr_t arg
, int cnt UNUSED
)
1948 cli_msg(-8, "%s: already disabled", p
->name
);
1952 log(L_INFO
"Restarting protocol %s", p
->name
);
1954 p
->down_code
= PDC_CMD_RESTART
;
1955 proto_set_message(p
, (char *) arg
, -1);
1956 proto_rethink_goal(p
);
1958 proto_rethink_goal(p
);
1959 cli_msg(-12, "%s: restarted", p
->name
);
1963 proto_cmd_reload(struct proto
*p
, uintptr_t dir
, int cnt UNUSED
)
1969 cli_msg(-8, "%s: already disabled", p
->name
);
1973 /* If the protocol in not UP, it has no routes */
1974 if (p
->proto_state
!= PS_UP
)
1977 /* All channels must support reload */
1978 if (dir
!= CMD_RELOAD_OUT
)
1979 WALK_LIST(c
, p
->channels
)
1980 if ((c
->channel_state
== CS_UP
) && !channel_reloadable(c
))
1982 cli_msg(-8006, "%s: reload failed", p
->name
);
1986 log(L_INFO
"Reloading protocol %s", p
->name
);
1988 /* re-importing routes */
1989 if (dir
!= CMD_RELOAD_OUT
)
1990 WALK_LIST(c
, p
->channels
)
1991 if (c
->channel_state
== CS_UP
)
1992 channel_request_reload(c
);
1994 /* re-exporting routes */
1995 if (dir
!= CMD_RELOAD_IN
)
1996 WALK_LIST(c
, p
->channels
)
1997 if (c
->channel_state
== CS_UP
)
1998 channel_request_feeding(c
);
2000 cli_msg(-15, "%s: reloading", p
->name
);
2004 proto_cmd_debug(struct proto
*p
, uintptr_t mask
, int cnt UNUSED
)
2010 proto_cmd_mrtdump(struct proto
*p
, uintptr_t mask
, int cnt UNUSED
)
2016 proto_apply_cmd_symbol(struct symbol
*s
, void (* cmd
)(struct proto
*, uintptr_t, int), uintptr_t arg
)
2018 if (s
->class != SYM_PROTO
)
2020 cli_msg(9002, "%s is not a protocol", s
->name
);
2024 cmd(s
->proto
->proto
, arg
, 0);
2029 proto_apply_cmd_patt(char *patt
, void (* cmd
)(struct proto
*, uintptr_t, int), uintptr_t arg
)
2034 WALK_LIST(p
, proto_list
)
2035 if (!patt
|| patmatch(patt
, p
->name
))
2039 cli_msg(8003, "No protocols match");
2045 proto_apply_cmd(struct proto_spec ps
, void (* cmd
)(struct proto
*, uintptr_t, int),
2046 int restricted
, uintptr_t arg
)
2048 if (restricted
&& cli_access_restricted())
2052 proto_apply_cmd_patt(ps
.ptr
, cmd
, arg
);
2054 proto_apply_cmd_symbol(ps
.ptr
, cmd
, arg
);
2058 proto_get_named(struct symbol
*sym
, struct protocol
*pr
)
2060 struct proto
*p
, *q
;
2064 if (sym
->class != SYM_PROTO
)
2065 cf_error("%s: Not a protocol", sym
->name
);
2067 p
= sym
->proto
->proto
;
2068 if (!p
|| p
->proto
!= pr
)
2069 cf_error("%s: Not a %s protocol", sym
->name
, pr
->name
);
2074 WALK_LIST(q
, proto_list
)
2075 if ((q
->proto
== pr
) && (q
->proto_state
!= PS_DOWN
))
2078 cf_error("There are multiple %s protocols running", pr
->name
);
2082 cf_error("There is no %s protocol running", pr
->name
);