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