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>