]> git.ipfire.org Git - thirdparty/bird.git/blame - nest/proto.c
Refactoring of net_route
[thirdparty/bird.git] / nest / proto.c
CommitLineData
2326b001
MM
1/*
2 * BIRD -- Protocols
3 *
50fe90ed 4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
2326b001
MM
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
6b9fa320 9#undef LOCAL_DEBUG
7f4a3988 10
2326b001
MM
11#include "nest/bird.h"
12#include "nest/protocol.h"
13#include "lib/resource.h"
14#include "lib/lists.h"
67bd949a 15#include "lib/event.h"
46434a3c 16#include "lib/timer.h"
f14a4bec 17#include "lib/string.h"
fe7cec12 18#include "conf/conf.h"
47b79306
MM
19#include "nest/route.h"
20#include "nest/iface.h"
333ddd4f 21#include "nest/mpls.h"
ae97b946 22#include "nest/cli.h"
529c4149 23#include "filter/filter.h"
d06a875b 24#include "filter/f-inst.h"
2326b001 25
acb60628 26pool *proto_pool;
4a23ede2 27list STATIC_LIST_INIT(proto_list);
67bd949a 28
4a23ede2 29static list STATIC_LIST_INIT(protocol_list);
ee7e2ffd 30struct protocol *class_to_protocol[PROTOCOL__MAX];
67bd949a 31
61dae32b
OZ
32#define CD(c, msg, args...) ({ if (c->debug & D_STATES) log(L_TRACE "%s.%s: " msg, c->proto->name, c->name ?: "?", ## args); })
33#define PD(p, msg, args...) ({ if (p->debug & D_STATES) log(L_TRACE "%s: " msg, p->name, ## args); })
839380d7 34
ebecb6f6 35static timer *proto_shutdown_timer;
0c791f87
OZ
36static timer *gr_wait_timer;
37
38#define GRS_NONE 0
39#define GRS_INIT 1
40#define GRS_ACTIVE 2
41#define GRS_DONE 3
42
43static int graceful_restart_state;
44static u32 graceful_restart_locks;
67bd949a
MM
45
46static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
d15b0b0a 47static char *c_states[] = { "DOWN", "START", "UP", "FLUSHING" };
61dae32b 48static char *e_states[] = { "DOWN", "FEEDING", "READY" };
67bd949a 49
f4a60a9b
OZ
50extern struct protocol proto_unix_iface;
51
00b85905 52static void channel_request_reload(struct channel *c);
02552526 53static void proto_shutdown_loop(timer *);
50fe90ed 54static void proto_rethink_goal(struct proto *p);
839380d7 55static char *proto_state_name(struct proto *p);
f4a60a9b 56static void channel_verify_limits(struct channel *c);
734e9fb8 57static inline void channel_reset_limit(struct channel_limit *l);
1a54b1c6 58
1a54b1c6 59
f4a60a9b
OZ
60static inline int proto_is_done(struct proto *p)
61{ return (p->proto_state == PS_DOWN) && (p->active_channels == 0); }
227af309 62
f4a60a9b
OZ
63static inline int channel_is_active(struct channel *c)
64{ return (c->channel_state == CS_START) || (c->channel_state == CS_UP); }
227af309 65
211fe69c
OZ
66static inline int channel_reloadable(struct channel *c)
67{ return c->proto->reload_routes && c->reloadable; }
68
61dae32b
OZ
69static inline void
70channel_log_state_change(struct channel *c)
71{
72 if (c->export_state)
73 CD(c, "State changed to %s/%s", c_states[c->channel_state], e_states[c->export_state]);
74 else
75 CD(c, "State changed to %s", c_states[c->channel_state]);
76}
77
227af309
OZ
78static void
79proto_log_state_change(struct proto *p)
80{
81 if (p->debug & D_STATES)
f4a60a9b
OZ
82 {
83 char *name = proto_state_name(p);
84 if (name != p->last_state_name_announced)
227af309 85 {
f4a60a9b
OZ
86 p->last_state_name_announced = name;
87 PD(p, "State changed to %s", proto_state_name(p));
227af309 88 }
f4a60a9b 89 }
227af309
OZ
90 else
91 p->last_state_name_announced = NULL;
67bd949a 92}
2326b001 93
f4a60a9b
OZ
94struct channel_config *
95proto_cf_find_channel(struct proto_config *pc, uint net_type)
7f4a3988 96{
f4a60a9b
OZ
97 struct channel_config *cc;
98
99 WALK_LIST(cc, pc->channels)
100 if (cc->net_type == net_type)
101 return cc;
102
103 return NULL;
7f4a3988
MM
104}
105
f4a60a9b
OZ
106/**
107 * proto_find_channel_by_table - find channel connected to a routing table
108 * @p: protocol instance
109 * @t: routing table
110 *
111 * Returns pointer to channel or NULL
112 */
113struct channel *
114proto_find_channel_by_table(struct proto *p, struct rtable *t)
1a54b1c6 115{
f4a60a9b 116 struct channel *c;
c0adf7e9 117
f4a60a9b
OZ
118 WALK_LIST(c, p->channels)
119 if (c->table == t)
120 return c;
0c791f87 121
f4a60a9b 122 return NULL;
1a54b1c6
MM
123}
124
b2949999
OZ
125/**
126 * proto_find_channel_by_name - find channel by its name
127 * @p: protocol instance
128 * @n: channel name
129 *
130 * Returns pointer to channel or NULL
131 */
132struct channel *
133proto_find_channel_by_name(struct proto *p, const char *n)
134{
135 struct channel *c;
136
137 WALK_LIST(c, p->channels)
138 if (!strcmp(c->name, n))
139 return c;
140
141 return NULL;
142}
143
3c6269b8 144/**
f4a60a9b 145 * proto_add_channel - connect protocol to a routing table
3c6269b8 146 * @p: protocol instance
f4a60a9b 147 * @cf: channel configuration
3c6269b8 148 *
f4a60a9b
OZ
149 * This function creates a channel between the protocol instance @p and the
150 * routing table specified in the configuration @cf, making the protocol hear
151 * all changes in the table and allowing the protocol to update routes in the
152 * table.
c0adf7e9 153 *
f4a60a9b
OZ
154 * The channel is linked in the protocol channel list and when active also in
155 * the table channel list. Channels are allocated from the global resource pool
156 * (@proto_pool) and they are automatically freed when the protocol is removed.
3c6269b8 157 */
f4a60a9b
OZ
158
159struct channel *
160proto_add_channel(struct proto *p, struct channel_config *cf)
161{
162 struct channel *c = mb_allocz(proto_pool, cf->channel->channel_size);
163
164 c->name = cf->name;
165 c->channel = cf->channel;
166 c->proto = p;
167 c->table = cf->table->table;
168
169 c->in_filter = cf->in_filter;
170 c->out_filter = cf->out_filter;
171 c->rx_limit = cf->rx_limit;
172 c->in_limit = cf->in_limit;
173 c->out_limit = cf->out_limit;
174
175 c->net_type = cf->net_type;
176 c->ra_mode = cf->ra_mode;
177 c->preference = cf->preference;
61dae32b 178 c->debug = cf->debug;
f4a60a9b
OZ
179 c->merge_limit = cf->merge_limit;
180 c->in_keep_filtered = cf->in_keep_filtered;
d3782c72 181 c->rpki_reload = cf->rpki_reload;
f4deef89 182 c->bmp_hack = cf->bmp_hack;
f4a60a9b
OZ
183
184 c->channel_state = CS_DOWN;
185 c->export_state = ES_DOWN;
f047271c 186 c->last_state_change = current_time();
f4a60a9b
OZ
187 c->reloadable = 1;
188
00b85905
OZ
189 init_list(&c->roa_subscriptions);
190
f4a60a9b
OZ
191 CALL(c->channel->init, c, cf);
192
193 add_tail(&p->channels, &c->n);
194
61dae32b 195 CD(c, "Connected to table %s", c->table->name);
f4a60a9b
OZ
196
197 return c;
198}
199
200void
61dae32b 201proto_remove_channel(struct proto *p UNUSED, struct channel *c)
f4a60a9b
OZ
202{
203 ASSERT(c->channel_state == CS_DOWN);
204
61dae32b 205 CD(c, "Removed", c->name);
f4a60a9b
OZ
206
207 rem_node(&c->n);
208 mb_free(c);
209}
210
211
212static void
213proto_start_channels(struct proto *p)
214{
215 struct channel *c;
216 WALK_LIST(c, p->channels)
217 if (!c->disabled)
218 channel_set_state(c, CS_UP);
219}
220
221static void
222proto_pause_channels(struct proto *p)
0e02abfd 223{
f4a60a9b
OZ
224 struct channel *c;
225 WALK_LIST(c, p->channels)
226 if (!c->disabled && channel_is_active(c))
227 channel_set_state(c, CS_START);
228}
0e02abfd 229
f4a60a9b
OZ
230static void
231proto_stop_channels(struct proto *p)
232{
233 struct channel *c;
234 WALK_LIST(c, p->channels)
235 if (!c->disabled && channel_is_active(c))
236 channel_set_state(c, CS_FLUSHING);
237}
c0adf7e9 238
f4a60a9b
OZ
239static void
240proto_remove_channels(struct proto *p)
241{
242 struct channel *c;
243 WALK_LIST_FIRST(c, p->channels)
244 proto_remove_channel(p, c);
245}
246
247static void
248channel_schedule_feed(struct channel *c, int initial)
249{
250 // DBG("%s: Scheduling meal\n", p->name);
251 ASSERT(c->channel_state == CS_UP);
c0adf7e9 252
f4a60a9b
OZ
253 c->export_state = ES_FEEDING;
254 c->refeeding = !initial;
c0adf7e9 255
7be3af7f 256 ev_schedule_work(c->feed_event);
f4a60a9b
OZ
257}
258
259static void
260channel_feed_loop(void *ptr)
261{
262 struct channel *c = ptr;
263
264 if (c->export_state != ES_FEEDING)
265 return;
266
00b85905 267 /* Start feeding */
f4a60a9b 268 if (!c->feed_active)
00b85905 269 {
f4a60a9b
OZ
270 if (c->proto->feed_begin)
271 c->proto->feed_begin(c, !c->refeeding);
272
00b85905
OZ
273 c->refeed_pending = 0;
274 }
275
f4a60a9b
OZ
276 // DBG("Feeding protocol %s continued\n", p->name);
277 if (!rt_feed_channel(c))
278 {
7be3af7f 279 ev_schedule_work(c->feed_event);
f4a60a9b
OZ
280 return;
281 }
282
5ea39eaa
OZ
283 /* Reset export limit if the feed ended with acceptable number of exported routes */
284 struct channel_limit *l = &c->out_limit;
285 if (c->refeeding &&
286 (l->state == PLS_BLOCKED) &&
287 (c->refeed_count <= l->limit) &&
288 (c->stats.exp_routes <= l->limit))
289 {
290 log(L_INFO "Protocol %s resets route export limit (%u)", c->proto->name, l->limit);
291 channel_reset_limit(&c->out_limit);
292
293 /* Continue in feed - it will process routing table again from beginning */
294 c->refeed_count = 0;
7be3af7f 295 ev_schedule_work(c->feed_event);
5ea39eaa
OZ
296 return;
297 }
298
f4a60a9b
OZ
299 // DBG("Feeding protocol %s finished\n", p->name);
300 c->export_state = ES_READY;
61dae32b 301 channel_log_state_change(c);
f4a60a9b
OZ
302
303 if (c->proto->feed_end)
304 c->proto->feed_end(c);
00b85905
OZ
305
306 /* Restart feeding */
307 if (c->refeed_pending)
308 channel_request_feeding(c);
f4a60a9b
OZ
309}
310
311
00b85905
OZ
312static void
313channel_roa_in_changed(struct rt_subscription *s)
314{
315 struct channel *c = s->data;
316 int active = c->reload_event && ev_active(c->reload_event);
317
318 CD(c, "Reload triggered by RPKI change%s", active ? " - already active" : "");
319
320 if (!active)
321 channel_request_reload(c);
322 else
323 c->reload_pending = 1;
324}
325
326static void
327channel_roa_out_changed(struct rt_subscription *s)
328{
329 struct channel *c = s->data;
330 int active = (c->export_state == ES_FEEDING);
331
332 CD(c, "Feeding triggered by RPKI change%s", active ? " - already active" : "");
333
334 if (!active)
335 channel_request_feeding(c);
336 else
337 c->refeed_pending = 1;
338}
339
340/* Temporary code, subscriptions should be changed to resources */
341struct roa_subscription {
342 struct rt_subscription s;
343 node roa_node;
344};
345
346static int
347channel_roa_is_subscribed(struct channel *c, rtable *tab, int dir)
348{
349 void (*hook)(struct rt_subscription *) =
350 dir ? channel_roa_in_changed : channel_roa_out_changed;
351
352 struct roa_subscription *s;
353 node *n;
354
355 WALK_LIST2(s, n, c->roa_subscriptions, roa_node)
356 if ((s->s.tab == tab) && (s->s.hook == hook))
357 return 1;
358
359 return 0;
360}
361
362
363static void
364channel_roa_subscribe(struct channel *c, rtable *tab, int dir)
365{
366 if (channel_roa_is_subscribed(c, tab, dir))
367 return;
368
369 struct roa_subscription *s = mb_allocz(c->proto->pool, sizeof(struct roa_subscription));
370
371 s->s.hook = dir ? channel_roa_in_changed : channel_roa_out_changed;
372 s->s.data = c;
373 rt_subscribe(tab, &s->s);
374
375 add_tail(&c->roa_subscriptions, &s->roa_node);
376}
377
378static void
379channel_roa_unsubscribe(struct roa_subscription *s)
380{
381 rt_unsubscribe(&s->s);
382 rem_node(&s->roa_node);
383 mb_free(s);
384}
385
386static void
387channel_roa_subscribe_filter(struct channel *c, int dir)
388{
389 const struct filter *f = dir ? c->in_filter : c->out_filter;
390 struct rtable *tab;
d3782c72 391 int valid = 1, found = 0;
00b85905
OZ
392
393 if ((f == FILTER_ACCEPT) || (f == FILTER_REJECT))
394 return;
395
211fe69c
OZ
396 /* No automatic reload for non-reloadable channels */
397 if (dir && !channel_reloadable(c))
398 valid = 0;
399
0a3db4c6 400#ifdef CONFIG_BGP
d3782c72
OZ
401 /* No automatic reload for BGP channels without in_table / out_table */
402 if (c->channel == &channel_bgp)
403 valid = dir ? !!c->in_table : !!c->out_table;
0a3db4c6 404#endif
d3782c72 405
00b85905
OZ
406 struct filter_iterator fit;
407 FILTER_ITERATE_INIT(&fit, f, c->proto->pool);
408
409 FILTER_ITERATE(&fit, fi)
410 {
411 switch (fi->fi_code)
412 {
413 case FI_ROA_CHECK_IMPLICIT:
414 tab = fi->i_FI_ROA_CHECK_IMPLICIT.rtc->table;
d3782c72
OZ
415 if (valid) channel_roa_subscribe(c, tab, dir);
416 found = 1;
00b85905
OZ
417 break;
418
419 case FI_ROA_CHECK_EXPLICIT:
420 tab = fi->i_FI_ROA_CHECK_EXPLICIT.rtc->table;
d3782c72
OZ
421 if (valid) channel_roa_subscribe(c, tab, dir);
422 found = 1;
00b85905
OZ
423 break;
424
425 default:
426 break;
427 }
428 }
429 FILTER_ITERATE_END;
430
431 FILTER_ITERATE_CLEANUP(&fit);
d3782c72
OZ
432
433 if (!valid && found)
434 log(L_WARN "%s.%s: Automatic RPKI reload not active for %s",
435 c->proto->name, c->name ?: "?", dir ? "import" : "export");
00b85905
OZ
436}
437
438static void
439channel_roa_unsubscribe_all(struct channel *c)
440{
441 struct roa_subscription *s;
442 node *n, *x;
443
444 WALK_LIST2_DELSAFE(s, n, x, c->roa_subscriptions, roa_node)
445 channel_roa_unsubscribe(s);
446}
447
f4a60a9b
OZ
448static void
449channel_start_export(struct channel *c)
450{
451 ASSERT(c->channel_state == CS_UP);
452 ASSERT(c->export_state == ES_DOWN);
453
52641e08 454 channel_schedule_feed(c, 1); /* Sets ES_FEEDING */
f4a60a9b
OZ
455}
456
457static void
458channel_stop_export(struct channel *c)
459{
460 /* Need to abort feeding */
461 if (c->export_state == ES_FEEDING)
462 rt_feed_channel_abort(c);
463
464 c->export_state = ES_DOWN;
7a7ac656 465 c->stats.exp_routes = 0;
5ea39eaa 466 bmap_reset(&c->export_map, 1024);
f4a60a9b
OZ
467}
468
682d3f7d
OZ
469
470/* Called by protocol for reload from in_table */
471void
472channel_schedule_reload(struct channel *c)
473{
474 ASSERT(c->channel_state == CS_UP);
475
476 rt_reload_channel_abort(c);
7be3af7f 477 ev_schedule_work(c->reload_event);
682d3f7d
OZ
478}
479
480static void
481channel_reload_loop(void *ptr)
482{
483 struct channel *c = ptr;
484
00b85905
OZ
485 /* Start reload */
486 if (!c->reload_active)
487 c->reload_pending = 0;
488
682d3f7d
OZ
489 if (!rt_reload_channel(c))
490 {
7be3af7f 491 ev_schedule_work(c->reload_event);
682d3f7d
OZ
492 return;
493 }
00b85905
OZ
494
495 /* Restart reload */
496 if (c->reload_pending)
497 channel_request_reload(c);
682d3f7d
OZ
498}
499
500static void
501channel_reset_import(struct channel *c)
502{
503 /* Need to abort feeding */
504 ev_postpone(c->reload_event);
505 rt_reload_channel_abort(c);
506
507 rt_prune_sync(c->in_table, 1);
508}
509
b7d7599c
OZ
510static void
511channel_reset_export(struct channel *c)
512{
513 /* Just free the routes */
514 rt_prune_sync(c->out_table, 1);
515}
516
682d3f7d
OZ
517/* Called by protocol to activate in_table */
518void
519channel_setup_in_table(struct channel *c)
520{
521 struct rtable_config *cf = mb_allocz(c->proto->pool, sizeof(struct rtable_config));
ff397df7 522
682d3f7d
OZ
523 cf->name = "import";
524 cf->addr_type = c->net_type;
ff397df7 525 cf->internal = 1;
682d3f7d 526
f4deef89 527 c->in_table = cf->table = rt_setup(c->proto->pool, cf);
682d3f7d
OZ
528
529 c->reload_event = ev_new_init(c->proto->pool, channel_reload_loop, c);
530}
531
b7d7599c
OZ
532/* Called by protocol to activate out_table */
533void
534channel_setup_out_table(struct channel *c)
535{
536 struct rtable_config *cf = mb_allocz(c->proto->pool, sizeof(struct rtable_config));
537 cf->name = "export";
538 cf->addr_type = c->net_type;
ff397df7 539 cf->internal = 1;
b7d7599c 540
ff397df7 541 c->out_table = rt_setup(c->proto->pool, cf);
b7d7599c
OZ
542}
543
682d3f7d 544
f4a60a9b
OZ
545static void
546channel_do_start(struct channel *c)
547{
548 rt_lock_table(c->table);
549 add_tail(&c->table->channels, &c->table_node);
550 c->proto->active_channels++;
551
961671c0 552 c->feed_event = ev_new_init(c->proto->pool, channel_feed_loop, c);
f4a60a9b 553
5ea39eaa
OZ
554 bmap_init(&c->export_map, c->proto->pool, 1024);
555 memset(&c->stats, 0, sizeof(struct proto_stats));
556
f4a60a9b
OZ
557 channel_reset_limit(&c->rx_limit);
558 channel_reset_limit(&c->in_limit);
559 channel_reset_limit(&c->out_limit);
560
561 CALL(c->channel->start, c);
562}
563
00b85905
OZ
564static void
565channel_do_up(struct channel *c)
566{
567 /* Register RPKI/ROA subscriptions */
d3782c72
OZ
568 if (c->rpki_reload)
569 {
570 channel_roa_subscribe_filter(c, 1);
571 channel_roa_subscribe_filter(c, 0);
572 }
00b85905
OZ
573}
574
f4a60a9b
OZ
575static void
576channel_do_flush(struct channel *c)
577{
f4deef89
OZ
578 if (!c->bmp_hack)
579 rt_schedule_prune(c->table);
f4a60a9b
OZ
580
581 c->gr_wait = 0;
582 if (c->gr_lock)
583 channel_graceful_restart_unlock(c);
584
585 CALL(c->channel->shutdown, c);
4ab54f1a
OZ
586
587 /* This have to be done in here, as channel pool is freed before channel_do_down() */
588 bmap_free(&c->export_map);
589 c->in_table = NULL;
590 c->reload_event = NULL;
591 c->out_table = NULL;
00b85905
OZ
592
593 channel_roa_unsubscribe_all(c);
f4a60a9b
OZ
594}
595
596static void
597channel_do_down(struct channel *c)
598{
682d3f7d
OZ
599 ASSERT(!c->feed_active && !c->reload_active);
600
7a7ac656 601 rem_node(&c->table_node);
f4a60a9b
OZ
602 rt_unlock_table(c->table);
603 c->proto->active_channels--;
604
605 if ((c->stats.imp_routes + c->stats.filt_routes) != 0)
606 log(L_ERR "%s: Channel %s is down but still has some routes", c->proto->name, c->name);
607
4ab54f1a 608 // bmap_free(&c->export_map);
f4a60a9b
OZ
609 memset(&c->stats, 0, sizeof(struct proto_stats));
610
682d3f7d
OZ
611 c->in_table = NULL;
612 c->reload_event = NULL;
b7d7599c 613 c->out_table = NULL;
682d3f7d 614
ff397df7
MM
615 /* The in_table and out_table are going to be freed by freeing their resource pools. */
616
d15b0b0a
OZ
617 CALL(c->channel->cleanup, c);
618
f4a60a9b
OZ
619 /* Schedule protocol shutddown */
620 if (proto_is_done(c->proto))
621 ev_schedule(c->proto->event);
622}
623
624void
625channel_set_state(struct channel *c, uint state)
626{
627 uint cs = c->channel_state;
628 uint es = c->export_state;
629
286e2011 630 DBG("%s reporting channel %s state transition %s -> %s\n", c->proto->name, c->name, c_states[cs], c_states[state]);
f4a60a9b
OZ
631 if (state == cs)
632 return;
633
634 c->channel_state = state;
f047271c 635 c->last_state_change = current_time();
f4a60a9b
OZ
636
637 switch (state)
638 {
639 case CS_START:
640 ASSERT(cs == CS_DOWN || cs == CS_UP);
641
642 if (cs == CS_DOWN)
643 channel_do_start(c);
644
645 if (es != ES_DOWN)
646 channel_stop_export(c);
647
682d3f7d
OZ
648 if (c->in_table && (cs == CS_UP))
649 channel_reset_import(c);
650
b7d7599c
OZ
651 if (c->out_table && (cs == CS_UP))
652 channel_reset_export(c);
653
f4a60a9b
OZ
654 break;
655
656 case CS_UP:
657 ASSERT(cs == CS_DOWN || cs == CS_START);
658
659 if (cs == CS_DOWN)
660 channel_do_start(c);
661
2a013bb3 662 if (!c->gr_wait && c->proto->rt_notify)
f4a60a9b
OZ
663 channel_start_export(c);
664
00b85905 665 channel_do_up(c);
f4a60a9b
OZ
666 break;
667
668 case CS_FLUSHING:
669 ASSERT(cs == CS_START || cs == CS_UP);
670
671 if (es != ES_DOWN)
672 channel_stop_export(c);
673
682d3f7d
OZ
674 if (c->in_table && (cs == CS_UP))
675 channel_reset_import(c);
676
b7d7599c
OZ
677 if (c->out_table && (cs == CS_UP))
678 channel_reset_export(c);
679
f4a60a9b
OZ
680 channel_do_flush(c);
681 break;
682
683 case CS_DOWN:
684 ASSERT(cs == CS_FLUSHING);
685
686 channel_do_down(c);
687 break;
688
689 default:
690 ASSERT(0);
691 }
61dae32b
OZ
692
693 channel_log_state_change(c);
0e02abfd
MM
694}
695
c0adf7e9 696/**
f4a60a9b
OZ
697 * channel_request_feeding - request feeding routes to the channel
698 * @c: given channel
c0adf7e9 699 *
f4a60a9b
OZ
700 * Sometimes it is needed to send again all routes to the channel. This is
701 * called feeding and can be requested by this function. This would cause
702 * channel export state transition to ES_FEEDING (during feeding) and when
703 * completed, it will switch back to ES_READY. This function can be called
704 * even when feeding is already running, in that case it is restarted.
c0adf7e9 705 */
f4a60a9b
OZ
706void
707channel_request_feeding(struct channel *c)
c0adf7e9 708{
f4a60a9b 709 ASSERT(c->channel_state == CS_UP);
c0adf7e9 710
61dae32b
OZ
711 CD(c, "Feeding requested");
712
f4a60a9b
OZ
713 /* Do nothing if we are still waiting for feeding */
714 if (c->export_state == ES_DOWN)
715 return;
c0adf7e9 716
f4a60a9b
OZ
717 /* If we are already feeding, we want to restart it */
718 if (c->export_state == ES_FEEDING)
719 {
720 /* Unless feeding is in initial state */
721 if (!c->feed_active)
722 return;
723
724 rt_feed_channel_abort(c);
725 }
726
5ea39eaa
OZ
727 /* Track number of exported routes during refeed */
728 c->refeed_count = 0;
f4a60a9b
OZ
729
730 channel_schedule_feed(c, 0); /* Sets ES_FEEDING */
61dae32b 731 channel_log_state_change(c);
f4a60a9b
OZ
732}
733
0c791f87 734static void
f4a60a9b 735channel_request_reload(struct channel *c)
0c791f87 736{
f4a60a9b 737 ASSERT(c->channel_state == CS_UP);
2e507a74 738 ASSERT(channel_reloadable(c));
f4a60a9b 739
61dae32b
OZ
740 CD(c, "Reload requested");
741
f4a60a9b 742 c->proto->reload_routes(c);
0c791f87 743
f4a60a9b
OZ
744 /*
745 * Should this be done before reload_routes() hook?
746 * Perhaps, but routes are updated asynchronously.
747 */
748 channel_reset_limit(&c->rx_limit);
749 channel_reset_limit(&c->in_limit);
0c791f87
OZ
750}
751
f4a60a9b
OZ
752const struct channel_class channel_basic = {
753 .channel_size = sizeof(struct channel),
754 .config_size = sizeof(struct channel_config)
755};
756
757void *
72163bd5 758channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto)
f4a60a9b
OZ
759{
760 struct channel_config *cf = NULL;
761 struct rtable_config *tab = NULL;
f4a60a9b
OZ
762
763 if (net_type)
764 {
765 if (!net_val_match(net_type, proto->protocol->channel_mask))
766 cf_error("Unsupported channel type");
767
333ddd4f 768 if (proto->net_type && (net_type != proto->net_type) && (net_type != NET_MPLS))
f4a60a9b
OZ
769 cf_error("Different channel type");
770
771 tab = new_config->def_tables[net_type];
f4a60a9b
OZ
772 }
773
774 if (!cc)
775 cc = &channel_basic;
776
777 cf = cfg_allocz(cc->config_size);
778 cf->name = name;
779 cf->channel = cc;
72163bd5 780 cf->parent = proto;
f4a60a9b
OZ
781 cf->table = tab;
782 cf->out_filter = FILTER_REJECT;
783
784 cf->net_type = net_type;
785 cf->ra_mode = RA_OPTIMAL;
786 cf->preference = proto->protocol->preference;
61dae32b 787 cf->debug = new_config->channel_default_debug;
d3782c72 788 cf->rpki_reload = 1;
f4a60a9b
OZ
789
790 add_tail(&proto->channels, &cf->n);
791
792 return cf;
793}
794
72163bd5
OZ
795void *
796channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto)
797{
798 struct channel_config *cf;
799
800 /* We are using name as token, so no strcmp() */
801 WALK_LIST(cf, proto->channels)
802 if (cf->name == name)
803 {
804 /* Allow to redefine channel only if inherited from template */
805 if (cf->parent == proto)
806 cf_error("Multiple %s channels", name);
807
808 cf->parent = proto;
8478de88 809 cf->copy = 1;
72163bd5
OZ
810 return cf;
811 }
812
813 return channel_config_new(cc, name, net_type, proto);
814}
815
f4a60a9b
OZ
816struct channel_config *
817channel_copy_config(struct channel_config *src, struct proto_config *proto)
818{
819 struct channel_config *dst = cfg_alloc(src->channel->config_size);
820
821 memcpy(dst, src, src->channel->config_size);
1678bc07 822 memset(&dst->n, 0, sizeof(node));
f4a60a9b
OZ
823 add_tail(&proto->channels, &dst->n);
824 CALL(src->channel->copy_config, dst, src);
825
826 return dst;
827}
828
829
830static int reconfigure_type; /* Hack to propagate type info to channel_reconfigure() */
831
832int
833channel_reconfigure(struct channel *c, struct channel_config *cf)
834{
54430df9
OZ
835 /* Touched by reconfiguration */
836 c->stale = 0;
837
f4a60a9b 838 /* FIXME: better handle these changes, also handle in_keep_filtered */
f8aad5d5 839 if ((c->table != cf->table->table) || (cf->ra_mode && (c->ra_mode != cf->ra_mode)))
f4a60a9b
OZ
840 return 0;
841
94f9be80
OZ
842 /* Note that filter_same() requires arguments in (new, old) order */
843 int import_changed = !filter_same(cf->in_filter, c->in_filter);
844 int export_changed = !filter_same(cf->out_filter, c->out_filter);
d3782c72 845 int rpki_reload_changed = (cf->rpki_reload != c->rpki_reload);
f4a60a9b
OZ
846
847 if (c->preference != cf->preference)
848 import_changed = 1;
849
850 if (c->merge_limit != cf->merge_limit)
851 export_changed = 1;
852
853 /* Reconfigure channel fields */
854 c->in_filter = cf->in_filter;
855 c->out_filter = cf->out_filter;
856 c->rx_limit = cf->rx_limit;
857 c->in_limit = cf->in_limit;
858 c->out_limit = cf->out_limit;
859
860 // c->ra_mode = cf->ra_mode;
861 c->merge_limit = cf->merge_limit;
862 c->preference = cf->preference;
61dae32b 863 c->debug = cf->debug;
f4a60a9b 864 c->in_keep_filtered = cf->in_keep_filtered;
d3782c72 865 c->rpki_reload = cf->rpki_reload;
f4a60a9b
OZ
866
867 channel_verify_limits(c);
868
d15b0b0a 869 /* Execute channel-specific reconfigure hook */
e2b530aa 870 if (c->channel->reconfigure && !c->channel->reconfigure(c, cf, &import_changed, &export_changed))
d15b0b0a 871 return 0;
f4a60a9b
OZ
872
873 /* If the channel is not open, it has no routes and we cannot reload it anyways */
874 if (c->channel_state != CS_UP)
61dae32b 875 goto done;
f4a60a9b 876
00b85905 877 /* Update RPKI/ROA subscriptions */
d3782c72 878 if (import_changed || export_changed || rpki_reload_changed)
00b85905
OZ
879 {
880 channel_roa_unsubscribe_all(c);
d3782c72
OZ
881
882 if (c->rpki_reload)
883 {
884 channel_roa_subscribe_filter(c, 1);
885 channel_roa_subscribe_filter(c, 0);
886 }
00b85905
OZ
887 }
888
f4a60a9b
OZ
889 if (reconfigure_type == RECONFIG_SOFT)
890 {
891 if (import_changed)
892 log(L_INFO "Channel %s.%s changed import", c->proto->name, c->name);
893
894 if (export_changed)
895 log(L_INFO "Channel %s.%s changed export", c->proto->name, c->name);
896
61dae32b 897 goto done;
f4a60a9b
OZ
898 }
899
900 /* Route reload may be not supported */
901 if (import_changed && !channel_reloadable(c))
902 return 0;
903
904 if (import_changed || export_changed)
905 log(L_INFO "Reloading channel %s.%s", c->proto->name, c->name);
906
907 if (import_changed)
908 channel_request_reload(c);
909
910 if (export_changed)
911 channel_request_feeding(c);
912
61dae32b
OZ
913done:
914 CD(c, "Reconfigured");
f4a60a9b
OZ
915 return 1;
916}
917
918
919int
920proto_configure_channel(struct proto *p, struct channel **pc, struct channel_config *cf)
0e02abfd 921{
f4a60a9b 922 struct channel *c = *pc;
0e02abfd 923
f4a60a9b
OZ
924 if (!c && cf)
925 {
d506263d
OZ
926 /* We could add the channel, but currently it would just stay in down state
927 until protocol is restarted, so it is better to force restart anyways. */
cfa6ff95
OZ
928 if (p->proto_state != PS_DOWN)
929 {
930 log(L_INFO "Cannot add channel %s.%s", p->name, cf->name);
931 return 0;
932 }
933
934 *pc = proto_add_channel(p, cf);
f4a60a9b
OZ
935 }
936 else if (c && !cf)
937 {
938 if (c->channel_state != CS_DOWN)
939 {
940 log(L_INFO "Cannot remove channel %s.%s", c->proto->name, c->name);
941 return 0;
942 }
943
944 proto_remove_channel(p, c);
945 *pc = NULL;
946 }
947 else if (c && cf)
948 {
949 if (!channel_reconfigure(c, cf))
950 {
951 log(L_INFO "Cannot reconfigure channel %s.%s", c->proto->name, c->name);
952 return 0;
953 }
954 }
955
956 return 1;
c0adf7e9
OZ
957}
958
333ddd4f
OZ
959/**
960 * proto_setup_mpls_map - automatically setup FEC map for protocol
961 * @p: affected protocol
962 * @rts: RTS_* value for generated MPLS routes
963 * @hooks: whether to update rte_insert / rte_remove hooks
964 *
965 * Add, remove or reconfigure MPLS FEC map of the protocol @p, depends on
966 * whether MPLS channel exists, and setup rte_insert / rte_remove hooks with
967 * default MPLS handlers. It is a convenience function supposed to be called
968 * from the protocol start and configure hooks, after reconfiguration of
969 * channels. For shutdown, use proto_shutdown_mpls_map(). If caller uses its own
970 * rte_insert / rte_remove hooks, it is possible to disable updating hooks and
971 * doing that manually.
972 */
973void
974proto_setup_mpls_map(struct proto *p, uint rts, int hooks)
975{
976 struct mpls_fec_map *m = p->mpls_map;
977 struct channel *c = p->mpls_channel;
978
979 if (!m && c)
980 {
981 /*
982 * Note that when called from a protocol start hook, it is called before
983 * mpls_channel_start(). But FEC map locks MPLS domain internally so it does
984 * not depend on lock from MPLS channel.
985 */
986 p->mpls_map = mpls_fec_map_new(p->pool, c, rts);
987 }
988 else if (m && !c)
989 {
990 /*
991 * Note that for reconfiguration, it is called after the MPLS channel has
992 * been already removed. But removal of active MPLS channel would trigger
993 * protocol restart anyways.
994 */
995 mpls_fec_map_free(m);
996 p->mpls_map = NULL;
997 }
998 else if (m && c)
999 {
a7a9df86 1000 mpls_fec_map_reconfigure(m, c);
333ddd4f
OZ
1001 }
1002
1003 if (hooks)
1004 {
1005 p->rte_insert = p->mpls_map ? mpls_rte_insert : NULL;
1006 p->rte_remove = p->mpls_map ? mpls_rte_remove : NULL;
1007 }
1008}
1009
1010/**
1011 * proto_shutdown_mpls_map - automatically shutdown FEC map for protocol
1012 * @p: affected protocol
1013 * @hooks: whether to update rte_insert / rte_remove hooks
1014 *
1015 * Remove MPLS FEC map of the protocol @p during protocol shutdown.
1016 */
1017void
1018proto_shutdown_mpls_map(struct proto *p, int hooks)
1019{
1020 struct mpls_fec_map *m = p->mpls_map;
1021
1022 if (!m)
1023 return;
1024
1025 mpls_fec_map_free(m);
1026 p->mpls_map = NULL;
1027
1028 if (hooks)
1029 {
1030 p->rte_insert = NULL;
1031 p->rte_remove = NULL;
1032 }
1033}
f4a60a9b 1034
c0adf7e9 1035static void
f4a60a9b 1036proto_event(void *ptr)
c0adf7e9 1037{
f4a60a9b
OZ
1038 struct proto *p = ptr;
1039
1040 if (p->do_start)
1041 {
1042 if_feed_baby(p);
1043 p->do_start = 0;
1044 }
c0adf7e9 1045
f4a60a9b 1046 if (p->do_stop)
c0adf7e9 1047 {
f4a60a9b
OZ
1048 if (p->proto == &proto_unix_iface)
1049 if_flush_ifaces(p);
1050 p->do_stop = 0;
c0adf7e9
OZ
1051 }
1052
f4a60a9b
OZ
1053 if (proto_is_done(p))
1054 {
1055 if (p->proto->cleanup)
1056 p->proto->cleanup(p);
1057
1058 p->active = 0;
1059 proto_log_state_change(p);
1060 proto_rethink_goal(p);
1061 }
1062}
1063
1064
1065/**
1066 * proto_new - create a new protocol instance
1067 * @c: protocol configuration
1068 *
1069 * When a new configuration has been read in, the core code starts
1070 * initializing all the protocol instances configured by calling their
1071 * init() hooks with the corresponding instance configuration. The initialization
1072 * code of the protocol is expected to create a new instance according to the
1073 * configuration by calling this function and then modifying the default settings
1074 * to values wanted by the protocol.
1075 */
1076void *
1077proto_new(struct proto_config *cf)
1078{
1079 struct proto *p = mb_allocz(proto_pool, cf->protocol->proto_size);
1080
1081 p->cf = cf;
1082 p->debug = cf->debug;
1083 p->mrtdump = cf->mrtdump;
1084 p->name = cf->name;
1085 p->proto = cf->protocol;
1086 p->net_type = cf->net_type;
1087 p->disabled = cf->disabled;
1088 p->hash_key = random_u32();
1089 cf->proto = p;
1090
1091 init_list(&p->channels);
1092
1093 return p;
1094}
1095
1096static struct proto *
1097proto_init(struct proto_config *c, node *n)
1098{
1099 struct protocol *pr = c->protocol;
1100 struct proto *p = pr->init(c);
1101
1102 p->proto_state = PS_DOWN;
f047271c 1103 p->last_state_change = current_time();
46434a3c 1104 p->vrf = c->vrf;
18f70a62 1105 p->vrf_set = c->vrf_set;
f4a60a9b
OZ
1106 insert_node(&p->n, n);
1107
961671c0 1108 p->event = ev_new_init(proto_pool, proto_event, p);
f4a60a9b
OZ
1109
1110 PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
1111
1112 return p;
1113}
1114
1115static void
1116proto_start(struct proto *p)
1117{
1118 /* Here we cannot use p->cf->name since it won't survive reconfiguration */
1119 p->pool = rp_new(proto_pool, p->proto->name);
1120
1121 if (graceful_restart_state == GRS_INIT)
1122 p->gr_recovery = 1;
0e02abfd
MM
1123}
1124
094d2bdb 1125
3c6269b8
MM
1126/**
1127 * proto_config_new - create a new protocol configuration
1128 * @pr: protocol the configuration will belong to
a7f23f58 1129 * @class: SYM_PROTO or SYM_TEMPLATE
3c6269b8
MM
1130 *
1131 * Whenever the configuration file says that a new instance
1132 * of a routing protocol should be created, the parser calls
1133 * proto_config_new() to create a configuration entry for this
1134 * instance (a structure staring with the &proto_config header
1135 * containing all the generic items followed by protocol-specific
1136 * ones). Also, the configuration entry gets added to the list
1137 * of protocol instances kept in the configuration.
a7f23f58
OZ
1138 *
1139 * The function is also used to create protocol templates (when class
1140 * SYM_TEMPLATE is specified), the only difference is that templates
1141 * are not added to the list of protocol instances and therefore not
1142 * initialized during protos_commit()).
3c6269b8 1143 */
31b3e1bb 1144void *
2bbc3083 1145proto_config_new(struct protocol *pr, int class)
31b3e1bb 1146{
f4a60a9b 1147 struct proto_config *cf = cfg_allocz(pr->config_size);
31b3e1bb 1148
a7f23f58 1149 if (class == SYM_PROTO)
f4a60a9b
OZ
1150 add_tail(&new_config->protos, &cf->n);
1151
1152 cf->global = new_config;
1153 cf->protocol = pr;
1154 cf->name = pr->name;
1155 cf->class = class;
1156 cf->debug = new_config->proto_default_debug;
1157 cf->mrtdump = new_config->proto_default_mrtdump;
1158
1159 init_list(&cf->channels);
1160
1161 return cf;
31b3e1bb
MM
1162}
1163
f4a60a9b 1164
a7f23f58
OZ
1165/**
1166 * proto_copy_config - copy a protocol configuration
1167 * @dest: destination protocol configuration
1168 * @src: source protocol configuration
1169 *
1170 * Whenever a new instance of a routing protocol is created from the
1171 * template, proto_copy_config() is called to copy a content of
1172 * the source protocol configuration to the new protocol configuration.
1173 * Name, class and a node in protos list of @dest are kept intact.
1174 * copy_config() protocol hook is used to copy protocol-specific data.
1175 */
1176void
1177proto_copy_config(struct proto_config *dest, struct proto_config *src)
1178{
f4a60a9b 1179 struct channel_config *cc;
a7f23f58
OZ
1180 node old_node;
1181 int old_class;
fd9f0c06 1182 const char *old_name;
a7f23f58
OZ
1183
1184 if (dest->protocol != src->protocol)
1185 cf_error("Can't copy configuration from a different protocol type");
1186
1187 if (dest->protocol->copy_config == NULL)
1188 cf_error("Inheriting configuration for %s is not supported", src->protocol->name);
1189
1190 DBG("Copying configuration from %s to %s\n", src->name, dest->name);
1191
f4a60a9b 1192 /*
a7f23f58
OZ
1193 * Copy struct proto_config here. Keep original node, class and name.
1194 * protocol-specific config copy is handled by protocol copy_config() hook
1195 */
1196
1197 old_node = dest->n;
1198 old_class = dest->class;
1199 old_name = dest->name;
1200
f4a60a9b 1201 memcpy(dest, src, src->protocol->config_size);
a7f23f58
OZ
1202
1203 dest->n = old_node;
1204 dest->class = old_class;
1205 dest->name = old_name;
f4a60a9b 1206 init_list(&dest->channels);
a7f23f58 1207
f4a60a9b
OZ
1208 WALK_LIST(cc, src->channels)
1209 channel_copy_config(cc, dest);
1210
1211 /* FIXME: allow for undefined copy_config */
a7f23f58
OZ
1212 dest->protocol->copy_config(dest, src);
1213}
1214
e0835db4
OZ
1215void
1216proto_clone_config(struct symbol *sym, struct proto_config *parent)
1217{
1218 struct proto_config *cf = proto_config_new(parent->protocol, SYM_PROTO);
1219 proto_copy_config(cf, parent);
1220 cf->name = sym->name;
1221 cf->proto = NULL;
1222 cf->parent = parent;
1223
1224 sym->class = cf->class;
eac9250f 1225 sym->proto = cf;
e0835db4
OZ
1226}
1227
1228static void
1229proto_undef_clone(struct symbol *sym, struct proto_config *cf)
1230{
1231 rem_node(&cf->n);
1232
1233 sym->class = SYM_VOID;
eac9250f 1234 sym->proto = NULL;
e0835db4
OZ
1235}
1236
3c6269b8
MM
1237/**
1238 * protos_preconfig - pre-configuration processing
1239 * @c: new configuration
1240 *
1241 * This function calls the preconfig() hooks of all routing
1242 * protocols available to prepare them for reading of the new
1243 * configuration.
1244 */
2326b001 1245void
31b3e1bb 1246protos_preconfig(struct config *c)
2326b001 1247{
7f4a3988
MM
1248 struct protocol *p;
1249
7c0cc76e 1250 init_list(&c->protos);
6b9fa320 1251 DBG("Protocol preconfig:");
7f4a3988 1252 WALK_LIST(p, protocol_list)
f4a60a9b
OZ
1253 {
1254 DBG(" %s", p->name);
1255 p->name_counter = 0;
1256 if (p->preconfig)
1257 p->preconfig(p, c);
1258 }
6b9fa320 1259 DBG("\n");
31b3e1bb
MM
1260}
1261
ebae4770
OZ
1262static int
1263proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
1264{
1265 /* If the protocol is DOWN, we just restart it */
1266 if (p->proto_state == PS_DOWN)
1267 return 0;
1268
1269 /* If there is a too big change in core attributes, ... */
1270 if ((nc->protocol != oc->protocol) ||
f4a60a9b 1271 (nc->net_type != oc->net_type) ||
23fd4644 1272 (nc->disabled != p->disabled) ||
18f70a62
OZ
1273 (nc->vrf != oc->vrf) ||
1274 (nc->vrf_set != oc->vrf_set))
ebae4770
OZ
1275 return 0;
1276
f4a60a9b 1277 p->name = nc->name;
ebae4770
OZ
1278 p->debug = nc->debug;
1279 p->mrtdump = nc->mrtdump;
f4a60a9b 1280 reconfigure_type = type;
ebae4770
OZ
1281
1282 /* Execute protocol specific reconfigure hook */
f4a60a9b 1283 if (!p->proto->reconfigure || !p->proto->reconfigure(p, nc))
ebae4770
OZ
1284 return 0;
1285
1286 DBG("\t%s: same\n", oc->name);
1287 PD(p, "Reconfigured");
1288 p->cf = nc;
ebae4770
OZ
1289
1290 return 1;
1291}
1292
3c6269b8
MM
1293/**
1294 * protos_commit - commit new protocol configuration
1295 * @new: new configuration
1296 * @old: old configuration or %NULL if it's boot time config
1297 * @force_reconfig: force restart of all protocols (used for example
1298 * when the router ID changes)
bf1aec97 1299 * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
3c6269b8
MM
1300 *
1301 * Scan differences between @old and @new configuration and adjust all
1302 * protocol instances to conform to the new configuration.
1303 *
1304 * When a protocol exists in the new configuration, but it doesn't in the
1305 * original one, it's immediately started. When a collision with the other
1306 * running protocol would arise, the new protocol will be temporarily stopped
1307 * by the locking mechanism.
1308 *
1309 * When a protocol exists in the old configuration, but it doesn't in the
1310 * new one, it's shut down and deleted after the shutdown completes.
1311 *
bf1aec97
OZ
1312 * When a protocol exists in both configurations, the core decides
1313 * whether it's possible to reconfigure it dynamically - it checks all
1314 * the core properties of the protocol (changes in filters are ignored
1315 * if type is RECONFIG_SOFT) and if they match, it asks the
1316 * reconfigure() hook of the protocol to see if the protocol is able
1317 * to switch to the new configuration. If it isn't possible, the
1318 * protocol is shut down and a new instance is started with the new
1319 * configuration after the shutdown is completed.
3c6269b8 1320 */
31b3e1bb 1321void
bf1aec97 1322protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
31b3e1bb 1323{
50fe90ed 1324 struct proto_config *oc, *nc;
a7f23f58 1325 struct symbol *sym;
f4a60a9b
OZ
1326 struct proto *p;
1327 node *n;
1328
31b3e1bb 1329
50fe90ed
MM
1330 DBG("protos_commit:\n");
1331 if (old)
f4a60a9b
OZ
1332 {
1333 WALK_LIST(oc, old->protos)
31b3e1bb 1334 {
f4a60a9b
OZ
1335 p = oc->proto;
1336 sym = cf_find_symbol(new, oc->name);
e0835db4
OZ
1337
1338 /* Handle dynamic protocols */
1339 if (!sym && oc->parent && !new->shutdown)
1340 {
1341 struct symbol *parsym = cf_find_symbol(new, oc->parent->name);
1342 if (parsym && parsym->class == SYM_PROTO)
1343 {
1344 /* This is hack, we would like to share config, but we need to copy it now */
1345 new_config = new;
1346 cfg_mem = new->mem;
51f2e7af
MM
1347 new->current_scope = new->root_scope;
1348 sym = cf_get_symbol(new, oc->name);
eac9250f 1349 proto_clone_config(sym, parsym->proto);
e0835db4
OZ
1350 new_config = NULL;
1351 cfg_mem = NULL;
1352 }
1353 }
1354
f4a60a9b
OZ
1355 if (sym && sym->class == SYM_PROTO && !new->shutdown)
1356 {
1357 /* Found match, let's check if we can smoothly switch to new configuration */
1358 /* No need to check description */
0b39b1cb 1359 nc = sym->proto;
f4a60a9b
OZ
1360 nc->proto = p;
1361
1362 /* We will try to reconfigure protocol p */
1363 if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
1364 continue;
1365
e0835db4
OZ
1366 if (nc->parent)
1367 {
1368 proto_undef_clone(sym, nc);
1369 goto remove;
1370 }
1371
f4a60a9b
OZ
1372 /* Unsuccessful, we will restart it */
1373 if (!p->disabled && !nc->disabled)
1374 log(L_INFO "Restarting protocol %s", p->name);
1375 else if (p->disabled && !nc->disabled)
1376 log(L_INFO "Enabling protocol %s", p->name);
1377 else if (!p->disabled && nc->disabled)
1378 log(L_INFO "Disabling protocol %s", p->name);
1379
1380 p->down_code = nc->disabled ? PDC_CF_DISABLE : PDC_CF_RESTART;
1381 p->cf_new = nc;
1382 }
1383 else if (!new->shutdown)
1384 {
e0835db4 1385 remove:
f4a60a9b
OZ
1386 log(L_INFO "Removing protocol %s", p->name);
1387 p->down_code = PDC_CF_REMOVE;
1388 p->cf_new = NULL;
1389 }
8a68316e
OZ
1390 else if (new->gr_down)
1391 {
1392 p->down_code = PDC_CMD_GR_DOWN;
1393 p->cf_new = NULL;
1394 }
f4a60a9b
OZ
1395 else /* global shutdown */
1396 {
1397 p->down_code = PDC_CMD_SHUTDOWN;
1398 p->cf_new = NULL;
1399 }
1400
1401 p->reconfiguring = 1;
1402 config_add_obstacle(old);
1403 proto_rethink_goal(p);
7f4a3988 1404 }
f4a60a9b
OZ
1405 }
1406
1407 struct proto *first_dev_proto = NULL;
50fe90ed 1408
f4a60a9b 1409 n = NODE &(proto_list.head);
50fe90ed
MM
1410 WALK_LIST(nc, new->protos)
1411 if (!nc->proto)
f4a60a9b
OZ
1412 {
1413 /* Not a first-time configuration */
1414 if (old)
1415 log(L_INFO "Adding protocol %s", nc->name);
1416
1417 p = proto_init(nc, n);
1418 n = NODE p;
1419
1420 if (p->proto == &proto_unix_iface)
1421 first_dev_proto = p;
1422 }
1423 else
1424 n = NODE nc->proto;
50fe90ed
MM
1425
1426 DBG("Protocol start\n");
4ef09506
OZ
1427
1428 /* Start device protocol first */
f4a60a9b
OZ
1429 if (first_dev_proto)
1430 proto_rethink_goal(first_dev_proto);
4ef09506 1431
79b4e12e
OZ
1432 /* Determine router ID for the first time - it has to be here and not in
1433 global_commit() because it is postponed after start of device protocol */
1434 if (!config->router_id)
f4a60a9b
OZ
1435 {
1436 config->router_id = if_choose_router_id(config->router_id_from, 0);
1437 if (!config->router_id)
1438 die("Cannot determine router ID, please configure it manually");
1439 }
79b4e12e 1440
f4a60a9b
OZ
1441 /* Start all new protocols */
1442 WALK_LIST_DELSAFE(p, n, proto_list)
50fe90ed 1443 proto_rethink_goal(p);
7f4a3988
MM
1444}
1445
47b79306 1446static void
67bd949a 1447proto_rethink_goal(struct proto *p)
47b79306 1448{
50fe90ed 1449 struct protocol *q;
0c791f87 1450 byte goal;
50fe90ed 1451
f4a60a9b
OZ
1452 if (p->reconfiguring && !p->active)
1453 {
1454 struct proto_config *nc = p->cf_new;
1455 node *n = p->n.prev;
1456 DBG("%s has shut down for reconfiguration\n", p->name);
1457 p->cf->proto = NULL;
1458 config_del_obstacle(p->cf->global);
1459 proto_remove_channels(p);
1460 rem_node(&p->n);
1461 rfree(p->event);
830ba75e 1462 mb_free(p->message);
f4a60a9b
OZ
1463 mb_free(p);
1464 if (!nc)
1465 return;
1466 p = proto_init(nc, n);
1467 }
50fe90ed
MM
1468
1469 /* Determine what state we want to reach */
bf8558bc 1470 if (p->disabled || p->reconfiguring)
0c791f87 1471 goal = PS_DOWN;
50fe90ed 1472 else
0c791f87 1473 goal = PS_UP;
50fe90ed
MM
1474
1475 q = p->proto;
f4a60a9b
OZ
1476 if (goal == PS_UP)
1477 {
1478 if (!p->active)
67bd949a 1479 {
f4a60a9b
OZ
1480 /* Going up */
1481 DBG("Kicking %s up\n", p->name);
1482 PD(p, "Starting");
1483 proto_start(p);
1484 proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
67bd949a 1485 }
f4a60a9b
OZ
1486 }
1487 else
1488 {
1489 if (p->proto_state == PS_START || p->proto_state == PS_UP)
67bd949a 1490 {
f4a60a9b
OZ
1491 /* Going down */
1492 DBG("Kicking %s down\n", p->name);
1493 PD(p, "Shutting down");
1494 proto_notify_state(p, (q->shutdown ? q->shutdown(p) : PS_DOWN));
67bd949a 1495 }
f4a60a9b 1496 }
67bd949a
MM
1497}
1498
e0835db4
OZ
1499struct proto *
1500proto_spawn(struct proto_config *cf, uint disabled)
1501{
1502 struct proto *p = proto_init(cf, TAIL(proto_list));
1503 p->disabled = disabled;
1504 proto_rethink_goal(p);
1505 return p;
1506}
1507
0c791f87 1508
6eda3f13
OZ
1509/**
1510 * DOC: Graceful restart recovery
1511 *
1512 * Graceful restart of a router is a process when the routing plane (e.g. BIRD)
1513 * restarts but both the forwarding plane (e.g kernel routing table) and routing
1514 * neighbors keep proper routes, and therefore uninterrupted packet forwarding
1515 * is maintained.
1516 *
1517 * BIRD implements graceful restart recovery by deferring export of routes to
1518 * protocols until routing tables are refilled with the expected content. After
1519 * start, protocols generate routes as usual, but routes are not propagated to
1520 * them, until protocols report that they generated all routes. After that,
1521 * graceful restart recovery is finished and the export (and the initial feed)
1522 * to protocols is enabled.
1523 *
1524 * When graceful restart recovery need is detected during initialization, then
1525 * enabled protocols are marked with @gr_recovery flag before start. Such
1526 * protocols then decide how to proceed with graceful restart, participation is
f4a60a9b 1527 * voluntary. Protocols could lock the recovery for each channel by function
286e2011 1528 * channel_graceful_restart_lock() (state stored in @gr_lock flag), which means
f4a60a9b
OZ
1529 * that they want to postpone the end of the recovery until they converge and
1530 * then unlock it. They also could set @gr_wait before advancing to %PS_UP,
1531 * which means that the core should defer route export to that channel until
1532 * the end of the recovery. This should be done by protocols that expect their
1533 * neigbors to keep the proper routes (kernel table, BGP sessions with BGP
1534 * graceful restart capability).
6eda3f13
OZ
1535 *
1536 * The graceful restart recovery is finished when either all graceful restart
1537 * locks are unlocked or when graceful restart wait timer fires.
1538 *
1539 */
0c791f87 1540
02552526 1541static void graceful_restart_done(timer *t);
0c791f87 1542
6eda3f13
OZ
1543/**
1544 * graceful_restart_recovery - request initial graceful restart recovery
1545 *
1546 * Called by the platform initialization code if the need for recovery
1547 * after graceful restart is detected during boot. Have to be called
1548 * before protos_commit().
1549 */
0c791f87
OZ
1550void
1551graceful_restart_recovery(void)
1552{
1553 graceful_restart_state = GRS_INIT;
1554}
1555
6eda3f13
OZ
1556/**
1557 * graceful_restart_init - initialize graceful restart
1558 *
1559 * When graceful restart recovery was requested, the function starts an active
1560 * phase of the recovery and initializes graceful restart wait timer. The
1561 * function have to be called after protos_commit().
1562 */
0c791f87
OZ
1563void
1564graceful_restart_init(void)
1565{
1566 if (!graceful_restart_state)
1567 return;
1568
1569 log(L_INFO "Graceful restart started");
1570
1571 if (!graceful_restart_locks)
f4a60a9b
OZ
1572 {
1573 graceful_restart_done(NULL);
1574 return;
1575 }
0c791f87
OZ
1576
1577 graceful_restart_state = GRS_ACTIVE;
a6f79ca5
OZ
1578 gr_wait_timer = tm_new_init(proto_pool, graceful_restart_done, NULL, 0, 0);
1579 tm_start(gr_wait_timer, config->gr_wait S);
0c791f87
OZ
1580}
1581
6eda3f13
OZ
1582/**
1583 * graceful_restart_done - finalize graceful restart
8e433d6a 1584 * @t: unused
6eda3f13
OZ
1585 *
1586 * When there are no locks on graceful restart, the functions finalizes the
1587 * graceful restart recovery. Protocols postponing route export until the end of
1588 * the recovery are awakened and the export to them is enabled. All other
1589 * related state is cleared. The function is also called when the graceful
1590 * restart wait timer fires (but there are still some locks).
1591 */
0c791f87 1592static void
02552526 1593graceful_restart_done(timer *t UNUSED)
0c791f87 1594{
0c791f87
OZ
1595 log(L_INFO "Graceful restart done");
1596 graceful_restart_state = GRS_DONE;
1597
f4a60a9b
OZ
1598 struct proto *p;
1599 WALK_LIST(p, proto_list)
1600 {
1601 if (!p->gr_recovery)
1602 continue;
0c791f87 1603
f4a60a9b
OZ
1604 struct channel *c;
1605 WALK_LIST(c, p->channels)
1606 {
0c791f87 1607 /* Resume postponed export of routes */
2a013bb3 1608 if ((c->channel_state == CS_UP) && c->gr_wait && c->proto->rt_notify)
f4a60a9b 1609 channel_start_export(c);
0c791f87
OZ
1610
1611 /* Cleanup */
f4a60a9b
OZ
1612 c->gr_wait = 0;
1613 c->gr_lock = 0;
0c791f87
OZ
1614 }
1615
f4a60a9b
OZ
1616 p->gr_recovery = 0;
1617 }
1618
0c791f87
OZ
1619 graceful_restart_locks = 0;
1620}
1621
1622void
1623graceful_restart_show_status(void)
1624{
1625 if (graceful_restart_state != GRS_ACTIVE)
1626 return;
1627
1628 cli_msg(-24, "Graceful restart recovery in progress");
f4a60a9b 1629 cli_msg(-24, " Waiting for %d channels to recover", graceful_restart_locks);
a6f79ca5 1630 cli_msg(-24, " Wait timer is %t/%u", tm_remains(gr_wait_timer), config->gr_wait);
0c791f87
OZ
1631}
1632
6eda3f13 1633/**
f4a60a9b
OZ
1634 * channel_graceful_restart_lock - lock graceful restart by channel
1635 * @p: channel instance
6eda3f13
OZ
1636 *
1637 * This function allows a protocol to postpone the end of graceful restart
1638 * recovery until it converges. The lock is removed when the protocol calls
f4a60a9b 1639 * channel_graceful_restart_unlock() or when the channel is closed.
6eda3f13
OZ
1640 *
1641 * The function have to be called during the initial phase of graceful restart
1642 * recovery and only for protocols that are part of graceful restart (i.e. their
1643 * @gr_recovery is set), which means it should be called from protocol start
1644 * hooks.
1645 */
0c791f87 1646void
f4a60a9b 1647channel_graceful_restart_lock(struct channel *c)
0c791f87
OZ
1648{
1649 ASSERT(graceful_restart_state == GRS_INIT);
f4a60a9b 1650 ASSERT(c->proto->gr_recovery);
0c791f87 1651
f4a60a9b 1652 if (c->gr_lock)
0c791f87
OZ
1653 return;
1654
f4a60a9b 1655 c->gr_lock = 1;
0c791f87
OZ
1656 graceful_restart_locks++;
1657}
1658
6eda3f13 1659/**
f4a60a9b
OZ
1660 * channel_graceful_restart_unlock - unlock graceful restart by channel
1661 * @p: channel instance
6eda3f13 1662 *
f4a60a9b 1663 * This function unlocks a lock from channel_graceful_restart_lock(). It is also
6eda3f13
OZ
1664 * automatically called when the lock holding protocol went down.
1665 */
0c791f87 1666void
f4a60a9b 1667channel_graceful_restart_unlock(struct channel *c)
0c791f87 1668{
f4a60a9b 1669 if (!c->gr_lock)
0c791f87
OZ
1670 return;
1671
f4a60a9b 1672 c->gr_lock = 0;
0c791f87
OZ
1673 graceful_restart_locks--;
1674
1675 if ((graceful_restart_state == GRS_ACTIVE) && !graceful_restart_locks)
a6f79ca5 1676 tm_start(gr_wait_timer, 0);
0c791f87
OZ
1677}
1678
1679
1680
3c6269b8
MM
1681/**
1682 * protos_dump_all - dump status of all protocols
1683 *
1684 * This function dumps status of all existing protocol instances to the
1685 * debug output. It involves printing of general status information
1686 * such as protocol states, its position on the protocol lists
1687 * and also calling of a dump() hook of the protocol to print
1688 * the internals.
1689 */
87d2be86
PM
1690void
1691protos_dump_all(void)
1692{
87d2be86
PM
1693 debug("Protocols:\n");
1694
f4a60a9b
OZ
1695 struct proto *p;
1696 WALK_LIST(p, proto_list)
1697 {
1698 debug(" protocol %s state %s\n", p->name, p_states[p->proto_state]);
1699
1700 struct channel *c;
1701 WALK_LIST(c, p->channels)
87d2be86 1702 {
f4a60a9b
OZ
1703 debug("\tTABLE %s\n", c->table->name);
1704 if (c->in_filter)
1705 debug("\tInput filter: %s\n", filter_name(c->in_filter));
1706 if (c->out_filter)
1707 debug("\tOutput filter: %s\n", filter_name(c->out_filter));
87d2be86 1708 }
f4a60a9b
OZ
1709
1710 if (p->proto->dump && (p->proto_state != PS_DOWN))
1711 p->proto->dump(p);
1712 }
87d2be86
PM
1713}
1714
3c6269b8
MM
1715/**
1716 * proto_build - make a single protocol available
1717 * @p: the protocol
1718 *
1719 * After the platform specific initialization code uses protos_build()
1720 * to add all the standard protocols, it should call proto_build() for
2e9b2421 1721 * all platform specific protocols to inform the core that they exist.
3c6269b8 1722 */
3991d84e
MM
1723void
1724proto_build(struct protocol *p)
1725{
1726 add_tail(&protocol_list, &p->n);
ee7e2ffd
JMM
1727 ASSERT(p->class);
1728 ASSERT(!class_to_protocol[p->class]);
1729 class_to_protocol[p->class] = p;
3991d84e
MM
1730}
1731
1ec52253
OZ
1732/* FIXME: convert this call to some protocol hook */
1733extern void bfd_init_all(void);
1734
4a23ede2
MM
1735void protos_build_gen(void);
1736
3c6269b8
MM
1737/**
1738 * protos_build - build a protocol list
1739 *
1740 * This function is called during BIRD startup to insert
1741 * all standard protocols to the global protocol list. Insertion
1742 * of platform specific protocols (such as the kernel syncer)
1743 * is in the domain of competence of the platform dependent
1744 * startup code.
1745 */
0432c017
MM
1746void
1747protos_build(void)
1748{
4a23ede2 1749 protos_build_gen();
6a8d3f1c 1750
67bd949a 1751 proto_pool = rp_new(&root_pool, "Protocols");
a6f79ca5 1752 proto_shutdown_timer = tm_new(proto_pool);
ebecb6f6 1753 proto_shutdown_timer->hook = proto_shutdown_loop;
67bd949a
MM
1754}
1755
fb829de6 1756
d9b77cc2
OZ
1757/* Temporary hack to propagate restart to BGP */
1758int proto_restart;
fb829de6 1759
ebecb6f6 1760static void
02552526 1761proto_shutdown_loop(timer *t UNUSED)
ebecb6f6
OZ
1762{
1763 struct proto *p, *p_next;
1764
f4a60a9b 1765 WALK_LIST_DELSAFE(p, p_next, proto_list)
ebecb6f6 1766 if (p->down_sched)
f4a60a9b
OZ
1767 {
1768 proto_restart = (p->down_sched == PDS_RESTART);
ebecb6f6 1769
f4a60a9b
OZ
1770 p->disabled = 1;
1771 proto_rethink_goal(p);
1772 if (proto_restart)
1773 {
1774 p->disabled = 0;
ebecb6f6 1775 proto_rethink_goal(p);
ebecb6f6 1776 }
f4a60a9b 1777 }
ebecb6f6
OZ
1778}
1779
1780static inline void
1781proto_schedule_down(struct proto *p, byte restart, byte code)
1782{
1783 /* Does not work for other states (even PS_START) */
1784 ASSERT(p->proto_state == PS_UP);
1785
1786 /* Scheduled restart may change to shutdown, but not otherwise */
1787 if (p->down_sched == PDS_DISABLE)
1788 return;
1789
1790 p->down_sched = restart ? PDS_RESTART : PDS_DISABLE;
1791 p->down_code = code;
a6f79ca5 1792 tm_start_max(proto_shutdown_timer, restart ? 250 MS : 0);
ebecb6f6
OZ
1793}
1794
cd1d9961
OZ
1795/**
1796 * proto_set_message - set administrative message to protocol
1797 * @p: protocol
1798 * @msg: message
1799 * @len: message length (-1 for NULL-terminated string)
1800 *
1801 * The function sets administrative message (string) related to protocol state
1802 * change. It is called by the nest code for manual enable/disable/restart
1803 * commands all routes to the protocol, and by protocol-specific code when the
1804 * protocol state change is initiated by the protocol. Using NULL message clears
1805 * the last message. The message string may be either NULL-terminated or with an
1806 * explicit length.
1807 */
1808void
1809proto_set_message(struct proto *p, char *msg, int len)
1810{
1811 mb_free(p->message);
1812 p->message = NULL;
1813
1814 if (!msg || !len)
1815 return;
1816
1817 if (len < 0)
1818 len = strlen(msg);
1819
1820 if (!len)
1821 return;
1822
1823 p->message = mb_alloc(proto_pool, len + 1);
1824 memcpy(p->message, msg, len);
1825 p->message[len] = 0;
1826}
1827
ebecb6f6 1828
ebecb6f6 1829static const char *
f4a60a9b 1830channel_limit_name(struct channel_limit *l)
ebecb6f6
OZ
1831{
1832 const char *actions[] = {
1833 [PLA_WARN] = "warn",
1834 [PLA_BLOCK] = "block",
1835 [PLA_RESTART] = "restart",
1836 [PLA_DISABLE] = "disable",
1837 };
1838
1839 return actions[l->action];
1840}
1841
1842/**
f4a60a9b
OZ
1843 * channel_notify_limit: notify about limit hit and take appropriate action
1844 * @c: channel
ebecb6f6 1845 * @l: limit being hit
b662290f 1846 * @dir: limit direction (PLD_*)
f4a60a9b 1847 * @rt_count: the number of routes
ebecb6f6
OZ
1848 *
1849 * The function is called by the route processing core when limit @l
1850 * is breached. It activates the limit and tooks appropriate action
7d0a31de 1851 * according to @l->action.
ebecb6f6 1852 */
7d0a31de 1853void
f4a60a9b 1854channel_notify_limit(struct channel *c, struct channel_limit *l, int dir, u32 rt_count)
ebecb6f6 1855{
b662290f
OZ
1856 const char *dir_name[PLD_MAX] = { "receive", "import" , "export" };
1857 const byte dir_down[PLD_MAX] = { PDC_RX_LIMIT_HIT, PDC_IN_LIMIT_HIT, PDC_OUT_LIMIT_HIT };
f4a60a9b 1858 struct proto *p = c->proto;
ebecb6f6 1859
7d0a31de
OZ
1860 if (l->state == PLS_BLOCKED)
1861 return;
ebecb6f6 1862
d9b77cc2
OZ
1863 /* For warning action, we want the log message every time we hit the limit */
1864 if (!l->state || ((l->action == PLA_WARN) && (rt_count == l->limit)))
7d0a31de 1865 log(L_WARN "Protocol %s hits route %s limit (%d), action: %s",
f4a60a9b 1866 p->name, dir_name[dir], l->limit, channel_limit_name(l));
ebecb6f6
OZ
1867
1868 switch (l->action)
f4a60a9b
OZ
1869 {
1870 case PLA_WARN:
1871 l->state = PLS_ACTIVE;
1872 break;
1873
1874 case PLA_BLOCK:
1875 l->state = PLS_BLOCKED;
1876 break;
1877
1878 case PLA_RESTART:
1879 case PLA_DISABLE:
1880 l->state = PLS_BLOCKED;
1881 if (p->proto_state == PS_UP)
1882 proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
1883 break;
1884 }
ebecb6f6
OZ
1885}
1886
f4a60a9b
OZ
1887static void
1888channel_verify_limits(struct channel *c)
984d7349 1889{
f4a60a9b
OZ
1890 struct channel_limit *l;
1891 u32 all_routes = c->stats.imp_routes + c->stats.filt_routes;
984d7349 1892
f4a60a9b
OZ
1893 l = &c->rx_limit;
1894 if (l->action && (all_routes > l->limit))
1895 channel_notify_limit(c, l, PLD_RX, all_routes);
984d7349 1896
f4a60a9b
OZ
1897 l = &c->in_limit;
1898 if (l->action && (c->stats.imp_routes > l->limit))
1899 channel_notify_limit(c, l, PLD_IN, c->stats.imp_routes);
984d7349 1900
f4a60a9b
OZ
1901 l = &c->out_limit;
1902 if (l->action && (c->stats.exp_routes > l->limit))
1903 channel_notify_limit(c, l, PLD_OUT, c->stats.exp_routes);
984d7349
OZ
1904}
1905
f4a60a9b
OZ
1906static inline void
1907channel_reset_limit(struct channel_limit *l)
0c791f87 1908{
f4a60a9b
OZ
1909 if (l->action)
1910 l->state = PLS_INITIAL;
0c791f87
OZ
1911}
1912
f4a60a9b
OZ
1913static inline void
1914proto_do_start(struct proto *p)
0c791f87 1915{
f4a60a9b
OZ
1916 p->active = 1;
1917 p->do_start = 1;
1918 ev_schedule(p->event);
0c791f87
OZ
1919}
1920
1921static void
f4a60a9b 1922proto_do_up(struct proto *p)
0c791f87 1923{
f4a60a9b
OZ
1924 if (!p->main_source)
1925 {
1926 p->main_source = rt_get_source(p, 0);
1927 rt_lock_source(p->main_source);
1928 }
0c791f87 1929
f4a60a9b 1930 proto_start_channels(p);
0c791f87
OZ
1931}
1932
f4a60a9b
OZ
1933static inline void
1934proto_do_pause(struct proto *p)
0c791f87 1935{
f4a60a9b 1936 proto_pause_channels(p);
0c791f87
OZ
1937}
1938
1939static void
f4a60a9b 1940proto_do_stop(struct proto *p)
0c791f87 1941{
f4a60a9b 1942 p->down_sched = 0;
0c791f87 1943 p->gr_recovery = 0;
6eda3f13 1944
f4a60a9b
OZ
1945 p->do_stop = 1;
1946 ev_schedule(p->event);
6eda3f13 1947
f4a60a9b
OZ
1948 if (p->main_source)
1949 {
1950 rt_unlock_source(p->main_source);
1951 p->main_source = NULL;
1952 }
6eda3f13 1953
f4a60a9b
OZ
1954 proto_stop_channels(p);
1955}
6eda3f13 1956
f4a60a9b
OZ
1957static void
1958proto_do_down(struct proto *p)
1959{
1960 p->down_code = 0;
1961 neigh_prune();
1962 rfree(p->pool);
1963 p->pool = NULL;
1964
1965 /* Shutdown is finished in the protocol event */
1966 if (proto_is_done(p))
1967 ev_schedule(p->event);
6eda3f13
OZ
1968}
1969
0c791f87 1970
f4a60a9b 1971
3c6269b8
MM
1972/**
1973 * proto_notify_state - notify core about protocol state change
1974 * @p: protocol the state of which has changed
1975 * @ps: the new status
1976 *
1977 * Whenever a state of a protocol changes due to some event internal
1978 * to the protocol (i.e., not inside a start() or shutdown() hook),
1979 * it should immediately notify the core about the change by calling
1980 * proto_notify_state() which will write the new state to the &proto
1981 * structure and take all the actions necessary to adapt to the new
d6a836f8
OZ
1982 * state. State change to PS_DOWN immediately frees resources of protocol
1983 * and might execute start callback of protocol; therefore,
1984 * it should be used at tail positions of protocol callbacks.
3c6269b8 1985 */
67bd949a 1986void
f4a60a9b 1987proto_notify_state(struct proto *p, uint state)
67bd949a 1988{
f4a60a9b 1989 uint ps = p->proto_state;
67bd949a 1990
f4a60a9b
OZ
1991 DBG("%s reporting state transition %s -> %s\n", p->name, p_states[ps], p_states[state]);
1992 if (state == ps)
67bd949a
MM
1993 return;
1994
f4a60a9b 1995 p->proto_state = state;
f047271c 1996 p->last_state_change = current_time();
d6a836f8 1997
f4a60a9b
OZ
1998 switch (state)
1999 {
2000 case PS_START:
2001 ASSERT(ps == PS_DOWN || ps == PS_UP);
2002
2003 if (ps == PS_DOWN)
2004 proto_do_start(p);
2005 else
2006 proto_do_pause(p);
2007 break;
2008
2009 case PS_UP:
2010 ASSERT(ps == PS_DOWN || ps == PS_START);
2011
2012 if (ps == PS_DOWN)
2013 proto_do_start(p);
2014
2015 proto_do_up(p);
2016 break;
2017
2018 case PS_STOP:
2019 ASSERT(ps == PS_START || ps == PS_UP);
2020
2021 proto_do_stop(p);
2022 break;
2023
2024 case PS_DOWN:
2025 if (ps != PS_STOP)
2026 proto_do_stop(p);
2027
2028 proto_do_down(p);
2029 break;
2030
2031 default:
2032 bug("%s: Invalid state %d", p->name, ps);
2033 }
227af309
OZ
2034
2035 proto_log_state_change(p);
0432c017 2036}
1a54b1c6 2037
0d3e6bce
MM
2038/*
2039 * CLI Commands
2040 */
2041
2042static char *
2043proto_state_name(struct proto *p)
2044{
f4a60a9b
OZ
2045 switch (p->proto_state)
2046 {
2047 case PS_DOWN: return p->active ? "flush" : "down";
2048 case PS_START: return "start";
2049 case PS_UP: return "up";
2050 case PS_STOP: return "stop";
2051 default: return "???";
2052 }
0d3e6bce
MM
2053}
2054
9db74169 2055static void
f4a60a9b 2056channel_show_stats(struct channel *c)
9db74169 2057{
f4a60a9b
OZ
2058 struct proto_stats *s = &c->stats;
2059
2060 if (c->in_keep_filtered)
52fdd1cb
OZ
2061 cli_msg(-1006, " Routes: %u imported, %u filtered, %u exported, %u preferred",
2062 s->imp_routes, s->filt_routes, s->exp_routes, s->pref_routes);
cf98be7b 2063 else
e1c275d8
OZ
2064 cli_msg(-1006, " Routes: %u imported, %u exported, %u preferred",
2065 s->imp_routes, s->exp_routes, s->pref_routes);
cf98be7b 2066
f4a60a9b
OZ
2067 cli_msg(-1006, " Route change stats: received rejected filtered ignored accepted");
2068 cli_msg(-1006, " Import updates: %10u %10u %10u %10u %10u",
9db74169
OZ
2069 s->imp_updates_received, s->imp_updates_invalid,
2070 s->imp_updates_filtered, s->imp_updates_ignored,
2071 s->imp_updates_accepted);
f4a60a9b 2072 cli_msg(-1006, " Import withdraws: %10u %10u --- %10u %10u",
9db74169
OZ
2073 s->imp_withdraws_received, s->imp_withdraws_invalid,
2074 s->imp_withdraws_ignored, s->imp_withdraws_accepted);
f4a60a9b 2075 cli_msg(-1006, " Export updates: %10u %10u %10u --- %10u",
9db74169
OZ
2076 s->exp_updates_received, s->exp_updates_rejected,
2077 s->exp_updates_filtered, s->exp_updates_accepted);
f4a60a9b 2078 cli_msg(-1006, " Export withdraws: %10u --- --- --- %10u",
9db74169
OZ
2079 s->exp_withdraws_received, s->exp_withdraws_accepted);
2080}
2081
ebecb6f6 2082void
f4a60a9b 2083channel_show_limit(struct channel_limit *l, const char *dsc)
ebecb6f6 2084{
f4a60a9b 2085 if (!l->action)
7d0a31de
OZ
2086 return;
2087
f4a60a9b
OZ
2088 cli_msg(-1006, " %-16s%d%s", dsc, l->limit, l->state ? " [HIT]" : "");
2089 cli_msg(-1006, " Action: %s", channel_limit_name(l));
ebecb6f6
OZ
2090}
2091
c0adf7e9 2092void
f4a60a9b 2093channel_show_info(struct channel *c)
9db74169 2094{
f4a60a9b 2095 cli_msg(-1006, " Channel %s", c->name);
d15b0b0a 2096 cli_msg(-1006, " State: %s", c_states[c->channel_state]);
f4a60a9b
OZ
2097 cli_msg(-1006, " Table: %s", c->table->name);
2098 cli_msg(-1006, " Preference: %d", c->preference);
2099 cli_msg(-1006, " Input filter: %s", filter_name(c->in_filter));
2100 cli_msg(-1006, " Output filter: %s", filter_name(c->out_filter));
9db74169 2101
0c791f87 2102 if (graceful_restart_state == GRS_ACTIVE)
f4a60a9b
OZ
2103 cli_msg(-1006, " GR recovery: %s%s",
2104 c->gr_lock ? " pending" : "",
2105 c->gr_wait ? " waiting" : "");
0c791f87 2106
f4a60a9b
OZ
2107 channel_show_limit(&c->rx_limit, "Receive limit:");
2108 channel_show_limit(&c->in_limit, "Import limit:");
2109 channel_show_limit(&c->out_limit, "Export limit:");
ebecb6f6 2110
f4a60a9b
OZ
2111 if (c->channel_state != CS_DOWN)
2112 channel_show_stats(c);
9db74169
OZ
2113}
2114
61dae32b
OZ
2115void
2116channel_cmd_debug(struct channel *c, uint mask)
2117{
2118 if (cli_access_restricted())
2119 return;
2120
2121 c->debug = mask;
2122 cli_msg(0, "");
2123}
2124
e304fd4b 2125void
cd1d9961 2126proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
1d2664a4 2127{
c37e7851 2128 byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
9685deb9 2129
e304fd4b
OZ
2130 /* First protocol - show header */
2131 if (!cnt)
eb95b5ec
OZ
2132 cli_msg(-2002, "%-10s %-10s %-10s %-6s %-12s %s",
2133 "Name", "Proto", "Table", "State", "Since", "Info");
e304fd4b 2134
9685deb9
MM
2135 buf[0] = 0;
2136 if (p->proto->get_status)
2137 p->proto->get_status(p, buf);
f047271c 2138 tm_format_time(tbuf, &config->tf_proto, p->last_state_change);
eb95b5ec 2139 cli_msg(-1002, "%-10s %-10s %-10s %-6s %-12s %s",
1d2664a4
MM
2140 p->name,
2141 p->proto->name,
f4a60a9b 2142 p->main_channel ? p->main_channel->table->name : "---",
1d2664a4 2143 proto_state_name(p),
c37e7851 2144 tbuf,
9685deb9 2145 buf);
f4a60a9b 2146
1d2664a4 2147 if (verbose)
f4a60a9b
OZ
2148 {
2149 if (p->cf->dsc)
2150 cli_msg(-1006, " Description: %s", p->cf->dsc);
830ba75e
OZ
2151 if (p->message)
2152 cli_msg(-1006, " Message: %s", p->message);
f4a60a9b
OZ
2153 if (p->cf->router_id)
2154 cli_msg(-1006, " Router ID: %R", p->cf->router_id);
18f70a62
OZ
2155 if (p->vrf_set)
2156 cli_msg(-1006, " VRF: %s", p->vrf ? p->vrf->name : "default");
f4a60a9b
OZ
2157
2158 if (p->proto->show_proto_info)
2159 p->proto->show_proto_info(p);
2160 else
1d2664a4 2161 {
f4a60a9b
OZ
2162 struct channel *c;
2163 WALK_LIST(c, p->channels)
2164 channel_show_info(c);
1d2664a4 2165 }
f4a60a9b
OZ
2166
2167 cli_msg(-1006, "");
2168 }
1d2664a4
MM
2169}
2170
ae97b946 2171void
cd1d9961 2172proto_cmd_disable(struct proto *p, uintptr_t arg, int cnt UNUSED)
ae97b946 2173{
e304fd4b 2174 if (p->disabled)
f4a60a9b
OZ
2175 {
2176 cli_msg(-8, "%s: already disabled", p->name);
2177 return;
2178 }
e304fd4b
OZ
2179
2180 log(L_INFO "Disabling protocol %s", p->name);
2181 p->disabled = 1;
ebecb6f6 2182 p->down_code = PDC_CMD_DISABLE;
cd1d9961 2183 proto_set_message(p, (char *) arg, -1);
e304fd4b
OZ
2184 proto_rethink_goal(p);
2185 cli_msg(-9, "%s: disabled", p->name);
2186}
2187
2188void
cd1d9961 2189proto_cmd_enable(struct proto *p, uintptr_t arg, int cnt UNUSED)
e304fd4b
OZ
2190{
2191 if (!p->disabled)
f4a60a9b
OZ
2192 {
2193 cli_msg(-10, "%s: already enabled", p->name);
2194 return;
2195 }
e304fd4b
OZ
2196
2197 log(L_INFO "Enabling protocol %s", p->name);
2198 p->disabled = 0;
cd1d9961 2199 proto_set_message(p, (char *) arg, -1);
e304fd4b
OZ
2200 proto_rethink_goal(p);
2201 cli_msg(-11, "%s: enabled", p->name);
2202}
2203
2204void
cd1d9961 2205proto_cmd_restart(struct proto *p, uintptr_t arg, int cnt UNUSED)
e304fd4b
OZ
2206{
2207 if (p->disabled)
f4a60a9b
OZ
2208 {
2209 cli_msg(-8, "%s: already disabled", p->name);
2210 return;
2211 }
e304fd4b
OZ
2212
2213 log(L_INFO "Restarting protocol %s", p->name);
2214 p->disabled = 1;
ebecb6f6 2215 p->down_code = PDC_CMD_RESTART;
cd1d9961 2216 proto_set_message(p, (char *) arg, -1);
e304fd4b
OZ
2217 proto_rethink_goal(p);
2218 p->disabled = 0;
2219 proto_rethink_goal(p);
2220 cli_msg(-12, "%s: restarted", p->name);
2221}
2222
2223void
cd1d9961 2224proto_cmd_reload(struct proto *p, uintptr_t dir, int cnt UNUSED)
e304fd4b 2225{
f4a60a9b
OZ
2226 struct channel *c;
2227
e304fd4b 2228 if (p->disabled)
f4a60a9b
OZ
2229 {
2230 cli_msg(-8, "%s: already disabled", p->name);
2231 return;
2232 }
e304fd4b
OZ
2233
2234 /* If the protocol in not UP, it has no routes */
2235 if (p->proto_state != PS_UP)
2236 return;
2237
f4a60a9b
OZ
2238 /* All channels must support reload */
2239 if (dir != CMD_RELOAD_OUT)
2240 WALK_LIST(c, p->channels)
a297a4f0 2241 if ((c->channel_state == CS_UP) && !channel_reloadable(c))
f4a60a9b
OZ
2242 {
2243 cli_msg(-8006, "%s: reload failed", p->name);
2244 return;
2245 }
2246
e304fd4b
OZ
2247 log(L_INFO "Reloading protocol %s", p->name);
2248
2249 /* re-importing routes */
2250 if (dir != CMD_RELOAD_OUT)
f4a60a9b 2251 WALK_LIST(c, p->channels)
a297a4f0
OZ
2252 if (c->channel_state == CS_UP)
2253 channel_request_reload(c);
ebecb6f6 2254
e304fd4b
OZ
2255 /* re-exporting routes */
2256 if (dir != CMD_RELOAD_IN)
f4a60a9b 2257 WALK_LIST(c, p->channels)
a297a4f0
OZ
2258 if (c->channel_state == CS_UP)
2259 channel_request_feeding(c);
e304fd4b
OZ
2260
2261 cli_msg(-15, "%s: reloading", p->name);
2262}
2263
2f981534
OZ
2264extern void pipe_update_debug(struct proto *P);
2265
e304fd4b 2266void
cd1d9961 2267proto_cmd_debug(struct proto *p, uintptr_t mask, int cnt UNUSED)
e304fd4b
OZ
2268{
2269 p->debug = mask;
2f981534
OZ
2270
2271#ifdef CONFIG_PIPE
2272 if (p->proto == &proto_pipe)
2273 pipe_update_debug(p);
2274#endif
e304fd4b
OZ
2275}
2276
2277void
cd1d9961 2278proto_cmd_mrtdump(struct proto *p, uintptr_t mask, int cnt UNUSED)
e304fd4b
OZ
2279{
2280 p->mrtdump = mask;
2281}
2282
2283static void
fd9f0c06 2284proto_apply_cmd_symbol(const struct symbol *s, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
e304fd4b
OZ
2285{
2286 if (s->class != SYM_PROTO)
f4a60a9b
OZ
2287 {
2288 cli_msg(9002, "%s is not a protocol", s->name);
2289 return;
2290 }
e304fd4b 2291
8216ec30
MM
2292 if (s->proto->proto)
2293 {
2294 cmd(s->proto->proto, arg, 0);
2295 cli_msg(0, "");
2296 }
2297 else
2298 cli_msg(9002, "%s does not exist", s->name);
ae97b946 2299}
02c1fbdd 2300
e304fd4b 2301static void
fd9f0c06 2302proto_apply_cmd_patt(const char *patt, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
e304fd4b 2303{
f4a60a9b 2304 struct proto *p;
e304fd4b
OZ
2305 int cnt = 0;
2306
f4a60a9b
OZ
2307 WALK_LIST(p, proto_list)
2308 if (!patt || patmatch(patt, p->name))
2309 cmd(p, arg, cnt++);
e304fd4b
OZ
2310
2311 if (!cnt)
2312 cli_msg(8003, "No protocols match");
2313 else
2314 cli_msg(0, "");
2315}
2316
2317void
cd1d9961
OZ
2318proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int),
2319 int restricted, uintptr_t arg)
e304fd4b 2320{
e0a45fb4
OZ
2321 if (restricted && cli_access_restricted())
2322 return;
2323
e304fd4b
OZ
2324 if (ps.patt)
2325 proto_apply_cmd_patt(ps.ptr, cmd, arg);
2326 else
2327 proto_apply_cmd_symbol(ps.ptr, cmd, arg);
2328}
2329
02c1fbdd
MM
2330struct proto *
2331proto_get_named(struct symbol *sym, struct protocol *pr)
2332{
2333 struct proto *p, *q;
2334
2335 if (sym)
f4a60a9b
OZ
2336 {
2337 if (sym->class != SYM_PROTO)
2338 cf_error("%s: Not a protocol", sym->name);
2339
0b39b1cb 2340 p = sym->proto->proto;
f4a60a9b
OZ
2341 if (!p || p->proto != pr)
2342 cf_error("%s: Not a %s protocol", sym->name, pr->name);
2343 }
02c1fbdd 2344 else
f4a60a9b
OZ
2345 {
2346 p = NULL;
2347 WALK_LIST(q, proto_list)
2348 if ((q->proto == pr) && (q->proto_state != PS_DOWN))
2349 {
2350 if (p)
2351 cf_error("There are multiple %s protocols running", pr->name);
2352 p = q;
2353 }
2354 if (!p)
2355 cf_error("There is no %s protocol running", pr->name);
2356 }
2357
02c1fbdd
MM
2358 return p;
2359}
c26c6bc2
OZ
2360
2361struct proto *
2362proto_iterate_named(struct symbol *sym, struct protocol *proto, struct proto *old)
2363{
2364 if (sym)
2365 {
2366 /* Just the first pass */
2367 if (old)
2368 {
2369 cli_msg(0, "");
2370 return NULL;
2371 }
2372
2373 if (sym->class != SYM_PROTO)
2374 cf_error("%s: Not a protocol", sym->name);
2375
2376 struct proto *p = sym->proto->proto;
2377 if (!p || (p->proto != proto))
2378 cf_error("%s: Not a %s protocol", sym->name, proto->name);
2379
2380 return p;
2381 }
2382 else
2383 {
2384 for (struct proto *p = !old ? HEAD(proto_list) : NODE_NEXT(old);
2385 NODE_VALID(p);
2386 p = NODE_NEXT(p))
2387 {
2388 if ((p->proto == proto) && (p->proto_state != PS_DOWN))
2389 {
2390 cli_separator(this_cli);
2391 return p;
2392 }
2393 }
2394
2395 /* Not found anything during first pass */
2396 if (!old)
2397 cf_error("There is no %s protocol running", proto->name);
2398
2399 /* No more items */
2400 cli_msg(0, "");
2401 return NULL;
2402 }
2403}