Annotation of embedaddon/bird/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/string.h"
                     17: #include "conf/conf.h"
                     18: #include "nest/route.h"
                     19: #include "nest/iface.h"
                     20: #include "nest/cli.h"
                     21: #include "filter/filter.h"
                     22: 
                     23: pool *proto_pool;
                     24: 
                     25: static list protocol_list;
                     26: static list proto_list;
                     27: 
                     28: #define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0)
                     29: 
                     30: list active_proto_list;
                     31: static list inactive_proto_list;
                     32: static list initial_proto_list;
                     33: static list flush_proto_list;
                     34: static struct proto *initial_device_proto;
                     35: 
                     36: static event *proto_flush_event;
                     37: static timer *proto_shutdown_timer;
                     38: static timer *gr_wait_timer;
                     39: 
                     40: #define GRS_NONE       0
                     41: #define GRS_INIT       1
                     42: #define GRS_ACTIVE     2
                     43: #define GRS_DONE       3
                     44: 
                     45: static int graceful_restart_state;
                     46: static u32 graceful_restart_locks;
                     47: 
                     48: static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
                     49: static char *c_states[] = { "HUNGRY", "???", "HAPPY", "FLUSHING" };
                     50: 
                     51: static void proto_flush_loop(void *);
                     52: static void proto_shutdown_loop(struct timer *);
                     53: static void proto_rethink_goal(struct proto *p);
                     54: static void proto_want_export_up(struct proto *p);
                     55: static void proto_fell_down(struct proto *p);
                     56: static char *proto_state_name(struct proto *p);
                     57: 
                     58: static void
                     59: proto_relink(struct proto *p)
                     60: {
                     61:   list *l = NULL;
                     62: 
                     63:   switch (p->core_state)
                     64:     {
                     65:     case FS_HUNGRY:
                     66:       l = &inactive_proto_list;
                     67:       break;
                     68:     case FS_HAPPY:
                     69:       l = &active_proto_list;
                     70:       break;
                     71:     case FS_FLUSHING:
                     72:       l = &flush_proto_list;
                     73:       break;
                     74:     default:
                     75:       ASSERT(0);
                     76:     }
                     77: 
                     78:   rem_node(&p->n);
                     79:   add_tail(l, &p->n);
                     80: }
                     81: 
                     82: static void
                     83: proto_log_state_change(struct proto *p)
                     84: {
                     85:   if (p->debug & D_STATES)
                     86:     {
                     87:       char *name = proto_state_name(p);
                     88:       if (name != p->last_state_name_announced)
                     89:        {
                     90:          p->last_state_name_announced = name;
                     91:          PD(p, "State changed to %s", proto_state_name(p));
                     92:        }
                     93:     }
                     94:   else
                     95:     p->last_state_name_announced = NULL;
                     96: }
                     97: 
                     98: 
                     99: /**
                    100:  * proto_new - create a new protocol instance
                    101:  * @c: protocol configuration
                    102:  * @size: size of protocol data structure (each protocol instance is represented by
                    103:  * a structure starting with generic part [struct &proto] and continued
                    104:  * with data specific to the protocol)
                    105:  *
                    106:  * When a new configuration has been read in, the core code starts
                    107:  * initializing all the protocol instances configured by calling their
                    108:  * init() hooks with the corresponding instance configuration. The initialization
                    109:  * code of the protocol is expected to create a new instance according to the
                    110:  * configuration by calling this function and then modifying the default settings
                    111:  * to values wanted by the protocol.
                    112:  */
                    113: void *
                    114: proto_new(struct proto_config *c, unsigned size)
                    115: {
                    116:   struct protocol *pr = c->protocol;
                    117:   struct proto *p = mb_allocz(proto_pool, size);
                    118: 
                    119:   p->cf = c;
                    120:   p->debug = c->debug;
                    121:   p->mrtdump = c->mrtdump;
                    122:   p->name = c->name;
                    123:   p->preference = c->preference;
                    124:   p->disabled = c->disabled;
                    125:   p->proto = pr;
                    126:   p->table = c->table->table;
                    127:   p->hash_key = random_u32();
                    128:   c->proto = p;
                    129:   return p;
                    130: }
                    131: 
                    132: static void
                    133: proto_init_instance(struct proto *p)
                    134: {
                    135:   /* Here we cannot use p->cf->name since it won't survive reconfiguration */
                    136:   p->pool = rp_new(proto_pool, p->proto->name);
                    137:   p->attn = ev_new(p->pool);
                    138:   p->attn->data = p;
                    139: 
                    140:   if (graceful_restart_state == GRS_INIT)
                    141:     p->gr_recovery = 1;
                    142: 
                    143:   if (! p->proto->multitable)
                    144:     rt_lock_table(p->table);
                    145: }
                    146: 
                    147: extern pool *rt_table_pool;
                    148: /**
                    149:  * proto_add_announce_hook - connect protocol to a routing table
                    150:  * @p: protocol instance
                    151:  * @t: routing table to connect to
                    152:  * @stats: per-table protocol statistics
                    153:  *
                    154:  * This function creates a connection between the protocol instance @p and the
                    155:  * routing table @t, making the protocol hear all changes in the table.
                    156:  *
                    157:  * The announce hook is linked in the protocol ahook list. Announce hooks are
                    158:  * allocated from the routing table resource pool and when protocol accepts
                    159:  * routes also in the table ahook list. The are linked to the table ahook list
                    160:  * and unlinked from it depending on export_state (in proto_want_export_up() and
                    161:  * proto_want_export_down()) and they are automatically freed after the protocol
                    162:  * is flushed (in proto_fell_down()).
                    163:  *
                    164:  * Unless you want to listen to multiple routing tables (as the Pipe protocol
                    165:  * does), you needn't to worry about this function since the connection to the
                    166:  * protocol's primary routing table is initialized automatically by the core
                    167:  * code.
                    168:  */
                    169: struct announce_hook *
                    170: proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats)
                    171: {
                    172:   struct announce_hook *h;
                    173: 
                    174:   DBG("Connecting protocol %s to table %s\n", p->name, t->name);
                    175:   PD(p, "Connected to table %s", t->name);
                    176: 
                    177:   h = mb_allocz(rt_table_pool, sizeof(struct announce_hook));
                    178:   h->table = t;
                    179:   h->proto = p;
                    180:   h->stats = stats;
                    181: 
                    182:   h->next = p->ahooks;
                    183:   p->ahooks = h;
                    184: 
                    185:   if (p->rt_notify && (p->export_state != ES_DOWN))
                    186:     add_tail(&t->hooks, &h->n);
                    187:   return h;
                    188: }
                    189: 
                    190: /**
                    191:  * proto_find_announce_hook - find announce hooks
                    192:  * @p: protocol instance
                    193:  * @t: routing table
                    194:  *
                    195:  * Returns pointer to announce hook or NULL
                    196:  */
                    197: struct announce_hook *
                    198: proto_find_announce_hook(struct proto *p, struct rtable *t)
                    199: {
                    200:   struct announce_hook *a;
                    201: 
                    202:   for (a = p->ahooks; a; a = a->next)
                    203:     if (a->table == t)
                    204:       return a;
                    205: 
                    206:   return NULL;
                    207: }
                    208: 
                    209: static void
                    210: proto_link_ahooks(struct proto *p)
                    211: {
                    212:   struct announce_hook *h;
                    213: 
                    214:   if (p->rt_notify)
                    215:     for(h=p->ahooks; h; h=h->next)
                    216:       add_tail(&h->table->hooks, &h->n);
                    217: }
                    218: 
                    219: static void
                    220: proto_unlink_ahooks(struct proto *p)
                    221: {
                    222:   struct announce_hook *h;
                    223: 
                    224:   if (p->rt_notify)
                    225:     for(h=p->ahooks; h; h=h->next)
                    226:       rem_node(&h->n);
                    227: }
                    228: 
                    229: static void
                    230: proto_free_ahooks(struct proto *p)
                    231: {
                    232:   struct announce_hook *h, *hn;
                    233: 
                    234:   for(h = p->ahooks; h; h = hn)
                    235:   {
                    236:     hn = h->next;
                    237:     mb_free(h);
                    238:   }
                    239: 
                    240:   p->ahooks = NULL;
                    241:   p->main_ahook = NULL;
                    242: }
                    243: 
                    244: 
                    245: /**
                    246:  * proto_config_new - create a new protocol configuration
                    247:  * @pr: protocol the configuration will belong to
                    248:  * @class: SYM_PROTO or SYM_TEMPLATE
                    249:  *
                    250:  * Whenever the configuration file says that a new instance
                    251:  * of a routing protocol should be created, the parser calls
                    252:  * proto_config_new() to create a configuration entry for this
                    253:  * instance (a structure staring with the &proto_config header
                    254:  * containing all the generic items followed by protocol-specific
                    255:  * ones). Also, the configuration entry gets added to the list
                    256:  * of protocol instances kept in the configuration.
                    257:  *
                    258:  * The function is also used to create protocol templates (when class
                    259:  * SYM_TEMPLATE is specified), the only difference is that templates
                    260:  * are not added to the list of protocol instances and therefore not
                    261:  * initialized during protos_commit()).
                    262:  */
                    263: void *
                    264: proto_config_new(struct protocol *pr, int class)
                    265: {
                    266:   struct proto_config *c = cfg_allocz(pr->config_size);
                    267: 
                    268:   if (class == SYM_PROTO)
                    269:     add_tail(&new_config->protos, &c->n);
                    270:   c->global = new_config;
                    271:   c->protocol = pr;
                    272:   c->name = pr->name;
                    273:   c->preference = pr->preference;
                    274:   c->class = class;
                    275:   c->out_filter = FILTER_REJECT;
                    276:   c->table = c->global->master_rtc;
                    277:   c->debug = new_config->proto_default_debug;
                    278:   c->mrtdump = new_config->proto_default_mrtdump;
                    279:   return c;
                    280: }
                    281: 
                    282: /**
                    283:  * proto_copy_config - copy a protocol configuration
                    284:  * @dest: destination protocol configuration
                    285:  * @src: source protocol configuration
                    286:  *
                    287:  * Whenever a new instance of a routing protocol is created from the
                    288:  * template, proto_copy_config() is called to copy a content of
                    289:  * the source protocol configuration to the new protocol configuration.
                    290:  * Name, class and a node in protos list of @dest are kept intact.
                    291:  * copy_config() protocol hook is used to copy protocol-specific data.
                    292:  */
                    293: void
                    294: proto_copy_config(struct proto_config *dest, struct proto_config *src)
                    295: {
                    296:   node old_node;
                    297:   int old_class;
                    298:   char *old_name;
                    299: 
                    300:   if (dest->protocol != src->protocol)
                    301:     cf_error("Can't copy configuration from a different protocol type");
                    302: 
                    303:   if (dest->protocol->copy_config == NULL)
                    304:     cf_error("Inheriting configuration for %s is not supported", src->protocol->name);
                    305: 
                    306:   DBG("Copying configuration from %s to %s\n", src->name, dest->name);
                    307: 
                    308:   /* 
                    309:    * Copy struct proto_config here. Keep original node, class and name.
                    310:    * protocol-specific config copy is handled by protocol copy_config() hook
                    311:    */
                    312: 
                    313:   old_node = dest->n;
                    314:   old_class = dest->class;
                    315:   old_name = dest->name;
                    316: 
                    317:   memcpy(dest, src, sizeof(struct proto_config));
                    318: 
                    319:   dest->n = old_node;
                    320:   dest->class = old_class;
                    321:   dest->name = old_name;
                    322: 
                    323:   dest->protocol->copy_config(dest, src);
                    324: }
                    325: 
                    326: /**
                    327:  * protos_preconfig - pre-configuration processing
                    328:  * @c: new configuration
                    329:  *
                    330:  * This function calls the preconfig() hooks of all routing
                    331:  * protocols available to prepare them for reading of the new
                    332:  * configuration.
                    333:  */
                    334: void
                    335: protos_preconfig(struct config *c)
                    336: {
                    337:   struct protocol *p;
                    338: 
                    339:   init_list(&c->protos);
                    340:   DBG("Protocol preconfig:");
                    341:   WALK_LIST(p, protocol_list)
                    342:     {
                    343:       DBG(" %s", p->name);
                    344:       p->name_counter = 0;
                    345:       if (p->preconfig)
                    346:        p->preconfig(p, c);
                    347:     }
                    348:   DBG("\n");
                    349: }
                    350: 
                    351: /**
                    352:  * protos_postconfig - post-configuration processing
                    353:  * @c: new configuration
                    354:  *
                    355:  * This function calls the postconfig() hooks of all protocol
                    356:  * instances specified in configuration @c. The hooks are not
                    357:  * called for protocol templates.
                    358:  */
                    359: void
                    360: protos_postconfig(struct config *c)
                    361: {
                    362:   struct proto_config *x;
                    363:   struct protocol *p;
                    364: 
                    365:   DBG("Protocol postconfig:");
                    366:   WALK_LIST(x, c->protos)
                    367:     {
                    368:       DBG(" %s", x->name);
                    369: 
                    370:       p = x->protocol;
                    371:       if (p->postconfig)
                    372:        p->postconfig(x);
                    373:     }
                    374:   DBG("\n");
                    375: }
                    376: 
                    377: extern struct protocol proto_unix_iface;
                    378: 
                    379: static struct proto *
                    380: proto_init(struct proto_config *c)
                    381: {
                    382:   struct protocol *p = c->protocol;
                    383:   struct proto *q = p->init(c);
                    384: 
                    385:   q->proto_state = PS_DOWN;
                    386:   q->core_state = FS_HUNGRY;
                    387:   q->export_state = ES_DOWN;
                    388:   q->last_state_change = now;
                    389: 
                    390:   add_tail(&initial_proto_list, &q->n);
                    391: 
                    392:   if (p == &proto_unix_iface)
                    393:     initial_device_proto = q;
                    394: 
                    395:   add_tail(&proto_list, &q->glob_node);
                    396:   PD(q, "Initializing%s", q->disabled ? " [disabled]" : "");
                    397:   return q;
                    398: }
                    399: 
                    400: int proto_reconfig_type;  /* Hack to propagate type info to pipe reconfigure hook */
                    401: 
                    402: static int
                    403: proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
                    404: {
                    405:   /* If the protocol is DOWN, we just restart it */
                    406:   if (p->proto_state == PS_DOWN)
                    407:     return 0;
                    408: 
                    409:   /* If there is a too big change in core attributes, ... */
                    410:   if ((nc->protocol != oc->protocol) ||
                    411:       (nc->disabled != p->disabled) ||
                    412:       (nc->table->table != oc->table->table))
                    413:     return 0;
                    414: 
                    415:   p->debug = nc->debug;
                    416:   p->mrtdump = nc->mrtdump;
                    417:   proto_reconfig_type = type;
                    418: 
                    419:   /* Execute protocol specific reconfigure hook */
                    420:   if (! (p->proto->reconfigure && p->proto->reconfigure(p, nc)))
                    421:     return 0;
                    422: 
                    423:   DBG("\t%s: same\n", oc->name);
                    424:   PD(p, "Reconfigured");
                    425:   p->cf = nc;
                    426:   p->name = nc->name;
                    427:   p->preference = nc->preference;
                    428: 
                    429: 
                    430:   /* Multitable protocols handle rest in their reconfigure hooks */
                    431:   if (p->proto->multitable)
                    432:     return 1;
                    433: 
                    434:   /* Update filters and limits in the main announce hook
                    435:      Note that this also resets limit state */
                    436:   if (p->main_ahook)
                    437:     {  
                    438:       struct announce_hook *ah = p->main_ahook;
                    439:       ah->in_filter = nc->in_filter;
                    440:       ah->out_filter = nc->out_filter;
                    441:       ah->rx_limit = nc->rx_limit;
                    442:       ah->in_limit = nc->in_limit;
                    443:       ah->out_limit = nc->out_limit;
                    444:       ah->in_keep_filtered = nc->in_keep_filtered;
                    445:       proto_verify_limits(ah);
                    446:     }
                    447: 
                    448:   /* Update routes when filters changed. If the protocol in not UP,
                    449:      it has no routes and we can ignore such changes */
                    450:   if ((p->proto_state != PS_UP) || (type == RECONFIG_SOFT))
                    451:     return 1;
                    452: 
                    453:   int import_changed = ! filter_same(nc->in_filter, oc->in_filter);
                    454:   int export_changed = ! filter_same(nc->out_filter, oc->out_filter);
                    455: 
                    456:   /* We treat a change in preferences by reimporting routes */
                    457:   if (nc->preference != oc->preference)
                    458:     import_changed = 1;
                    459: 
                    460:   if (import_changed || export_changed)
                    461:     log(L_INFO "Reloading protocol %s", p->name);
                    462: 
                    463:   /* If import filter changed, call reload hook */
                    464:   if (import_changed && ! (p->reload_routes && p->reload_routes(p)))
                    465:     {
                    466:       /* Now, the protocol is reconfigured. But route reload failed
                    467:         and we have to do regular protocol restart. */
                    468:       log(L_INFO "Restarting protocol %s", p->name);
                    469:       p->disabled = 1;
                    470:       p->down_code = PDC_CF_RESTART;
                    471:       proto_rethink_goal(p);
                    472:       p->disabled = 0;
                    473:       proto_rethink_goal(p);
                    474:       return 1;
                    475:     }
                    476: 
                    477:   if (export_changed)
                    478:     proto_request_feeding(p);
                    479: 
                    480:   return 1;
                    481: }
                    482: 
                    483: /**
                    484:  * protos_commit - commit new protocol configuration
                    485:  * @new: new configuration
                    486:  * @old: old configuration or %NULL if it's boot time config
                    487:  * @force_reconfig: force restart of all protocols (used for example
                    488:  * when the router ID changes)
                    489:  * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
                    490:  *
                    491:  * Scan differences between @old and @new configuration and adjust all
                    492:  * protocol instances to conform to the new configuration.
                    493:  *
                    494:  * When a protocol exists in the new configuration, but it doesn't in the
                    495:  * original one, it's immediately started. When a collision with the other
                    496:  * running protocol would arise, the new protocol will be temporarily stopped
                    497:  * by the locking mechanism.
                    498:  *
                    499:  * When a protocol exists in the old configuration, but it doesn't in the
                    500:  * new one, it's shut down and deleted after the shutdown completes.
                    501:  *
                    502:  * When a protocol exists in both configurations, the core decides
                    503:  * whether it's possible to reconfigure it dynamically - it checks all
                    504:  * the core properties of the protocol (changes in filters are ignored
                    505:  * if type is RECONFIG_SOFT) and if they match, it asks the
                    506:  * reconfigure() hook of the protocol to see if the protocol is able
                    507:  * to switch to the new configuration.  If it isn't possible, the
                    508:  * protocol is shut down and a new instance is started with the new
                    509:  * configuration after the shutdown is completed.
                    510:  */
                    511: void
                    512: protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
                    513: {
                    514:   struct proto_config *oc, *nc;
                    515:   struct proto *p, *n;
                    516:   struct symbol *sym;
                    517: 
                    518:   DBG("protos_commit:\n");
                    519:   if (old)
                    520:     {
                    521:       WALK_LIST(oc, old->protos)
                    522:        {
                    523:          p = oc->proto;
                    524:          sym = cf_find_symbol(new, oc->name);
                    525:          if (sym && sym->class == SYM_PROTO && !new->shutdown)
                    526:            {
                    527:              /* Found match, let's check if we can smoothly switch to new configuration */
                    528:              /* No need to check description */
                    529:              nc = sym->def;
                    530:              nc->proto = p;
                    531: 
                    532:              /* We will try to reconfigure protocol p */
                    533:              if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
                    534:                continue;
                    535: 
                    536:              /* Unsuccessful, we will restart it */
                    537:              if (!p->disabled && !nc->disabled)
                    538:                log(L_INFO "Restarting protocol %s", p->name);
                    539:              else if (p->disabled && !nc->disabled)
                    540:                log(L_INFO "Enabling protocol %s", p->name);
                    541:              else if (!p->disabled && nc->disabled)
                    542:                log(L_INFO "Disabling protocol %s", p->name);
                    543: 
                    544:              p->down_code = nc->disabled ? PDC_CF_DISABLE : PDC_CF_RESTART;
                    545:              p->cf_new = nc;
                    546:            }
                    547:          else if (!new->shutdown)
                    548:            {
                    549:              log(L_INFO "Removing protocol %s", p->name);
                    550:              p->down_code = PDC_CF_REMOVE;
                    551:              p->cf_new = NULL;
                    552:            }
                    553:          else /* global shutdown */
                    554:            {
                    555:              p->down_code = PDC_CMD_SHUTDOWN;
                    556:              p->cf_new = NULL;
                    557:            }
                    558: 
                    559:          p->reconfiguring = 1;
                    560:          config_add_obstacle(old);
                    561:          proto_rethink_goal(p);
                    562:        }
                    563:     }
                    564: 
                    565:   WALK_LIST(nc, new->protos)
                    566:     if (!nc->proto)
                    567:       {
                    568:        if (old)                /* Not a first-time configuration */
                    569:          log(L_INFO "Adding protocol %s", nc->name);
                    570:        proto_init(nc);
                    571:       }
                    572:   DBG("\tdone\n");
                    573: 
                    574:   DBG("Protocol start\n");
                    575: 
                    576:   /* Start device protocol first */
                    577:   if (initial_device_proto)
                    578:   {
                    579:     proto_rethink_goal(initial_device_proto);
                    580:     initial_device_proto = NULL;
                    581:   }
                    582: 
                    583:   /* Determine router ID for the first time - it has to be here and not in
                    584:      global_commit() because it is postponed after start of device protocol */
                    585:   if (!config->router_id)
                    586:     {
                    587:       config->router_id = if_choose_router_id(config->router_id_from, 0);
                    588:       if (!config->router_id)
                    589:        die("Cannot determine router ID, please configure it manually");
                    590:     }
                    591: 
                    592:   /* Start all other protocols */
                    593:   WALK_LIST_DELSAFE(p, n, initial_proto_list)
                    594:     proto_rethink_goal(p);
                    595: }
                    596: 
                    597: static void
                    598: proto_rethink_goal(struct proto *p)
                    599: {
                    600:   struct protocol *q;
                    601:   byte goal;
                    602: 
                    603:   if (p->reconfiguring && p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN)
                    604:     {
                    605:       struct proto_config *nc = p->cf_new;
                    606:       DBG("%s has shut down for reconfiguration\n", p->name);
                    607:       p->cf->proto = NULL;
                    608:       config_del_obstacle(p->cf->global);
                    609:       rem_node(&p->n);
                    610:       rem_node(&p->glob_node);
                    611:       mb_free(p);
                    612:       if (!nc)
                    613:        return;
                    614:       p = proto_init(nc);
                    615:     }
                    616: 
                    617:   /* Determine what state we want to reach */
                    618:   if (p->disabled || p->reconfiguring)
                    619:     goal = PS_DOWN;
                    620:   else
                    621:     goal = PS_UP;
                    622: 
                    623:   q = p->proto;
                    624:   if (goal == PS_UP)                   /* Going up */
                    625:     {
                    626:       if (p->proto_state == PS_DOWN && p->core_state == FS_HUNGRY)
                    627:        {
                    628:          DBG("Kicking %s up\n", p->name);
                    629:          PD(p, "Starting");
                    630:          proto_init_instance(p);
                    631:          proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
                    632:        }
                    633:     }
                    634:   else                                         /* Going down */
                    635:     {
                    636:       if (p->proto_state == PS_START || p->proto_state == PS_UP)
                    637:        {
                    638:          DBG("Kicking %s down\n", p->name);
                    639:          PD(p, "Shutting down");
                    640:          proto_notify_state(p, (q->shutdown ? q->shutdown(p) : PS_DOWN));
                    641:        }
                    642:     }
                    643: }
                    644: 
                    645: 
                    646: /**
                    647:  * DOC: Graceful restart recovery
                    648:  *
                    649:  * Graceful restart of a router is a process when the routing plane (e.g. BIRD)
                    650:  * restarts but both the forwarding plane (e.g kernel routing table) and routing
                    651:  * neighbors keep proper routes, and therefore uninterrupted packet forwarding
                    652:  * is maintained.
                    653:  *
                    654:  * BIRD implements graceful restart recovery by deferring export of routes to
                    655:  * protocols until routing tables are refilled with the expected content. After
                    656:  * start, protocols generate routes as usual, but routes are not propagated to
                    657:  * them, until protocols report that they generated all routes. After that,
                    658:  * graceful restart recovery is finished and the export (and the initial feed)
                    659:  * to protocols is enabled.
                    660:  *
                    661:  * When graceful restart recovery need is detected during initialization, then
                    662:  * enabled protocols are marked with @gr_recovery flag before start. Such
                    663:  * protocols then decide how to proceed with graceful restart, participation is
                    664:  * voluntary. Protocols could lock the recovery by proto_graceful_restart_lock()
                    665:  * (stored in @gr_lock flag), which means that they want to postpone the end of
                    666:  * the recovery until they converge and then unlock it. They also could set
                    667:  * @gr_wait before advancing to %PS_UP, which means that the core should defer
                    668:  * route export to that protocol until the end of the recovery. This should be
                    669:  * done by protocols that expect their neigbors to keep the proper routes
                    670:  * (kernel table, BGP sessions with BGP graceful restart capability).
                    671:  *
                    672:  * The graceful restart recovery is finished when either all graceful restart
                    673:  * locks are unlocked or when graceful restart wait timer fires.
                    674:  *
                    675:  */
                    676: 
                    677: static void graceful_restart_done(struct timer *t);
                    678: 
                    679: /**
                    680:  * graceful_restart_recovery - request initial graceful restart recovery
                    681:  *
                    682:  * Called by the platform initialization code if the need for recovery
                    683:  * after graceful restart is detected during boot. Have to be called
                    684:  * before protos_commit().
                    685:  */
                    686: void
                    687: graceful_restart_recovery(void)
                    688: {
                    689:   graceful_restart_state = GRS_INIT;
                    690: }
                    691: 
                    692: /**
                    693:  * graceful_restart_init - initialize graceful restart
                    694:  *
                    695:  * When graceful restart recovery was requested, the function starts an active
                    696:  * phase of the recovery and initializes graceful restart wait timer. The
                    697:  * function have to be called after protos_commit().
                    698:  */
                    699: void
                    700: graceful_restart_init(void)
                    701: {
                    702:   if (!graceful_restart_state)
                    703:     return;
                    704: 
                    705:   log(L_INFO "Graceful restart started");
                    706: 
                    707:   if (!graceful_restart_locks)
                    708:     {
                    709:       graceful_restart_done(NULL);
                    710:       return;
                    711:     }
                    712: 
                    713:   graceful_restart_state = GRS_ACTIVE;
                    714:   gr_wait_timer = tm_new(proto_pool);
                    715:   gr_wait_timer->hook = graceful_restart_done;
                    716:   tm_start(gr_wait_timer, config->gr_wait);
                    717: }
                    718: 
                    719: /**
                    720:  * graceful_restart_done - finalize graceful restart
                    721:  * @t: unused
                    722:  *
                    723:  * When there are no locks on graceful restart, the functions finalizes the
                    724:  * graceful restart recovery. Protocols postponing route export until the end of
                    725:  * the recovery are awakened and the export to them is enabled. All other
                    726:  * related state is cleared. The function is also called when the graceful
                    727:  * restart wait timer fires (but there are still some locks).
                    728:  */
                    729: static void
                    730: graceful_restart_done(struct timer *t UNUSED)
                    731: {
                    732:   struct proto *p;
                    733:   node *n;
                    734: 
                    735:   log(L_INFO "Graceful restart done");
                    736:   graceful_restart_state = GRS_DONE;
                    737: 
                    738:   WALK_LIST2(p, n, proto_list, glob_node)
                    739:     {
                    740:       if (!p->gr_recovery)
                    741:        continue;
                    742: 
                    743:       /* Resume postponed export of routes */
                    744:       if ((p->proto_state == PS_UP) && p->gr_wait)
                    745:       {
                    746:        proto_want_export_up(p);
                    747:        proto_log_state_change(p);
                    748:       }
                    749: 
                    750:       /* Cleanup */
                    751:       p->gr_recovery = 0;
                    752:       p->gr_wait = 0;
                    753:       p->gr_lock = 0;
                    754:     }
                    755: 
                    756:   graceful_restart_locks = 0;
                    757: }
                    758: 
                    759: void
                    760: graceful_restart_show_status(void)
                    761: {
                    762:   if (graceful_restart_state != GRS_ACTIVE)
                    763:     return;
                    764: 
                    765:   cli_msg(-24, "Graceful restart recovery in progress");
                    766:   cli_msg(-24, "  Waiting for %d protocols to recover", graceful_restart_locks);
                    767:   cli_msg(-24, "  Wait timer is %d/%d", tm_remains(gr_wait_timer), config->gr_wait);
                    768: }
                    769: 
                    770: /**
                    771:  * proto_graceful_restart_lock - lock graceful restart by protocol
                    772:  * @p: protocol instance
                    773:  *
                    774:  * This function allows a protocol to postpone the end of graceful restart
                    775:  * recovery until it converges. The lock is removed when the protocol calls
                    776:  * proto_graceful_restart_unlock() or when the protocol is stopped.
                    777:  *
                    778:  * The function have to be called during the initial phase of graceful restart
                    779:  * recovery and only for protocols that are part of graceful restart (i.e. their
                    780:  * @gr_recovery is set), which means it should be called from protocol start
                    781:  * hooks.
                    782:  */
                    783: void
                    784: proto_graceful_restart_lock(struct proto *p)
                    785: {
                    786:   ASSERT(graceful_restart_state == GRS_INIT);
                    787:   ASSERT(p->gr_recovery);
                    788: 
                    789:   if (p->gr_lock)
                    790:     return;
                    791: 
                    792:   p->gr_lock = 1;
                    793:   graceful_restart_locks++;
                    794: }
                    795: 
                    796: /**
                    797:  * proto_graceful_restart_unlock - unlock graceful restart by protocol
                    798:  * @p: protocol instance
                    799:  *
                    800:  * This function unlocks a lock from proto_graceful_restart_lock(). It is also
                    801:  * automatically called when the lock holding protocol went down.
                    802:  */
                    803: void
                    804: proto_graceful_restart_unlock(struct proto *p)
                    805: {
                    806:   if (!p->gr_lock)
                    807:     return;
                    808: 
                    809:   p->gr_lock = 0;
                    810:   graceful_restart_locks--;
                    811: 
                    812:   if ((graceful_restart_state == GRS_ACTIVE) && !graceful_restart_locks)
                    813:     tm_start(gr_wait_timer, 0);
                    814: }
                    815: 
                    816: 
                    817: 
                    818: /**
                    819:  * protos_dump_all - dump status of all protocols
                    820:  *
                    821:  * This function dumps status of all existing protocol instances to the
                    822:  * debug output. It involves printing of general status information
                    823:  * such as protocol states, its position on the protocol lists
                    824:  * and also calling of a dump() hook of the protocol to print
                    825:  * the internals.
                    826:  */
                    827: void
                    828: protos_dump_all(void)
                    829: {
                    830:   struct proto *p;
                    831:   struct announce_hook *a;
                    832: 
                    833:   debug("Protocols:\n");
                    834: 
                    835:   WALK_LIST(p, active_proto_list)
                    836:     {
                    837:       debug("  protocol %s state %s/%s\n", p->name,
                    838:            p_states[p->proto_state], c_states[p->core_state]);
                    839:       for (a = p->ahooks; a; a = a->next)
                    840:        {
                    841:          debug("\tTABLE %s\n", a->table->name);
                    842:          if (a->in_filter)
                    843:            debug("\tInput filter: %s\n", filter_name(a->in_filter));
                    844:          if (a->out_filter != FILTER_REJECT)
                    845:            debug("\tOutput filter: %s\n", filter_name(a->out_filter));
                    846:        }
                    847:       if (p->disabled)
                    848:        debug("\tDISABLED\n");
                    849:       else if (p->proto->dump)
                    850:        p->proto->dump(p);
                    851:     }
                    852:   WALK_LIST(p, inactive_proto_list)
                    853:     debug("  inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]);
                    854:   WALK_LIST(p, initial_proto_list)
                    855:     debug("  initial %s\n", p->name);
                    856:   WALK_LIST(p, flush_proto_list)
                    857:     debug("  flushing %s\n", p->name);
                    858: }
                    859: 
                    860: /**
                    861:  * proto_build - make a single protocol available
                    862:  * @p: the protocol
                    863:  *
                    864:  * After the platform specific initialization code uses protos_build()
                    865:  * to add all the standard protocols, it should call proto_build() for
                    866:  * all platform specific protocols to inform the core that they exist.
                    867:  */
                    868: void
                    869: proto_build(struct protocol *p)
                    870: {
                    871:   add_tail(&protocol_list, &p->n);
                    872:   if (p->attr_class)
                    873:     {
                    874:       ASSERT(!attr_class_to_protocol[p->attr_class]);
                    875:       attr_class_to_protocol[p->attr_class] = p;
                    876:     }
                    877: }
                    878: 
                    879: /* FIXME: convert this call to some protocol hook */
                    880: extern void bfd_init_all(void);
                    881: 
                    882: /**
                    883:  * protos_build - build a protocol list
                    884:  *
                    885:  * This function is called during BIRD startup to insert
                    886:  * all standard protocols to the global protocol list. Insertion
                    887:  * of platform specific protocols (such as the kernel syncer)
                    888:  * is in the domain of competence of the platform dependent
                    889:  * startup code.
                    890:  */
                    891: void
                    892: protos_build(void)
                    893: {
                    894:   init_list(&protocol_list);
                    895:   init_list(&proto_list);
                    896:   init_list(&active_proto_list);
                    897:   init_list(&inactive_proto_list);
                    898:   init_list(&initial_proto_list);
                    899:   init_list(&flush_proto_list);
                    900:   proto_build(&proto_device);
                    901: #ifdef CONFIG_RADV
                    902:   proto_build(&proto_radv);
                    903: #endif
                    904: #ifdef CONFIG_RIP
                    905:   proto_build(&proto_rip);
                    906: #endif
                    907: #ifdef CONFIG_STATIC
                    908:   proto_build(&proto_static);
                    909: #endif
                    910: #ifdef CONFIG_OSPF
                    911:   proto_build(&proto_ospf);
                    912: #endif
                    913: #ifdef CONFIG_PIPE
                    914:   proto_build(&proto_pipe);
                    915: #endif
                    916: #ifdef CONFIG_BGP
                    917:   proto_build(&proto_bgp);
                    918: #endif
                    919: #ifdef CONFIG_BFD
                    920:   proto_build(&proto_bfd);
                    921:   bfd_init_all();
                    922: #endif
                    923: #ifdef CONFIG_BABEL
                    924:   proto_build(&proto_babel);
                    925: #endif
                    926: 
                    927:   proto_pool = rp_new(&root_pool, "Protocols");
                    928:   proto_flush_event = ev_new(proto_pool);
                    929:   proto_flush_event->hook = proto_flush_loop;
                    930:   proto_shutdown_timer = tm_new(proto_pool);
                    931:   proto_shutdown_timer->hook = proto_shutdown_loop;
                    932: }
                    933: 
                    934: static void
                    935: proto_feed_more(void *P)
                    936: {
                    937:   struct proto *p = P;
                    938: 
                    939:   if (p->export_state != ES_FEEDING)
                    940:     return;
                    941: 
                    942:   DBG("Feeding protocol %s continued\n", p->name);
                    943:   if (rt_feed_baby(p))
                    944:     {
                    945:       DBG("Feeding protocol %s finished\n", p->name);
                    946:       p->export_state = ES_READY;
                    947:       proto_log_state_change(p);
                    948: 
                    949:       if (p->feed_end)
                    950:        p->feed_end(p);
                    951:     }
                    952:   else
                    953:     {
                    954:       p->attn->hook = proto_feed_more;
                    955:       ev_schedule(p->attn);            /* Will continue later... */
                    956:     }
                    957: }
                    958: 
                    959: static void
                    960: proto_feed_initial(void *P)
                    961: {
                    962:   struct proto *p = P;
                    963: 
                    964:   if (p->export_state != ES_FEEDING)
                    965:     return;
                    966: 
                    967:   DBG("Feeding protocol %s\n", p->name);
                    968: 
                    969:   if_feed_baby(p);
                    970:   proto_feed_more(P);
                    971: }
                    972: 
                    973: static void
                    974: proto_schedule_feed(struct proto *p, int initial)
                    975: {
                    976:   DBG("%s: Scheduling meal\n", p->name);
                    977: 
                    978:   p->export_state = ES_FEEDING;
                    979:   p->refeeding = !initial;
                    980: 
                    981:   p->attn->hook = initial ? proto_feed_initial : proto_feed_more;
                    982:   ev_schedule(p->attn);
                    983: 
                    984:   if (p->feed_begin)
                    985:     p->feed_begin(p, initial);
                    986: }
                    987: 
                    988: /*
                    989:  * Flushing loop is responsible for flushing routes and protocols
                    990:  * after they went down. It runs in proto_flush_event. At the start of
                    991:  * one round, protocols waiting to flush are marked in
                    992:  * proto_schedule_flush_loop(). At the end of the round (when routing
                    993:  * table flush is complete), marked protocols are flushed and a next
                    994:  * round may start.
                    995:  */
                    996: 
                    997: static int flush_loop_state;   /* 1 -> running */
                    998: 
                    999: static void
                   1000: proto_schedule_flush_loop(void)
                   1001: {
                   1002:   struct proto *p;
                   1003:   struct announce_hook *h;
                   1004: 
                   1005:   if (flush_loop_state)
                   1006:     return;
                   1007:   flush_loop_state = 1;
                   1008: 
                   1009:   WALK_LIST(p, flush_proto_list)
                   1010:   {
                   1011:     p->flushing = 1;
                   1012:     for (h=p->ahooks; h; h=h->next)
                   1013:       rt_mark_for_prune(h->table);
                   1014:   }
                   1015: 
                   1016:   ev_schedule(proto_flush_event);
                   1017: }
                   1018: 
                   1019: static void
                   1020: proto_flush_loop(void *unused UNUSED)
                   1021: {
                   1022:   struct proto *p;
                   1023: 
                   1024:   if (! rt_prune_loop())
                   1025:     {
                   1026:       /* Rtable pruning is not finished */
                   1027:       ev_schedule(proto_flush_event);
                   1028:       return;
                   1029:     }
                   1030: 
                   1031:   rt_prune_sources();
                   1032: 
                   1033:  again:
                   1034:   WALK_LIST(p, flush_proto_list)
                   1035:     if (p->flushing)
                   1036:       {
                   1037:        /* This will flush interfaces in the same manner
                   1038:           like rt_prune_all() flushes routes */
                   1039:        if (p->proto == &proto_unix_iface)
                   1040:          if_flush_ifaces(p);
                   1041: 
                   1042:        DBG("Flushing protocol %s\n", p->name);
                   1043:        p->flushing = 0;
                   1044:        p->core_state = FS_HUNGRY;
                   1045:        proto_relink(p);
                   1046:        proto_log_state_change(p);
                   1047:        if (p->proto_state == PS_DOWN)
                   1048:          proto_fell_down(p);
                   1049:        goto again;
                   1050:       }
                   1051: 
                   1052:   /* This round finished, perhaps there will be another one */
                   1053:   flush_loop_state = 0;
                   1054:   if (!EMPTY_LIST(flush_proto_list))
                   1055:     proto_schedule_flush_loop();
                   1056: }
                   1057: 
                   1058: 
                   1059: /* Temporary hack to propagate restart to BGP */
                   1060: int proto_restart;
                   1061: 
                   1062: static void
                   1063: proto_shutdown_loop(struct timer *t UNUSED)
                   1064: {
                   1065:   struct proto *p, *p_next;
                   1066: 
                   1067:   WALK_LIST_DELSAFE(p, p_next, active_proto_list)
                   1068:     if (p->down_sched)
                   1069:       {
                   1070:        proto_restart = (p->down_sched == PDS_RESTART);
                   1071: 
                   1072:        p->disabled = 1;
                   1073:        proto_rethink_goal(p);
                   1074:        if (proto_restart)
                   1075:          {
                   1076:            p->disabled = 0;
                   1077:            proto_rethink_goal(p);
                   1078:          }
                   1079:       }
                   1080: }
                   1081: 
                   1082: static inline void
                   1083: proto_schedule_down(struct proto *p, byte restart, byte code)
                   1084: {
                   1085:   /* Does not work for other states (even PS_START) */
                   1086:   ASSERT(p->proto_state == PS_UP);
                   1087: 
                   1088:   /* Scheduled restart may change to shutdown, but not otherwise */
                   1089:   if (p->down_sched == PDS_DISABLE)
                   1090:     return;
                   1091: 
                   1092:   p->down_sched = restart ? PDS_RESTART : PDS_DISABLE;
                   1093:   p->down_code = code;
                   1094:   tm_start_max(proto_shutdown_timer, restart ? 2 : 0);
                   1095: }
                   1096: 
                   1097: 
                   1098: /**
                   1099:  * proto_request_feeding - request feeding routes to the protocol
                   1100:  * @p: given protocol 
                   1101:  *
                   1102:  * Sometimes it is needed to send again all routes to the
                   1103:  * protocol. This is called feeding and can be requested by this
                   1104:  * function. This would cause protocol export state transition
                   1105:  * to ES_FEEDING (during feeding) and when completed, it will
                   1106:  * switch back to ES_READY. This function can be called even
                   1107:  * when feeding is already running, in that case it is restarted.
                   1108:  */
                   1109: void
                   1110: proto_request_feeding(struct proto *p)
                   1111: {
                   1112:   ASSERT(p->proto_state == PS_UP);
                   1113: 
                   1114:   /* Do nothing if we are still waiting for feeding */
                   1115:   if (p->export_state == ES_DOWN)
                   1116:     return;
                   1117: 
                   1118:   /* If we are already feeding, we want to restart it */
                   1119:   if (p->export_state == ES_FEEDING)
                   1120:     {
                   1121:       /* Unless feeding is in initial state */
                   1122:       if (p->attn->hook == proto_feed_initial)
                   1123:        return;
                   1124: 
                   1125:       rt_feed_baby_abort(p);
                   1126:     }
                   1127: 
                   1128:   /* FIXME: This should be changed for better support of multitable protos */
                   1129:   struct announce_hook *ah;
                   1130:   for (ah = p->ahooks; ah; ah = ah->next)
                   1131:     proto_reset_limit(ah->out_limit);
                   1132: 
                   1133:   /* Hack: reset exp_routes during refeed, and do not decrease it later */
                   1134:   p->stats.exp_routes = 0;
                   1135: 
                   1136:   proto_schedule_feed(p, 0);
                   1137:   proto_log_state_change(p);
                   1138: }
                   1139: 
                   1140: static const char *
                   1141: proto_limit_name(struct proto_limit *l)
                   1142: {
                   1143:   const char *actions[] = {
                   1144:     [PLA_WARN] = "warn",
                   1145:     [PLA_BLOCK] = "block",
                   1146:     [PLA_RESTART] = "restart",
                   1147:     [PLA_DISABLE] = "disable",
                   1148:   };
                   1149: 
                   1150:   return actions[l->action];
                   1151: }
                   1152: 
                   1153: /**
                   1154:  * proto_notify_limit: notify about limit hit and take appropriate action
                   1155:  * @ah: announce hook
                   1156:  * @l: limit being hit
                   1157:  * @dir: limit direction (PLD_*)
                   1158:  * @rt_count: the number of routes 
                   1159:  *
                   1160:  * The function is called by the route processing core when limit @l
                   1161:  * is breached. It activates the limit and tooks appropriate action
                   1162:  * according to @l->action.
                   1163:  */
                   1164: void
                   1165: proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count)
                   1166: {
                   1167:   const char *dir_name[PLD_MAX] = { "receive", "import" , "export" };
                   1168:   const byte dir_down[PLD_MAX] = { PDC_RX_LIMIT_HIT, PDC_IN_LIMIT_HIT, PDC_OUT_LIMIT_HIT };
                   1169:   struct proto *p = ah->proto;
                   1170: 
                   1171:   if (l->state == PLS_BLOCKED)
                   1172:     return;
                   1173: 
                   1174:   /* For warning action, we want the log message every time we hit the limit */
                   1175:   if (!l->state || ((l->action == PLA_WARN) && (rt_count == l->limit)))
                   1176:     log(L_WARN "Protocol %s hits route %s limit (%d), action: %s",
                   1177:        p->name, dir_name[dir], l->limit, proto_limit_name(l));
                   1178: 
                   1179:   switch (l->action)
                   1180:     {
                   1181:     case PLA_WARN:
                   1182:       l->state = PLS_ACTIVE;
                   1183:       break;
                   1184: 
                   1185:     case PLA_BLOCK:
                   1186:       l->state = PLS_BLOCKED;
                   1187:       break;
                   1188: 
                   1189:     case PLA_RESTART:
                   1190:     case PLA_DISABLE:
                   1191:       l->state = PLS_BLOCKED;
                   1192:       if (p->proto_state == PS_UP)
                   1193:        proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
                   1194:       break;
                   1195:     }
                   1196: }
                   1197: 
                   1198: void
                   1199: proto_verify_limits(struct announce_hook *ah)
                   1200: {
                   1201:   struct proto_limit *l;
                   1202:   struct proto_stats *stats = ah->stats;
                   1203:   u32 all_routes = stats->imp_routes + stats->filt_routes;
                   1204: 
                   1205:   l = ah->rx_limit;
                   1206:   if (l && (all_routes > l->limit))
                   1207:     proto_notify_limit(ah, l, PLD_RX, all_routes);
                   1208: 
                   1209:   l = ah->in_limit;
                   1210:   if (l && (stats->imp_routes > l->limit))
                   1211:     proto_notify_limit(ah, l, PLD_IN, stats->imp_routes);
                   1212: 
                   1213:   l = ah->out_limit;
                   1214:   if (l && (stats->exp_routes > l->limit))
                   1215:     proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes);
                   1216: }
                   1217: 
                   1218: 
                   1219: static void
                   1220: proto_want_core_up(struct proto *p)
                   1221: {
                   1222:   ASSERT(p->core_state == FS_HUNGRY);
                   1223: 
                   1224:   if (!p->proto->multitable)
                   1225:     {
                   1226:       p->main_source = rt_get_source(p, 0);
                   1227:       rt_lock_source(p->main_source);
                   1228: 
                   1229:       /* Connect protocol to routing table */
                   1230:       p->main_ahook = proto_add_announce_hook(p, p->table, &p->stats);
                   1231:       p->main_ahook->in_filter = p->cf->in_filter;
                   1232:       p->main_ahook->out_filter = p->cf->out_filter;
                   1233:       p->main_ahook->rx_limit = p->cf->rx_limit;
                   1234:       p->main_ahook->in_limit = p->cf->in_limit;
                   1235:       p->main_ahook->out_limit = p->cf->out_limit;
                   1236:       p->main_ahook->in_keep_filtered = p->cf->in_keep_filtered;
                   1237: 
                   1238:       proto_reset_limit(p->main_ahook->rx_limit);
                   1239:       proto_reset_limit(p->main_ahook->in_limit);
                   1240:       proto_reset_limit(p->main_ahook->out_limit);
                   1241:     }
                   1242: 
                   1243:   p->core_state = FS_HAPPY;
                   1244:   proto_relink(p);
                   1245: }
                   1246: 
                   1247: static void
                   1248: proto_want_export_up(struct proto *p)
                   1249: {
                   1250:   ASSERT(p->core_state == FS_HAPPY);
                   1251:   ASSERT(p->export_state == ES_DOWN);
                   1252: 
                   1253:   proto_link_ahooks(p);
                   1254:   proto_schedule_feed(p, 1); /* Sets ES_FEEDING */
                   1255: }
                   1256: 
                   1257: static void
                   1258: proto_want_export_down(struct proto *p)
                   1259: {
                   1260:   ASSERT(p->export_state != ES_DOWN);
                   1261: 
                   1262:   /* Need to abort feeding */
                   1263:   if (p->export_state == ES_FEEDING)
                   1264:     rt_feed_baby_abort(p);
                   1265: 
                   1266:   p->export_state = ES_DOWN;
                   1267:   p->stats.exp_routes = 0;
                   1268:   proto_unlink_ahooks(p);
                   1269: }
                   1270: 
                   1271: static void
                   1272: proto_want_core_down(struct proto *p)
                   1273: {
                   1274:   ASSERT(p->core_state == FS_HAPPY);
                   1275:   ASSERT(p->export_state == ES_DOWN);
                   1276: 
                   1277:   p->core_state = FS_FLUSHING;
                   1278:   proto_relink(p);
                   1279:   proto_schedule_flush_loop();
                   1280: 
                   1281:   if (!p->proto->multitable)
                   1282:     {
                   1283:       rt_unlock_source(p->main_source);
                   1284:       p->main_source = NULL;
                   1285:     }
                   1286: }
                   1287: 
                   1288: static void
                   1289: proto_falling_down(struct proto *p)
                   1290: {
                   1291:   p->gr_recovery = 0;
                   1292:   p->gr_wait = 0;
                   1293:   if (p->gr_lock)
                   1294:     proto_graceful_restart_unlock(p);
                   1295: }
                   1296: 
                   1297: static void
                   1298: proto_fell_down(struct proto *p)
                   1299: {
                   1300:   DBG("Protocol %s down\n", p->name);
                   1301: 
                   1302:   u32 all_routes = p->stats.imp_routes + p->stats.filt_routes;
                   1303:   if (all_routes != 0)
                   1304:     log(L_ERR "Protocol %s is down but still has %d routes", p->name, all_routes);
                   1305: 
                   1306:   bzero(&p->stats, sizeof(struct proto_stats));
                   1307:   proto_free_ahooks(p);
                   1308: 
                   1309:   if (! p->proto->multitable)
                   1310:     rt_unlock_table(p->table);
                   1311: 
                   1312:   if (p->proto->cleanup)
                   1313:     p->proto->cleanup(p);
                   1314: 
                   1315:   proto_rethink_goal(p);
                   1316: }
                   1317: 
                   1318: 
                   1319: /**
                   1320:  * proto_notify_state - notify core about protocol state change
                   1321:  * @p: protocol the state of which has changed
                   1322:  * @ps: the new status
                   1323:  *
                   1324:  * Whenever a state of a protocol changes due to some event internal
                   1325:  * to the protocol (i.e., not inside a start() or shutdown() hook),
                   1326:  * it should immediately notify the core about the change by calling
                   1327:  * proto_notify_state() which will write the new state to the &proto
                   1328:  * structure and take all the actions necessary to adapt to the new
                   1329:  * state. State change to PS_DOWN immediately frees resources of protocol
                   1330:  * and might execute start callback of protocol; therefore,
                   1331:  * it should be used at tail positions of protocol callbacks.
                   1332:  */
                   1333: void
                   1334: proto_notify_state(struct proto *p, unsigned ps)
                   1335: {
                   1336:   unsigned ops = p->proto_state;
                   1337:   unsigned cs = p->core_state;
                   1338:   unsigned es = p->export_state;
                   1339: 
                   1340:   DBG("%s reporting state transition %s/%s -> */%s\n", p->name, c_states[cs], p_states[ops], p_states[ps]);
                   1341:   if (ops == ps)
                   1342:     return;
                   1343: 
                   1344:   p->proto_state = ps;
                   1345:   p->last_state_change = now;
                   1346: 
                   1347:   switch (ps)
                   1348:     {
                   1349:     case PS_START:
                   1350:       ASSERT(ops == PS_DOWN || ops == PS_UP);
                   1351:       ASSERT(cs == FS_HUNGRY || cs == FS_HAPPY);
                   1352: 
                   1353:       if (es != ES_DOWN)
                   1354:        proto_want_export_down(p);
                   1355:       break;
                   1356: 
                   1357:     case PS_UP:
                   1358:       ASSERT(ops == PS_DOWN || ops == PS_START);
                   1359:       ASSERT(cs == FS_HUNGRY || cs == FS_HAPPY);
                   1360:       ASSERT(es == ES_DOWN);
                   1361: 
                   1362:       if (cs == FS_HUNGRY)
                   1363:        proto_want_core_up(p);
                   1364:       if (!p->gr_wait)
                   1365:        proto_want_export_up(p);
                   1366:       break;
                   1367: 
                   1368:     case PS_STOP:
                   1369:       ASSERT(ops == PS_START || ops == PS_UP);
                   1370: 
                   1371:       p->down_sched = 0;
                   1372: 
                   1373:       if (es != ES_DOWN)
                   1374:        proto_want_export_down(p);
                   1375:       if (cs == FS_HAPPY)
                   1376:        proto_want_core_down(p);
                   1377:       proto_falling_down(p);
                   1378:       break;
                   1379: 
                   1380:     case PS_DOWN:
                   1381:       p->down_code = 0;
                   1382:       p->down_sched = 0;
                   1383: 
                   1384:       if (es != ES_DOWN)
                   1385:        proto_want_export_down(p);
                   1386:       if (cs == FS_HAPPY)
                   1387:        proto_want_core_down(p);
                   1388:       if (ops != PS_STOP)
                   1389:        proto_falling_down(p);
                   1390: 
                   1391:       neigh_prune(); // FIXME convert neighbors to resource?
                   1392:       rfree(p->pool);
                   1393:       p->pool = NULL;
                   1394: 
                   1395:       if (cs == FS_HUNGRY)             /* Shutdown finished */
                   1396:        {
                   1397:          proto_log_state_change(p);
                   1398:          proto_fell_down(p);
                   1399:          return;                       /* The protocol might have ceased to exist */
                   1400:        }
                   1401:       break;
                   1402: 
                   1403:     default:
                   1404:       bug("%s: Invalid state %d", p->name, ps);
                   1405:     }
                   1406: 
                   1407:   proto_log_state_change(p);
                   1408: }
                   1409: 
                   1410: /*
                   1411:  *  CLI Commands
                   1412:  */
                   1413: 
                   1414: static char *
                   1415: proto_state_name(struct proto *p)
                   1416: {
                   1417: #define P(x,y) ((x << 4) | y)
                   1418:   switch (P(p->proto_state, p->core_state))
                   1419:     {
                   1420:     case P(PS_DOWN, FS_HUNGRY):                return "down";
                   1421:     case P(PS_START, FS_HUNGRY):
                   1422:     case P(PS_START, FS_HAPPY):                return "start";
                   1423:     case P(PS_UP, FS_HAPPY):
                   1424:       switch (p->export_state)
                   1425:        {
                   1426:        case ES_DOWN:                   return "wait";
                   1427:        case ES_FEEDING:                return "feed";
                   1428:        case ES_READY:                  return "up";
                   1429:        default:                        return "???";
                   1430:        }
                   1431:     case P(PS_STOP, FS_HUNGRY):
                   1432:     case P(PS_STOP, FS_FLUSHING):      return "stop";
                   1433:     case P(PS_DOWN, FS_FLUSHING):      return "flush";
                   1434:     default:                           return "???";
                   1435:     }
                   1436: #undef P
                   1437: }
                   1438: 
                   1439: static void
                   1440: proto_show_stats(struct proto_stats *s, int in_keep_filtered)
                   1441: {
                   1442:   if (in_keep_filtered)
                   1443:     cli_msg(-1006, "  Routes:         %u imported, %u filtered, %u exported, %u preferred", 
                   1444:            s->imp_routes, s->filt_routes, s->exp_routes, s->pref_routes);
                   1445:   else
                   1446:     cli_msg(-1006, "  Routes:         %u imported, %u exported, %u preferred", 
                   1447:            s->imp_routes, s->exp_routes, s->pref_routes);
                   1448: 
                   1449:   cli_msg(-1006, "  Route change stats:     received   rejected   filtered    ignored   accepted");
                   1450:   cli_msg(-1006, "    Import updates:     %10u %10u %10u %10u %10u",
                   1451:          s->imp_updates_received, s->imp_updates_invalid,
                   1452:          s->imp_updates_filtered, s->imp_updates_ignored,
                   1453:          s->imp_updates_accepted);
                   1454:   cli_msg(-1006, "    Import withdraws:   %10u %10u        --- %10u %10u",
                   1455:          s->imp_withdraws_received, s->imp_withdraws_invalid,
                   1456:          s->imp_withdraws_ignored, s->imp_withdraws_accepted);
                   1457:   cli_msg(-1006, "    Export updates:     %10u %10u %10u        --- %10u",
                   1458:          s->exp_updates_received, s->exp_updates_rejected,
                   1459:          s->exp_updates_filtered, s->exp_updates_accepted);
                   1460:   cli_msg(-1006, "    Export withdraws:   %10u        ---        ---        --- %10u",
                   1461:          s->exp_withdraws_received, s->exp_withdraws_accepted);
                   1462: }
                   1463: 
                   1464: void
                   1465: proto_show_limit(struct proto_limit *l, const char *dsc)
                   1466: {
                   1467:   if (!l)
                   1468:     return;
                   1469: 
                   1470:   cli_msg(-1006, "  %-16s%d%s", dsc, l->limit, l->state ? " [HIT]" : "");
                   1471:   cli_msg(-1006, "    Action:       %s", proto_limit_name(l));
                   1472: }
                   1473: 
                   1474: void
                   1475: proto_show_basic_info(struct proto *p)
                   1476: {
                   1477:   // cli_msg(-1006, "  Table:          %s", p->table->name);
                   1478:   cli_msg(-1006, "  Preference:     %d", p->preference);
                   1479:   cli_msg(-1006, "  Input filter:   %s", filter_name(p->cf->in_filter));
                   1480:   cli_msg(-1006, "  Output filter:  %s", filter_name(p->cf->out_filter));
                   1481: 
                   1482:   if (graceful_restart_state == GRS_ACTIVE)
                   1483:     cli_msg(-1006, "  GR recovery:   %s%s",
                   1484:            p->gr_lock ? " pending" : "",
                   1485:            p->gr_wait ? " waiting" : "");
                   1486: 
                   1487:   proto_show_limit(p->cf->rx_limit, "Receive limit:");
                   1488:   proto_show_limit(p->cf->in_limit, "Import limit:");
                   1489:   proto_show_limit(p->cf->out_limit, "Export limit:");
                   1490: 
                   1491:   if (p->proto_state != PS_DOWN)
                   1492:     proto_show_stats(&p->stats, p->cf->in_keep_filtered);
                   1493: }
                   1494: 
                   1495: void
                   1496: proto_cmd_show(struct proto *p, uint verbose, int cnt)
                   1497: {
                   1498:   byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
                   1499: 
                   1500:   /* First protocol - show header */
                   1501:   if (!cnt)
                   1502:     cli_msg(-2002, "name     proto    table    state  since       info");
                   1503: 
                   1504:   buf[0] = 0;
                   1505:   if (p->proto->get_status)
                   1506:     p->proto->get_status(p, buf);
                   1507:   tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change);
                   1508:   cli_msg(-1002, "%-8s %-8s %-8s %-5s  %-10s  %s",
                   1509:          p->name,
                   1510:          p->proto->name,
                   1511:          p->table->name,
                   1512:          proto_state_name(p),
                   1513:          tbuf,
                   1514:          buf);
                   1515:   if (verbose)
                   1516:     {
                   1517:       if (p->cf->dsc)
                   1518:        cli_msg(-1006, "  Description:    %s", p->cf->dsc);
                   1519:       if (p->cf->router_id)
                   1520:        cli_msg(-1006, "  Router ID:      %R", p->cf->router_id);
                   1521: 
                   1522:       if (p->proto->show_proto_info)
                   1523:        p->proto->show_proto_info(p);
                   1524:       else
                   1525:        proto_show_basic_info(p);
                   1526: 
                   1527:       cli_msg(-1006, "");
                   1528:     }
                   1529: }
                   1530: 
                   1531: void
                   1532: proto_cmd_disable(struct proto *p, uint arg UNUSED, int cnt UNUSED)
                   1533: {
                   1534:   if (p->disabled)
                   1535:     {
                   1536:       cli_msg(-8, "%s: already disabled", p->name);
                   1537:       return;
                   1538:     }
                   1539: 
                   1540:   log(L_INFO "Disabling protocol %s", p->name);
                   1541:   p->disabled = 1;
                   1542:   p->down_code = PDC_CMD_DISABLE;
                   1543:   proto_rethink_goal(p);
                   1544:   cli_msg(-9, "%s: disabled", p->name);
                   1545: }
                   1546: 
                   1547: void
                   1548: proto_cmd_enable(struct proto *p, uint arg UNUSED, int cnt UNUSED)
                   1549: {
                   1550:   if (!p->disabled)
                   1551:     {
                   1552:       cli_msg(-10, "%s: already enabled", p->name);
                   1553:       return;
                   1554:     }
                   1555: 
                   1556:   log(L_INFO "Enabling protocol %s", p->name);
                   1557:   p->disabled = 0;
                   1558:   proto_rethink_goal(p);
                   1559:   cli_msg(-11, "%s: enabled", p->name);
                   1560: }
                   1561: 
                   1562: void
                   1563: proto_cmd_restart(struct proto *p, uint arg UNUSED, int cnt UNUSED)
                   1564: {
                   1565:   if (p->disabled)
                   1566:     {
                   1567:       cli_msg(-8, "%s: already disabled", p->name);
                   1568:       return;
                   1569:     }
                   1570: 
                   1571:   log(L_INFO "Restarting protocol %s", p->name);
                   1572:   p->disabled = 1;
                   1573:   p->down_code = PDC_CMD_RESTART;
                   1574:   proto_rethink_goal(p);
                   1575:   p->disabled = 0;
                   1576:   proto_rethink_goal(p);
                   1577:   cli_msg(-12, "%s: restarted", p->name);
                   1578: }
                   1579: 
                   1580: void
                   1581: proto_cmd_reload(struct proto *p, uint dir, int cnt UNUSED)
                   1582: {
                   1583:   if (p->disabled)
                   1584:     {
                   1585:       cli_msg(-8, "%s: already disabled", p->name);
                   1586:       return;
                   1587:     }
                   1588: 
                   1589:   /* If the protocol in not UP, it has no routes */
                   1590:   if (p->proto_state != PS_UP)
                   1591:     return;
                   1592: 
                   1593:   log(L_INFO "Reloading protocol %s", p->name);
                   1594: 
                   1595:   /* re-importing routes */
                   1596:   if (dir != CMD_RELOAD_OUT)
                   1597:     {
                   1598:       if (! (p->reload_routes && p->reload_routes(p)))
                   1599:        {
                   1600:          cli_msg(-8006, "%s: reload failed", p->name);
                   1601:          return;
                   1602:        }
                   1603: 
                   1604:       /*
                   1605:        * Should be done before reload_routes() hook?
                   1606:        * Perhaps, but these hooks work asynchronously.
                   1607:        */
                   1608:       if (!p->proto->multitable)
                   1609:        {
                   1610:          proto_reset_limit(p->main_ahook->rx_limit);
                   1611:          proto_reset_limit(p->main_ahook->in_limit);
                   1612:        }
                   1613:     }
                   1614: 
                   1615:   /* re-exporting routes */
                   1616:   if (dir != CMD_RELOAD_IN)
                   1617:     proto_request_feeding(p);
                   1618: 
                   1619:   cli_msg(-15, "%s: reloading", p->name);
                   1620: }
                   1621: 
                   1622: void
                   1623: proto_cmd_debug(struct proto *p, uint mask, int cnt UNUSED)
                   1624: {
                   1625:   p->debug = mask;
                   1626: }
                   1627: 
                   1628: void
                   1629: proto_cmd_mrtdump(struct proto *p, uint mask, int cnt UNUSED)
                   1630: {
                   1631:   p->mrtdump = mask;
                   1632: }
                   1633: 
                   1634: static void
                   1635: proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uint, int), uint arg)
                   1636: {
                   1637:   if (s->class != SYM_PROTO)
                   1638:     {
                   1639:       cli_msg(9002, "%s is not a protocol", s->name);
                   1640:       return;
                   1641:     }
                   1642: 
                   1643:   cmd(((struct proto_config *)s->def)->proto, arg, 0);
                   1644:   cli_msg(0, "");
                   1645: }
                   1646: 
                   1647: static void
                   1648: proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, uint, int), uint arg)
                   1649: {
                   1650:   int cnt = 0;
                   1651: 
                   1652:   node *nn;
                   1653:   WALK_LIST(nn, proto_list)
                   1654:     {
                   1655:       struct proto *p = SKIP_BACK(struct proto, glob_node, nn);
                   1656: 
                   1657:       if (!patt || patmatch(patt, p->name))
                   1658:        cmd(p, arg, cnt++);
                   1659:     }
                   1660: 
                   1661:   if (!cnt)
                   1662:     cli_msg(8003, "No protocols match");
                   1663:   else
                   1664:     cli_msg(0, "");
                   1665: }
                   1666: 
                   1667: void
                   1668: proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uint, int),
                   1669:                int restricted, uint arg)
                   1670: {
                   1671:   if (restricted && cli_access_restricted())
                   1672:     return;
                   1673: 
                   1674:   if (ps.patt)
                   1675:     proto_apply_cmd_patt(ps.ptr, cmd, arg);
                   1676:   else
                   1677:     proto_apply_cmd_symbol(ps.ptr, cmd, arg);
                   1678: }
                   1679: 
                   1680: struct proto *
                   1681: proto_get_named(struct symbol *sym, struct protocol *pr)
                   1682: {
                   1683:   struct proto *p, *q;
                   1684: 
                   1685:   if (sym)
                   1686:     {
                   1687:       if (sym->class != SYM_PROTO)
                   1688:        cf_error("%s: Not a protocol", sym->name);
                   1689:       p = ((struct proto_config *)sym->def)->proto;
                   1690:       if (!p || p->proto != pr)
                   1691:        cf_error("%s: Not a %s protocol", sym->name, pr->name);
                   1692:     }
                   1693:   else
                   1694:     {
                   1695:       p = NULL;
                   1696:       WALK_LIST(q, active_proto_list)
                   1697:        if (q->proto == pr)
                   1698:          {
                   1699:            if (p)
                   1700:              cf_error("There are multiple %s protocols running", pr->name);
                   1701:            p = q;
                   1702:          }
                   1703:       if (!p)
                   1704:        cf_error("There is no %s protocol running", pr->name);
                   1705:     }
                   1706:   return p;
                   1707: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>