Annotation of embedaddon/bird/nest/proto.c, revision 1.1.1.2

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;
1.1.1.2 ! misho     389:   q->vrf = c->vrf;
        !           390:   q->vrf_set = c->vrf_set;
1.1       misho     391: 
                    392:   add_tail(&initial_proto_list, &q->n);
                    393: 
                    394:   if (p == &proto_unix_iface)
                    395:     initial_device_proto = q;
                    396: 
                    397:   add_tail(&proto_list, &q->glob_node);
                    398:   PD(q, "Initializing%s", q->disabled ? " [disabled]" : "");
                    399:   return q;
                    400: }
                    401: 
                    402: int proto_reconfig_type;  /* Hack to propagate type info to pipe reconfigure hook */
                    403: 
                    404: static int
                    405: proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
                    406: {
                    407:   /* If the protocol is DOWN, we just restart it */
                    408:   if (p->proto_state == PS_DOWN)
                    409:     return 0;
                    410: 
                    411:   /* If there is a too big change in core attributes, ... */
                    412:   if ((nc->protocol != oc->protocol) ||
                    413:       (nc->disabled != p->disabled) ||
1.1.1.2 ! misho     414:       (nc->vrf != oc->vrf) ||
        !           415:       (nc->vrf_set != oc->vrf_set) ||
1.1       misho     416:       (nc->table->table != oc->table->table))
                    417:     return 0;
                    418: 
                    419:   p->debug = nc->debug;
                    420:   p->mrtdump = nc->mrtdump;
                    421:   proto_reconfig_type = type;
                    422: 
                    423:   /* Execute protocol specific reconfigure hook */
                    424:   if (! (p->proto->reconfigure && p->proto->reconfigure(p, nc)))
                    425:     return 0;
                    426: 
                    427:   DBG("\t%s: same\n", oc->name);
                    428:   PD(p, "Reconfigured");
                    429:   p->cf = nc;
                    430:   p->name = nc->name;
                    431:   p->preference = nc->preference;
                    432: 
                    433: 
                    434:   /* Multitable protocols handle rest in their reconfigure hooks */
                    435:   if (p->proto->multitable)
                    436:     return 1;
                    437: 
1.1.1.2 ! misho     438:   int import_changed = ! filter_same(nc->in_filter, oc->in_filter);
        !           439:   int export_changed = ! filter_same(nc->out_filter, oc->out_filter);
        !           440: 
        !           441:   /* We treat a change in preferences by reimporting routes */
        !           442:   if (nc->preference != oc->preference)
        !           443:     import_changed = 1;
        !           444: 
1.1       misho     445:   /* Update filters and limits in the main announce hook
                    446:      Note that this also resets limit state */
                    447:   if (p->main_ahook)
1.1.1.2 ! misho     448:     {
1.1       misho     449:       struct announce_hook *ah = p->main_ahook;
                    450:       ah->in_filter = nc->in_filter;
                    451:       ah->out_filter = nc->out_filter;
                    452:       ah->rx_limit = nc->rx_limit;
                    453:       ah->in_limit = nc->in_limit;
                    454:       ah->out_limit = nc->out_limit;
                    455:       ah->in_keep_filtered = nc->in_keep_filtered;
                    456:       proto_verify_limits(ah);
1.1.1.2 ! misho     457: 
        !           458:       if (export_changed)
        !           459:        ah->last_out_filter_change = now;
1.1       misho     460:     }
                    461: 
                    462:   /* Update routes when filters changed. If the protocol in not UP,
                    463:      it has no routes and we can ignore such changes */
                    464:   if ((p->proto_state != PS_UP) || (type == RECONFIG_SOFT))
                    465:     return 1;
                    466: 
                    467:   if (import_changed || export_changed)
                    468:     log(L_INFO "Reloading protocol %s", p->name);
                    469: 
                    470:   /* If import filter changed, call reload hook */
                    471:   if (import_changed && ! (p->reload_routes && p->reload_routes(p)))
                    472:     {
                    473:       /* Now, the protocol is reconfigured. But route reload failed
                    474:         and we have to do regular protocol restart. */
                    475:       log(L_INFO "Restarting protocol %s", p->name);
                    476:       p->disabled = 1;
                    477:       p->down_code = PDC_CF_RESTART;
                    478:       proto_rethink_goal(p);
                    479:       p->disabled = 0;
                    480:       proto_rethink_goal(p);
                    481:       return 1;
                    482:     }
                    483: 
                    484:   if (export_changed)
                    485:     proto_request_feeding(p);
                    486: 
                    487:   return 1;
                    488: }
                    489: 
                    490: /**
                    491:  * protos_commit - commit new protocol configuration
                    492:  * @new: new configuration
                    493:  * @old: old configuration or %NULL if it's boot time config
                    494:  * @force_reconfig: force restart of all protocols (used for example
                    495:  * when the router ID changes)
                    496:  * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
                    497:  *
                    498:  * Scan differences between @old and @new configuration and adjust all
                    499:  * protocol instances to conform to the new configuration.
                    500:  *
                    501:  * When a protocol exists in the new configuration, but it doesn't in the
                    502:  * original one, it's immediately started. When a collision with the other
                    503:  * running protocol would arise, the new protocol will be temporarily stopped
                    504:  * by the locking mechanism.
                    505:  *
                    506:  * When a protocol exists in the old configuration, but it doesn't in the
                    507:  * new one, it's shut down and deleted after the shutdown completes.
                    508:  *
                    509:  * When a protocol exists in both configurations, the core decides
                    510:  * whether it's possible to reconfigure it dynamically - it checks all
                    511:  * the core properties of the protocol (changes in filters are ignored
                    512:  * if type is RECONFIG_SOFT) and if they match, it asks the
                    513:  * reconfigure() hook of the protocol to see if the protocol is able
                    514:  * to switch to the new configuration.  If it isn't possible, the
                    515:  * protocol is shut down and a new instance is started with the new
                    516:  * configuration after the shutdown is completed.
                    517:  */
                    518: void
                    519: protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
                    520: {
                    521:   struct proto_config *oc, *nc;
                    522:   struct proto *p, *n;
                    523:   struct symbol *sym;
                    524: 
                    525:   DBG("protos_commit:\n");
                    526:   if (old)
                    527:     {
                    528:       WALK_LIST(oc, old->protos)
                    529:        {
                    530:          p = oc->proto;
                    531:          sym = cf_find_symbol(new, oc->name);
                    532:          if (sym && sym->class == SYM_PROTO && !new->shutdown)
                    533:            {
                    534:              /* Found match, let's check if we can smoothly switch to new configuration */
                    535:              /* No need to check description */
                    536:              nc = sym->def;
                    537:              nc->proto = p;
                    538: 
                    539:              /* We will try to reconfigure protocol p */
                    540:              if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
                    541:                continue;
                    542: 
                    543:              /* Unsuccessful, we will restart it */
                    544:              if (!p->disabled && !nc->disabled)
                    545:                log(L_INFO "Restarting protocol %s", p->name);
                    546:              else if (p->disabled && !nc->disabled)
                    547:                log(L_INFO "Enabling protocol %s", p->name);
                    548:              else if (!p->disabled && nc->disabled)
                    549:                log(L_INFO "Disabling protocol %s", p->name);
                    550: 
                    551:              p->down_code = nc->disabled ? PDC_CF_DISABLE : PDC_CF_RESTART;
                    552:              p->cf_new = nc;
                    553:            }
                    554:          else if (!new->shutdown)
                    555:            {
                    556:              log(L_INFO "Removing protocol %s", p->name);
                    557:              p->down_code = PDC_CF_REMOVE;
                    558:              p->cf_new = NULL;
                    559:            }
                    560:          else /* global shutdown */
                    561:            {
                    562:              p->down_code = PDC_CMD_SHUTDOWN;
                    563:              p->cf_new = NULL;
                    564:            }
                    565: 
                    566:          p->reconfiguring = 1;
                    567:          config_add_obstacle(old);
                    568:          proto_rethink_goal(p);
                    569:        }
                    570:     }
                    571: 
                    572:   WALK_LIST(nc, new->protos)
                    573:     if (!nc->proto)
                    574:       {
                    575:        if (old)                /* Not a first-time configuration */
                    576:          log(L_INFO "Adding protocol %s", nc->name);
                    577:        proto_init(nc);
                    578:       }
                    579:   DBG("\tdone\n");
                    580: 
                    581:   DBG("Protocol start\n");
                    582: 
                    583:   /* Start device protocol first */
                    584:   if (initial_device_proto)
                    585:   {
                    586:     proto_rethink_goal(initial_device_proto);
                    587:     initial_device_proto = NULL;
                    588:   }
                    589: 
                    590:   /* Determine router ID for the first time - it has to be here and not in
                    591:      global_commit() because it is postponed after start of device protocol */
                    592:   if (!config->router_id)
                    593:     {
                    594:       config->router_id = if_choose_router_id(config->router_id_from, 0);
                    595:       if (!config->router_id)
                    596:        die("Cannot determine router ID, please configure it manually");
                    597:     }
                    598: 
                    599:   /* Start all other protocols */
                    600:   WALK_LIST_DELSAFE(p, n, initial_proto_list)
                    601:     proto_rethink_goal(p);
                    602: }
                    603: 
                    604: static void
                    605: proto_rethink_goal(struct proto *p)
                    606: {
                    607:   struct protocol *q;
                    608:   byte goal;
                    609: 
                    610:   if (p->reconfiguring && p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN)
                    611:     {
                    612:       struct proto_config *nc = p->cf_new;
                    613:       DBG("%s has shut down for reconfiguration\n", p->name);
                    614:       p->cf->proto = NULL;
                    615:       config_del_obstacle(p->cf->global);
                    616:       rem_node(&p->n);
                    617:       rem_node(&p->glob_node);
1.1.1.2 ! misho     618:       mb_free(p->message);
1.1       misho     619:       mb_free(p);
                    620:       if (!nc)
                    621:        return;
                    622:       p = proto_init(nc);
                    623:     }
                    624: 
                    625:   /* Determine what state we want to reach */
                    626:   if (p->disabled || p->reconfiguring)
                    627:     goal = PS_DOWN;
                    628:   else
                    629:     goal = PS_UP;
                    630: 
                    631:   q = p->proto;
                    632:   if (goal == PS_UP)                   /* Going up */
                    633:     {
                    634:       if (p->proto_state == PS_DOWN && p->core_state == FS_HUNGRY)
                    635:        {
                    636:          DBG("Kicking %s up\n", p->name);
                    637:          PD(p, "Starting");
                    638:          proto_init_instance(p);
                    639:          proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
                    640:        }
                    641:     }
                    642:   else                                         /* Going down */
                    643:     {
                    644:       if (p->proto_state == PS_START || p->proto_state == PS_UP)
                    645:        {
                    646:          DBG("Kicking %s down\n", p->name);
                    647:          PD(p, "Shutting down");
                    648:          proto_notify_state(p, (q->shutdown ? q->shutdown(p) : PS_DOWN));
                    649:        }
                    650:     }
                    651: }
                    652: 
                    653: 
                    654: /**
                    655:  * DOC: Graceful restart recovery
                    656:  *
                    657:  * Graceful restart of a router is a process when the routing plane (e.g. BIRD)
                    658:  * restarts but both the forwarding plane (e.g kernel routing table) and routing
                    659:  * neighbors keep proper routes, and therefore uninterrupted packet forwarding
                    660:  * is maintained.
                    661:  *
                    662:  * BIRD implements graceful restart recovery by deferring export of routes to
                    663:  * protocols until routing tables are refilled with the expected content. After
                    664:  * start, protocols generate routes as usual, but routes are not propagated to
                    665:  * them, until protocols report that they generated all routes. After that,
                    666:  * graceful restart recovery is finished and the export (and the initial feed)
                    667:  * to protocols is enabled.
                    668:  *
                    669:  * When graceful restart recovery need is detected during initialization, then
                    670:  * enabled protocols are marked with @gr_recovery flag before start. Such
                    671:  * protocols then decide how to proceed with graceful restart, participation is
                    672:  * voluntary. Protocols could lock the recovery by proto_graceful_restart_lock()
                    673:  * (stored in @gr_lock flag), which means that they want to postpone the end of
                    674:  * the recovery until they converge and then unlock it. They also could set
                    675:  * @gr_wait before advancing to %PS_UP, which means that the core should defer
                    676:  * route export to that protocol until the end of the recovery. This should be
                    677:  * done by protocols that expect their neigbors to keep the proper routes
                    678:  * (kernel table, BGP sessions with BGP graceful restart capability).
                    679:  *
                    680:  * The graceful restart recovery is finished when either all graceful restart
                    681:  * locks are unlocked or when graceful restart wait timer fires.
                    682:  *
                    683:  */
                    684: 
                    685: static void graceful_restart_done(struct timer *t);
                    686: 
                    687: /**
                    688:  * graceful_restart_recovery - request initial graceful restart recovery
                    689:  *
                    690:  * Called by the platform initialization code if the need for recovery
                    691:  * after graceful restart is detected during boot. Have to be called
                    692:  * before protos_commit().
                    693:  */
                    694: void
                    695: graceful_restart_recovery(void)
                    696: {
                    697:   graceful_restart_state = GRS_INIT;
                    698: }
                    699: 
                    700: /**
                    701:  * graceful_restart_init - initialize graceful restart
                    702:  *
                    703:  * When graceful restart recovery was requested, the function starts an active
                    704:  * phase of the recovery and initializes graceful restart wait timer. The
                    705:  * function have to be called after protos_commit().
                    706:  */
                    707: void
                    708: graceful_restart_init(void)
                    709: {
                    710:   if (!graceful_restart_state)
                    711:     return;
                    712: 
                    713:   log(L_INFO "Graceful restart started");
                    714: 
                    715:   if (!graceful_restart_locks)
                    716:     {
                    717:       graceful_restart_done(NULL);
                    718:       return;
                    719:     }
                    720: 
                    721:   graceful_restart_state = GRS_ACTIVE;
                    722:   gr_wait_timer = tm_new(proto_pool);
                    723:   gr_wait_timer->hook = graceful_restart_done;
                    724:   tm_start(gr_wait_timer, config->gr_wait);
                    725: }
                    726: 
                    727: /**
                    728:  * graceful_restart_done - finalize graceful restart
                    729:  * @t: unused
                    730:  *
                    731:  * When there are no locks on graceful restart, the functions finalizes the
                    732:  * graceful restart recovery. Protocols postponing route export until the end of
                    733:  * the recovery are awakened and the export to them is enabled. All other
                    734:  * related state is cleared. The function is also called when the graceful
                    735:  * restart wait timer fires (but there are still some locks).
                    736:  */
                    737: static void
                    738: graceful_restart_done(struct timer *t UNUSED)
                    739: {
                    740:   struct proto *p;
                    741:   node *n;
                    742: 
                    743:   log(L_INFO "Graceful restart done");
                    744:   graceful_restart_state = GRS_DONE;
                    745: 
                    746:   WALK_LIST2(p, n, proto_list, glob_node)
                    747:     {
                    748:       if (!p->gr_recovery)
                    749:        continue;
                    750: 
                    751:       /* Resume postponed export of routes */
                    752:       if ((p->proto_state == PS_UP) && p->gr_wait)
                    753:       {
                    754:        proto_want_export_up(p);
                    755:        proto_log_state_change(p);
                    756:       }
                    757: 
                    758:       /* Cleanup */
                    759:       p->gr_recovery = 0;
                    760:       p->gr_wait = 0;
                    761:       p->gr_lock = 0;
                    762:     }
                    763: 
                    764:   graceful_restart_locks = 0;
                    765: }
                    766: 
                    767: void
                    768: graceful_restart_show_status(void)
                    769: {
                    770:   if (graceful_restart_state != GRS_ACTIVE)
                    771:     return;
                    772: 
                    773:   cli_msg(-24, "Graceful restart recovery in progress");
                    774:   cli_msg(-24, "  Waiting for %d protocols to recover", graceful_restart_locks);
                    775:   cli_msg(-24, "  Wait timer is %d/%d", tm_remains(gr_wait_timer), config->gr_wait);
                    776: }
                    777: 
                    778: /**
                    779:  * proto_graceful_restart_lock - lock graceful restart by protocol
                    780:  * @p: protocol instance
                    781:  *
                    782:  * This function allows a protocol to postpone the end of graceful restart
                    783:  * recovery until it converges. The lock is removed when the protocol calls
                    784:  * proto_graceful_restart_unlock() or when the protocol is stopped.
                    785:  *
                    786:  * The function have to be called during the initial phase of graceful restart
                    787:  * recovery and only for protocols that are part of graceful restart (i.e. their
                    788:  * @gr_recovery is set), which means it should be called from protocol start
                    789:  * hooks.
                    790:  */
                    791: void
                    792: proto_graceful_restart_lock(struct proto *p)
                    793: {
                    794:   ASSERT(graceful_restart_state == GRS_INIT);
                    795:   ASSERT(p->gr_recovery);
                    796: 
                    797:   if (p->gr_lock)
                    798:     return;
                    799: 
                    800:   p->gr_lock = 1;
                    801:   graceful_restart_locks++;
                    802: }
                    803: 
                    804: /**
                    805:  * proto_graceful_restart_unlock - unlock graceful restart by protocol
                    806:  * @p: protocol instance
                    807:  *
                    808:  * This function unlocks a lock from proto_graceful_restart_lock(). It is also
                    809:  * automatically called when the lock holding protocol went down.
                    810:  */
                    811: void
                    812: proto_graceful_restart_unlock(struct proto *p)
                    813: {
                    814:   if (!p->gr_lock)
                    815:     return;
                    816: 
                    817:   p->gr_lock = 0;
                    818:   graceful_restart_locks--;
                    819: 
                    820:   if ((graceful_restart_state == GRS_ACTIVE) && !graceful_restart_locks)
                    821:     tm_start(gr_wait_timer, 0);
                    822: }
                    823: 
                    824: 
                    825: 
                    826: /**
                    827:  * protos_dump_all - dump status of all protocols
                    828:  *
                    829:  * This function dumps status of all existing protocol instances to the
                    830:  * debug output. It involves printing of general status information
                    831:  * such as protocol states, its position on the protocol lists
                    832:  * and also calling of a dump() hook of the protocol to print
                    833:  * the internals.
                    834:  */
                    835: void
                    836: protos_dump_all(void)
                    837: {
                    838:   struct proto *p;
                    839:   struct announce_hook *a;
                    840: 
                    841:   debug("Protocols:\n");
                    842: 
                    843:   WALK_LIST(p, active_proto_list)
                    844:     {
                    845:       debug("  protocol %s state %s/%s\n", p->name,
                    846:            p_states[p->proto_state], c_states[p->core_state]);
                    847:       for (a = p->ahooks; a; a = a->next)
                    848:        {
                    849:          debug("\tTABLE %s\n", a->table->name);
                    850:          if (a->in_filter)
                    851:            debug("\tInput filter: %s\n", filter_name(a->in_filter));
                    852:          if (a->out_filter != FILTER_REJECT)
                    853:            debug("\tOutput filter: %s\n", filter_name(a->out_filter));
                    854:        }
                    855:       if (p->disabled)
                    856:        debug("\tDISABLED\n");
                    857:       else if (p->proto->dump)
                    858:        p->proto->dump(p);
                    859:     }
                    860:   WALK_LIST(p, inactive_proto_list)
                    861:     debug("  inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]);
                    862:   WALK_LIST(p, initial_proto_list)
                    863:     debug("  initial %s\n", p->name);
                    864:   WALK_LIST(p, flush_proto_list)
                    865:     debug("  flushing %s\n", p->name);
                    866: }
                    867: 
                    868: /**
                    869:  * proto_build - make a single protocol available
                    870:  * @p: the protocol
                    871:  *
                    872:  * After the platform specific initialization code uses protos_build()
                    873:  * to add all the standard protocols, it should call proto_build() for
                    874:  * all platform specific protocols to inform the core that they exist.
                    875:  */
                    876: void
                    877: proto_build(struct protocol *p)
                    878: {
                    879:   add_tail(&protocol_list, &p->n);
                    880:   if (p->attr_class)
                    881:     {
                    882:       ASSERT(!attr_class_to_protocol[p->attr_class]);
                    883:       attr_class_to_protocol[p->attr_class] = p;
                    884:     }
                    885: }
                    886: 
                    887: /* FIXME: convert this call to some protocol hook */
                    888: extern void bfd_init_all(void);
                    889: 
                    890: /**
                    891:  * protos_build - build a protocol list
                    892:  *
                    893:  * This function is called during BIRD startup to insert
                    894:  * all standard protocols to the global protocol list. Insertion
                    895:  * of platform specific protocols (such as the kernel syncer)
                    896:  * is in the domain of competence of the platform dependent
                    897:  * startup code.
                    898:  */
                    899: void
                    900: protos_build(void)
                    901: {
                    902:   init_list(&protocol_list);
                    903:   init_list(&proto_list);
                    904:   init_list(&active_proto_list);
                    905:   init_list(&inactive_proto_list);
                    906:   init_list(&initial_proto_list);
                    907:   init_list(&flush_proto_list);
                    908:   proto_build(&proto_device);
                    909: #ifdef CONFIG_RADV
                    910:   proto_build(&proto_radv);
                    911: #endif
                    912: #ifdef CONFIG_RIP
                    913:   proto_build(&proto_rip);
                    914: #endif
                    915: #ifdef CONFIG_STATIC
                    916:   proto_build(&proto_static);
                    917: #endif
1.1.1.2 ! misho     918: #ifdef CONFIG_MRT
        !           919:   proto_build(&proto_mrt);
        !           920: #endif
1.1       misho     921: #ifdef CONFIG_OSPF
                    922:   proto_build(&proto_ospf);
                    923: #endif
                    924: #ifdef CONFIG_PIPE
                    925:   proto_build(&proto_pipe);
                    926: #endif
                    927: #ifdef CONFIG_BGP
                    928:   proto_build(&proto_bgp);
                    929: #endif
                    930: #ifdef CONFIG_BFD
                    931:   proto_build(&proto_bfd);
                    932:   bfd_init_all();
                    933: #endif
                    934: #ifdef CONFIG_BABEL
                    935:   proto_build(&proto_babel);
                    936: #endif
                    937: 
                    938:   proto_pool = rp_new(&root_pool, "Protocols");
                    939:   proto_flush_event = ev_new(proto_pool);
                    940:   proto_flush_event->hook = proto_flush_loop;
                    941:   proto_shutdown_timer = tm_new(proto_pool);
                    942:   proto_shutdown_timer->hook = proto_shutdown_loop;
                    943: }
                    944: 
                    945: static void
                    946: proto_feed_more(void *P)
                    947: {
                    948:   struct proto *p = P;
                    949: 
                    950:   if (p->export_state != ES_FEEDING)
                    951:     return;
                    952: 
                    953:   DBG("Feeding protocol %s continued\n", p->name);
                    954:   if (rt_feed_baby(p))
                    955:     {
                    956:       DBG("Feeding protocol %s finished\n", p->name);
                    957:       p->export_state = ES_READY;
                    958:       proto_log_state_change(p);
                    959: 
                    960:       if (p->feed_end)
                    961:        p->feed_end(p);
                    962:     }
                    963:   else
                    964:     {
                    965:       p->attn->hook = proto_feed_more;
                    966:       ev_schedule(p->attn);            /* Will continue later... */
                    967:     }
                    968: }
                    969: 
                    970: static void
                    971: proto_feed_initial(void *P)
                    972: {
                    973:   struct proto *p = P;
                    974: 
                    975:   if (p->export_state != ES_FEEDING)
                    976:     return;
                    977: 
                    978:   DBG("Feeding protocol %s\n", p->name);
                    979: 
                    980:   if_feed_baby(p);
                    981:   proto_feed_more(P);
                    982: }
                    983: 
                    984: static void
                    985: proto_schedule_feed(struct proto *p, int initial)
                    986: {
                    987:   DBG("%s: Scheduling meal\n", p->name);
                    988: 
                    989:   p->export_state = ES_FEEDING;
                    990:   p->refeeding = !initial;
                    991: 
                    992:   p->attn->hook = initial ? proto_feed_initial : proto_feed_more;
                    993:   ev_schedule(p->attn);
                    994: 
                    995:   if (p->feed_begin)
                    996:     p->feed_begin(p, initial);
                    997: }
                    998: 
                    999: /*
                   1000:  * Flushing loop is responsible for flushing routes and protocols
                   1001:  * after they went down. It runs in proto_flush_event. At the start of
                   1002:  * one round, protocols waiting to flush are marked in
                   1003:  * proto_schedule_flush_loop(). At the end of the round (when routing
                   1004:  * table flush is complete), marked protocols are flushed and a next
                   1005:  * round may start.
                   1006:  */
                   1007: 
                   1008: static int flush_loop_state;   /* 1 -> running */
                   1009: 
                   1010: static void
                   1011: proto_schedule_flush_loop(void)
                   1012: {
                   1013:   struct proto *p;
                   1014:   struct announce_hook *h;
                   1015: 
                   1016:   if (flush_loop_state)
                   1017:     return;
                   1018:   flush_loop_state = 1;
                   1019: 
                   1020:   WALK_LIST(p, flush_proto_list)
                   1021:   {
                   1022:     p->flushing = 1;
                   1023:     for (h=p->ahooks; h; h=h->next)
                   1024:       rt_mark_for_prune(h->table);
                   1025:   }
                   1026: 
                   1027:   ev_schedule(proto_flush_event);
                   1028: }
                   1029: 
                   1030: static void
                   1031: proto_flush_loop(void *unused UNUSED)
                   1032: {
                   1033:   struct proto *p;
                   1034: 
                   1035:   if (! rt_prune_loop())
                   1036:     {
                   1037:       /* Rtable pruning is not finished */
                   1038:       ev_schedule(proto_flush_event);
                   1039:       return;
                   1040:     }
                   1041: 
                   1042:   rt_prune_sources();
                   1043: 
                   1044:  again:
                   1045:   WALK_LIST(p, flush_proto_list)
                   1046:     if (p->flushing)
                   1047:       {
                   1048:        /* This will flush interfaces in the same manner
                   1049:           like rt_prune_all() flushes routes */
                   1050:        if (p->proto == &proto_unix_iface)
                   1051:          if_flush_ifaces(p);
                   1052: 
                   1053:        DBG("Flushing protocol %s\n", p->name);
                   1054:        p->flushing = 0;
                   1055:        p->core_state = FS_HUNGRY;
                   1056:        proto_relink(p);
                   1057:        proto_log_state_change(p);
                   1058:        if (p->proto_state == PS_DOWN)
                   1059:          proto_fell_down(p);
                   1060:        goto again;
                   1061:       }
                   1062: 
                   1063:   /* This round finished, perhaps there will be another one */
                   1064:   flush_loop_state = 0;
                   1065:   if (!EMPTY_LIST(flush_proto_list))
                   1066:     proto_schedule_flush_loop();
                   1067: }
                   1068: 
                   1069: 
                   1070: /* Temporary hack to propagate restart to BGP */
                   1071: int proto_restart;
                   1072: 
                   1073: static void
                   1074: proto_shutdown_loop(struct timer *t UNUSED)
                   1075: {
                   1076:   struct proto *p, *p_next;
                   1077: 
                   1078:   WALK_LIST_DELSAFE(p, p_next, active_proto_list)
                   1079:     if (p->down_sched)
                   1080:       {
                   1081:        proto_restart = (p->down_sched == PDS_RESTART);
                   1082: 
                   1083:        p->disabled = 1;
                   1084:        proto_rethink_goal(p);
                   1085:        if (proto_restart)
                   1086:          {
                   1087:            p->disabled = 0;
                   1088:            proto_rethink_goal(p);
                   1089:          }
                   1090:       }
                   1091: }
                   1092: 
                   1093: static inline void
                   1094: proto_schedule_down(struct proto *p, byte restart, byte code)
                   1095: {
                   1096:   /* Does not work for other states (even PS_START) */
                   1097:   ASSERT(p->proto_state == PS_UP);
                   1098: 
                   1099:   /* Scheduled restart may change to shutdown, but not otherwise */
                   1100:   if (p->down_sched == PDS_DISABLE)
                   1101:     return;
                   1102: 
                   1103:   p->down_sched = restart ? PDS_RESTART : PDS_DISABLE;
                   1104:   p->down_code = code;
                   1105:   tm_start_max(proto_shutdown_timer, restart ? 2 : 0);
                   1106: }
                   1107: 
1.1.1.2 ! misho    1108: /**
        !          1109:  * proto_set_message - set administrative message to protocol
        !          1110:  * @p: protocol
        !          1111:  * @msg: message
        !          1112:  * @len: message length (-1 for NULL-terminated string)
        !          1113:  *
        !          1114:  * The function sets administrative message (string) related to protocol state
        !          1115:  * change. It is called by the nest code for manual enable/disable/restart
        !          1116:  * commands all routes to the protocol, and by protocol-specific code when the
        !          1117:  * protocol state change is initiated by the protocol. Using NULL message clears
        !          1118:  * the last message. The message string may be either NULL-terminated or with an
        !          1119:  * explicit length.
        !          1120:  */
        !          1121: void
        !          1122: proto_set_message(struct proto *p, char *msg, int len)
        !          1123: {
        !          1124:   mb_free(p->message);
        !          1125:   p->message = NULL;
        !          1126: 
        !          1127:   if (!msg || !len)
        !          1128:     return;
        !          1129: 
        !          1130:   if (len < 0)
        !          1131:     len = strlen(msg);
        !          1132: 
        !          1133:   if (!len)
        !          1134:     return;
        !          1135: 
        !          1136:   p->message = mb_alloc(proto_pool, len + 1);
        !          1137:   memcpy(p->message, msg, len);
        !          1138:   p->message[len] = 0;
        !          1139: }
        !          1140: 
1.1       misho    1141: 
                   1142: /**
                   1143:  * proto_request_feeding - request feeding routes to the protocol
                   1144:  * @p: given protocol 
                   1145:  *
                   1146:  * Sometimes it is needed to send again all routes to the
                   1147:  * protocol. This is called feeding and can be requested by this
                   1148:  * function. This would cause protocol export state transition
                   1149:  * to ES_FEEDING (during feeding) and when completed, it will
                   1150:  * switch back to ES_READY. This function can be called even
                   1151:  * when feeding is already running, in that case it is restarted.
                   1152:  */
                   1153: void
                   1154: proto_request_feeding(struct proto *p)
                   1155: {
                   1156:   ASSERT(p->proto_state == PS_UP);
                   1157: 
                   1158:   /* Do nothing if we are still waiting for feeding */
                   1159:   if (p->export_state == ES_DOWN)
                   1160:     return;
                   1161: 
                   1162:   /* If we are already feeding, we want to restart it */
                   1163:   if (p->export_state == ES_FEEDING)
                   1164:     {
                   1165:       /* Unless feeding is in initial state */
                   1166:       if (p->attn->hook == proto_feed_initial)
                   1167:        return;
                   1168: 
                   1169:       rt_feed_baby_abort(p);
                   1170:     }
                   1171: 
                   1172:   /* FIXME: This should be changed for better support of multitable protos */
                   1173:   struct announce_hook *ah;
                   1174:   for (ah = p->ahooks; ah; ah = ah->next)
                   1175:     proto_reset_limit(ah->out_limit);
                   1176: 
                   1177:   /* Hack: reset exp_routes during refeed, and do not decrease it later */
                   1178:   p->stats.exp_routes = 0;
                   1179: 
                   1180:   proto_schedule_feed(p, 0);
                   1181:   proto_log_state_change(p);
                   1182: }
                   1183: 
                   1184: static const char *
                   1185: proto_limit_name(struct proto_limit *l)
                   1186: {
                   1187:   const char *actions[] = {
                   1188:     [PLA_WARN] = "warn",
                   1189:     [PLA_BLOCK] = "block",
                   1190:     [PLA_RESTART] = "restart",
                   1191:     [PLA_DISABLE] = "disable",
                   1192:   };
                   1193: 
                   1194:   return actions[l->action];
                   1195: }
                   1196: 
                   1197: /**
                   1198:  * proto_notify_limit: notify about limit hit and take appropriate action
                   1199:  * @ah: announce hook
                   1200:  * @l: limit being hit
                   1201:  * @dir: limit direction (PLD_*)
                   1202:  * @rt_count: the number of routes 
                   1203:  *
                   1204:  * The function is called by the route processing core when limit @l
                   1205:  * is breached. It activates the limit and tooks appropriate action
                   1206:  * according to @l->action.
                   1207:  */
                   1208: void
                   1209: proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count)
                   1210: {
                   1211:   const char *dir_name[PLD_MAX] = { "receive", "import" , "export" };
                   1212:   const byte dir_down[PLD_MAX] = { PDC_RX_LIMIT_HIT, PDC_IN_LIMIT_HIT, PDC_OUT_LIMIT_HIT };
                   1213:   struct proto *p = ah->proto;
                   1214: 
                   1215:   if (l->state == PLS_BLOCKED)
                   1216:     return;
                   1217: 
                   1218:   /* For warning action, we want the log message every time we hit the limit */
                   1219:   if (!l->state || ((l->action == PLA_WARN) && (rt_count == l->limit)))
                   1220:     log(L_WARN "Protocol %s hits route %s limit (%d), action: %s",
                   1221:        p->name, dir_name[dir], l->limit, proto_limit_name(l));
                   1222: 
                   1223:   switch (l->action)
                   1224:     {
                   1225:     case PLA_WARN:
                   1226:       l->state = PLS_ACTIVE;
                   1227:       break;
                   1228: 
                   1229:     case PLA_BLOCK:
                   1230:       l->state = PLS_BLOCKED;
                   1231:       break;
                   1232: 
                   1233:     case PLA_RESTART:
                   1234:     case PLA_DISABLE:
                   1235:       l->state = PLS_BLOCKED;
                   1236:       if (p->proto_state == PS_UP)
                   1237:        proto_schedule_down(p, l->action == PLA_RESTART, dir_down[dir]);
                   1238:       break;
                   1239:     }
                   1240: }
                   1241: 
                   1242: void
                   1243: proto_verify_limits(struct announce_hook *ah)
                   1244: {
                   1245:   struct proto_limit *l;
                   1246:   struct proto_stats *stats = ah->stats;
                   1247:   u32 all_routes = stats->imp_routes + stats->filt_routes;
                   1248: 
                   1249:   l = ah->rx_limit;
                   1250:   if (l && (all_routes > l->limit))
                   1251:     proto_notify_limit(ah, l, PLD_RX, all_routes);
                   1252: 
                   1253:   l = ah->in_limit;
                   1254:   if (l && (stats->imp_routes > l->limit))
                   1255:     proto_notify_limit(ah, l, PLD_IN, stats->imp_routes);
                   1256: 
                   1257:   l = ah->out_limit;
                   1258:   if (l && (stats->exp_routes > l->limit))
                   1259:     proto_notify_limit(ah, l, PLD_OUT, stats->exp_routes);
                   1260: }
                   1261: 
                   1262: 
                   1263: static void
                   1264: proto_want_core_up(struct proto *p)
                   1265: {
                   1266:   ASSERT(p->core_state == FS_HUNGRY);
                   1267: 
                   1268:   if (!p->proto->multitable)
                   1269:     {
                   1270:       p->main_source = rt_get_source(p, 0);
                   1271:       rt_lock_source(p->main_source);
                   1272: 
                   1273:       /* Connect protocol to routing table */
                   1274:       p->main_ahook = proto_add_announce_hook(p, p->table, &p->stats);
                   1275:       p->main_ahook->in_filter = p->cf->in_filter;
                   1276:       p->main_ahook->out_filter = p->cf->out_filter;
                   1277:       p->main_ahook->rx_limit = p->cf->rx_limit;
                   1278:       p->main_ahook->in_limit = p->cf->in_limit;
                   1279:       p->main_ahook->out_limit = p->cf->out_limit;
                   1280:       p->main_ahook->in_keep_filtered = p->cf->in_keep_filtered;
                   1281: 
                   1282:       proto_reset_limit(p->main_ahook->rx_limit);
                   1283:       proto_reset_limit(p->main_ahook->in_limit);
                   1284:       proto_reset_limit(p->main_ahook->out_limit);
                   1285:     }
                   1286: 
                   1287:   p->core_state = FS_HAPPY;
                   1288:   proto_relink(p);
                   1289: }
                   1290: 
                   1291: static void
                   1292: proto_want_export_up(struct proto *p)
                   1293: {
                   1294:   ASSERT(p->core_state == FS_HAPPY);
                   1295:   ASSERT(p->export_state == ES_DOWN);
                   1296: 
                   1297:   proto_link_ahooks(p);
                   1298:   proto_schedule_feed(p, 1); /* Sets ES_FEEDING */
                   1299: }
                   1300: 
                   1301: static void
                   1302: proto_want_export_down(struct proto *p)
                   1303: {
                   1304:   ASSERT(p->export_state != ES_DOWN);
                   1305: 
                   1306:   /* Need to abort feeding */
                   1307:   if (p->export_state == ES_FEEDING)
                   1308:     rt_feed_baby_abort(p);
                   1309: 
                   1310:   p->export_state = ES_DOWN;
                   1311:   p->stats.exp_routes = 0;
                   1312:   proto_unlink_ahooks(p);
                   1313: }
                   1314: 
                   1315: static void
                   1316: proto_want_core_down(struct proto *p)
                   1317: {
                   1318:   ASSERT(p->core_state == FS_HAPPY);
                   1319:   ASSERT(p->export_state == ES_DOWN);
                   1320: 
                   1321:   p->core_state = FS_FLUSHING;
                   1322:   proto_relink(p);
                   1323:   proto_schedule_flush_loop();
                   1324: 
                   1325:   if (!p->proto->multitable)
                   1326:     {
                   1327:       rt_unlock_source(p->main_source);
                   1328:       p->main_source = NULL;
                   1329:     }
                   1330: }
                   1331: 
                   1332: static void
                   1333: proto_falling_down(struct proto *p)
                   1334: {
                   1335:   p->gr_recovery = 0;
                   1336:   p->gr_wait = 0;
                   1337:   if (p->gr_lock)
                   1338:     proto_graceful_restart_unlock(p);
                   1339: }
                   1340: 
                   1341: static void
                   1342: proto_fell_down(struct proto *p)
                   1343: {
                   1344:   DBG("Protocol %s down\n", p->name);
                   1345: 
                   1346:   u32 all_routes = p->stats.imp_routes + p->stats.filt_routes;
                   1347:   if (all_routes != 0)
                   1348:     log(L_ERR "Protocol %s is down but still has %d routes", p->name, all_routes);
                   1349: 
                   1350:   bzero(&p->stats, sizeof(struct proto_stats));
                   1351:   proto_free_ahooks(p);
                   1352: 
                   1353:   if (! p->proto->multitable)
                   1354:     rt_unlock_table(p->table);
                   1355: 
                   1356:   if (p->proto->cleanup)
                   1357:     p->proto->cleanup(p);
                   1358: 
                   1359:   proto_rethink_goal(p);
                   1360: }
                   1361: 
                   1362: 
                   1363: /**
                   1364:  * proto_notify_state - notify core about protocol state change
                   1365:  * @p: protocol the state of which has changed
                   1366:  * @ps: the new status
                   1367:  *
                   1368:  * Whenever a state of a protocol changes due to some event internal
                   1369:  * to the protocol (i.e., not inside a start() or shutdown() hook),
                   1370:  * it should immediately notify the core about the change by calling
                   1371:  * proto_notify_state() which will write the new state to the &proto
                   1372:  * structure and take all the actions necessary to adapt to the new
                   1373:  * state. State change to PS_DOWN immediately frees resources of protocol
                   1374:  * and might execute start callback of protocol; therefore,
                   1375:  * it should be used at tail positions of protocol callbacks.
                   1376:  */
                   1377: void
                   1378: proto_notify_state(struct proto *p, unsigned ps)
                   1379: {
                   1380:   unsigned ops = p->proto_state;
                   1381:   unsigned cs = p->core_state;
                   1382:   unsigned es = p->export_state;
                   1383: 
                   1384:   DBG("%s reporting state transition %s/%s -> */%s\n", p->name, c_states[cs], p_states[ops], p_states[ps]);
                   1385:   if (ops == ps)
                   1386:     return;
                   1387: 
                   1388:   p->proto_state = ps;
                   1389:   p->last_state_change = now;
                   1390: 
                   1391:   switch (ps)
                   1392:     {
                   1393:     case PS_START:
                   1394:       ASSERT(ops == PS_DOWN || ops == PS_UP);
                   1395:       ASSERT(cs == FS_HUNGRY || cs == FS_HAPPY);
                   1396: 
                   1397:       if (es != ES_DOWN)
                   1398:        proto_want_export_down(p);
                   1399:       break;
                   1400: 
                   1401:     case PS_UP:
                   1402:       ASSERT(ops == PS_DOWN || ops == PS_START);
                   1403:       ASSERT(cs == FS_HUNGRY || cs == FS_HAPPY);
                   1404:       ASSERT(es == ES_DOWN);
                   1405: 
                   1406:       if (cs == FS_HUNGRY)
                   1407:        proto_want_core_up(p);
                   1408:       if (!p->gr_wait)
                   1409:        proto_want_export_up(p);
                   1410:       break;
                   1411: 
                   1412:     case PS_STOP:
                   1413:       ASSERT(ops == PS_START || ops == PS_UP);
                   1414: 
                   1415:       p->down_sched = 0;
                   1416: 
                   1417:       if (es != ES_DOWN)
                   1418:        proto_want_export_down(p);
                   1419:       if (cs == FS_HAPPY)
                   1420:        proto_want_core_down(p);
                   1421:       proto_falling_down(p);
                   1422:       break;
                   1423: 
                   1424:     case PS_DOWN:
                   1425:       p->down_code = 0;
                   1426:       p->down_sched = 0;
                   1427: 
                   1428:       if (es != ES_DOWN)
                   1429:        proto_want_export_down(p);
                   1430:       if (cs == FS_HAPPY)
                   1431:        proto_want_core_down(p);
                   1432:       if (ops != PS_STOP)
                   1433:        proto_falling_down(p);
                   1434: 
                   1435:       neigh_prune(); // FIXME convert neighbors to resource?
                   1436:       rfree(p->pool);
                   1437:       p->pool = NULL;
                   1438: 
                   1439:       if (cs == FS_HUNGRY)             /* Shutdown finished */
                   1440:        {
                   1441:          proto_log_state_change(p);
                   1442:          proto_fell_down(p);
                   1443:          return;                       /* The protocol might have ceased to exist */
                   1444:        }
                   1445:       break;
                   1446: 
                   1447:     default:
                   1448:       bug("%s: Invalid state %d", p->name, ps);
                   1449:     }
                   1450: 
                   1451:   proto_log_state_change(p);
                   1452: }
                   1453: 
                   1454: /*
                   1455:  *  CLI Commands
                   1456:  */
                   1457: 
                   1458: static char *
                   1459: proto_state_name(struct proto *p)
                   1460: {
                   1461: #define P(x,y) ((x << 4) | y)
                   1462:   switch (P(p->proto_state, p->core_state))
                   1463:     {
                   1464:     case P(PS_DOWN, FS_HUNGRY):                return "down";
                   1465:     case P(PS_START, FS_HUNGRY):
                   1466:     case P(PS_START, FS_HAPPY):                return "start";
                   1467:     case P(PS_UP, FS_HAPPY):
                   1468:       switch (p->export_state)
                   1469:        {
                   1470:        case ES_DOWN:                   return "wait";
                   1471:        case ES_FEEDING:                return "feed";
                   1472:        case ES_READY:                  return "up";
                   1473:        default:                        return "???";
                   1474:        }
                   1475:     case P(PS_STOP, FS_HUNGRY):
                   1476:     case P(PS_STOP, FS_FLUSHING):      return "stop";
                   1477:     case P(PS_DOWN, FS_FLUSHING):      return "flush";
                   1478:     default:                           return "???";
                   1479:     }
                   1480: #undef P
                   1481: }
                   1482: 
                   1483: static void
                   1484: proto_show_stats(struct proto_stats *s, int in_keep_filtered)
                   1485: {
                   1486:   if (in_keep_filtered)
                   1487:     cli_msg(-1006, "  Routes:         %u imported, %u filtered, %u exported, %u preferred", 
                   1488:            s->imp_routes, s->filt_routes, s->exp_routes, s->pref_routes);
                   1489:   else
                   1490:     cli_msg(-1006, "  Routes:         %u imported, %u exported, %u preferred", 
                   1491:            s->imp_routes, s->exp_routes, s->pref_routes);
                   1492: 
                   1493:   cli_msg(-1006, "  Route change stats:     received   rejected   filtered    ignored   accepted");
                   1494:   cli_msg(-1006, "    Import updates:     %10u %10u %10u %10u %10u",
                   1495:          s->imp_updates_received, s->imp_updates_invalid,
                   1496:          s->imp_updates_filtered, s->imp_updates_ignored,
                   1497:          s->imp_updates_accepted);
                   1498:   cli_msg(-1006, "    Import withdraws:   %10u %10u        --- %10u %10u",
                   1499:          s->imp_withdraws_received, s->imp_withdraws_invalid,
                   1500:          s->imp_withdraws_ignored, s->imp_withdraws_accepted);
                   1501:   cli_msg(-1006, "    Export updates:     %10u %10u %10u        --- %10u",
                   1502:          s->exp_updates_received, s->exp_updates_rejected,
                   1503:          s->exp_updates_filtered, s->exp_updates_accepted);
                   1504:   cli_msg(-1006, "    Export withdraws:   %10u        ---        ---        --- %10u",
                   1505:          s->exp_withdraws_received, s->exp_withdraws_accepted);
                   1506: }
                   1507: 
                   1508: void
                   1509: proto_show_limit(struct proto_limit *l, const char *dsc)
                   1510: {
                   1511:   if (!l)
                   1512:     return;
                   1513: 
                   1514:   cli_msg(-1006, "  %-16s%d%s", dsc, l->limit, l->state ? " [HIT]" : "");
                   1515:   cli_msg(-1006, "    Action:       %s", proto_limit_name(l));
                   1516: }
                   1517: 
                   1518: void
                   1519: proto_show_basic_info(struct proto *p)
                   1520: {
1.1.1.2 ! misho    1521:   if (p->vrf)
        !          1522:     cli_msg(-1006, "  VRF:            %s", p->vrf->name);
        !          1523: 
1.1       misho    1524:   cli_msg(-1006, "  Preference:     %d", p->preference);
                   1525:   cli_msg(-1006, "  Input filter:   %s", filter_name(p->cf->in_filter));
                   1526:   cli_msg(-1006, "  Output filter:  %s", filter_name(p->cf->out_filter));
                   1527: 
                   1528:   if (graceful_restart_state == GRS_ACTIVE)
                   1529:     cli_msg(-1006, "  GR recovery:   %s%s",
                   1530:            p->gr_lock ? " pending" : "",
                   1531:            p->gr_wait ? " waiting" : "");
                   1532: 
                   1533:   proto_show_limit(p->cf->rx_limit, "Receive limit:");
                   1534:   proto_show_limit(p->cf->in_limit, "Import limit:");
                   1535:   proto_show_limit(p->cf->out_limit, "Export limit:");
                   1536: 
                   1537:   if (p->proto_state != PS_DOWN)
                   1538:     proto_show_stats(&p->stats, p->cf->in_keep_filtered);
                   1539: }
                   1540: 
                   1541: void
1.1.1.2 ! misho    1542: proto_cmd_show(struct proto *p, uintptr_t verbose, int cnt)
1.1       misho    1543: {
                   1544:   byte buf[256], tbuf[TM_DATETIME_BUFFER_SIZE];
                   1545: 
                   1546:   /* First protocol - show header */
                   1547:   if (!cnt)
                   1548:     cli_msg(-2002, "name     proto    table    state  since       info");
                   1549: 
                   1550:   buf[0] = 0;
                   1551:   if (p->proto->get_status)
                   1552:     p->proto->get_status(p, buf);
                   1553:   tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change);
                   1554:   cli_msg(-1002, "%-8s %-8s %-8s %-5s  %-10s  %s",
                   1555:          p->name,
                   1556:          p->proto->name,
                   1557:          p->table->name,
                   1558:          proto_state_name(p),
                   1559:          tbuf,
                   1560:          buf);
                   1561:   if (verbose)
                   1562:     {
                   1563:       if (p->cf->dsc)
                   1564:        cli_msg(-1006, "  Description:    %s", p->cf->dsc);
1.1.1.2 ! misho    1565: 
        !          1566:       if (p->message)
        !          1567:        cli_msg(-1006, "  Message:        %s", p->message);
        !          1568: 
1.1       misho    1569:       if (p->cf->router_id)
                   1570:        cli_msg(-1006, "  Router ID:      %R", p->cf->router_id);
                   1571: 
1.1.1.2 ! misho    1572:       if (p->vrf_set)
        !          1573:        cli_msg(-1006, "  VRF:            %s", p->vrf ? p->vrf->name : "default");
        !          1574: 
1.1       misho    1575:       if (p->proto->show_proto_info)
                   1576:        p->proto->show_proto_info(p);
                   1577:       else
                   1578:        proto_show_basic_info(p);
                   1579: 
                   1580:       cli_msg(-1006, "");
                   1581:     }
                   1582: }
                   1583: 
                   1584: void
1.1.1.2 ! misho    1585: proto_cmd_disable(struct proto *p, uintptr_t arg, int cnt UNUSED)
1.1       misho    1586: {
                   1587:   if (p->disabled)
                   1588:     {
                   1589:       cli_msg(-8, "%s: already disabled", p->name);
                   1590:       return;
                   1591:     }
                   1592: 
                   1593:   log(L_INFO "Disabling protocol %s", p->name);
                   1594:   p->disabled = 1;
                   1595:   p->down_code = PDC_CMD_DISABLE;
1.1.1.2 ! misho    1596:   proto_set_message(p, (char *) arg, -1);
1.1       misho    1597:   proto_rethink_goal(p);
                   1598:   cli_msg(-9, "%s: disabled", p->name);
                   1599: }
                   1600: 
                   1601: void
1.1.1.2 ! misho    1602: proto_cmd_enable(struct proto *p, uintptr_t arg, int cnt UNUSED)
1.1       misho    1603: {
                   1604:   if (!p->disabled)
                   1605:     {
                   1606:       cli_msg(-10, "%s: already enabled", p->name);
                   1607:       return;
                   1608:     }
                   1609: 
                   1610:   log(L_INFO "Enabling protocol %s", p->name);
                   1611:   p->disabled = 0;
1.1.1.2 ! misho    1612:   proto_set_message(p, (char *) arg, -1);
1.1       misho    1613:   proto_rethink_goal(p);
                   1614:   cli_msg(-11, "%s: enabled", p->name);
                   1615: }
                   1616: 
                   1617: void
1.1.1.2 ! misho    1618: proto_cmd_restart(struct proto *p, uintptr_t arg, int cnt UNUSED)
1.1       misho    1619: {
                   1620:   if (p->disabled)
                   1621:     {
                   1622:       cli_msg(-8, "%s: already disabled", p->name);
                   1623:       return;
                   1624:     }
                   1625: 
                   1626:   log(L_INFO "Restarting protocol %s", p->name);
                   1627:   p->disabled = 1;
                   1628:   p->down_code = PDC_CMD_RESTART;
1.1.1.2 ! misho    1629:   proto_set_message(p, (char *) arg, -1);
1.1       misho    1630:   proto_rethink_goal(p);
                   1631:   p->disabled = 0;
                   1632:   proto_rethink_goal(p);
                   1633:   cli_msg(-12, "%s: restarted", p->name);
                   1634: }
                   1635: 
                   1636: void
1.1.1.2 ! misho    1637: proto_cmd_reload(struct proto *p, uintptr_t dir, int cnt UNUSED)
1.1       misho    1638: {
                   1639:   if (p->disabled)
                   1640:     {
                   1641:       cli_msg(-8, "%s: already disabled", p->name);
                   1642:       return;
                   1643:     }
                   1644: 
                   1645:   /* If the protocol in not UP, it has no routes */
                   1646:   if (p->proto_state != PS_UP)
                   1647:     return;
                   1648: 
                   1649:   log(L_INFO "Reloading protocol %s", p->name);
                   1650: 
                   1651:   /* re-importing routes */
                   1652:   if (dir != CMD_RELOAD_OUT)
                   1653:     {
                   1654:       if (! (p->reload_routes && p->reload_routes(p)))
                   1655:        {
                   1656:          cli_msg(-8006, "%s: reload failed", p->name);
                   1657:          return;
                   1658:        }
                   1659: 
                   1660:       /*
                   1661:        * Should be done before reload_routes() hook?
                   1662:        * Perhaps, but these hooks work asynchronously.
                   1663:        */
                   1664:       if (!p->proto->multitable)
                   1665:        {
                   1666:          proto_reset_limit(p->main_ahook->rx_limit);
                   1667:          proto_reset_limit(p->main_ahook->in_limit);
                   1668:        }
                   1669:     }
                   1670: 
                   1671:   /* re-exporting routes */
                   1672:   if (dir != CMD_RELOAD_IN)
                   1673:     proto_request_feeding(p);
                   1674: 
                   1675:   cli_msg(-15, "%s: reloading", p->name);
                   1676: }
                   1677: 
                   1678: void
1.1.1.2 ! misho    1679: proto_cmd_debug(struct proto *p, uintptr_t mask, int cnt UNUSED)
1.1       misho    1680: {
                   1681:   p->debug = mask;
                   1682: }
                   1683: 
                   1684: void
1.1.1.2 ! misho    1685: proto_cmd_mrtdump(struct proto *p, uintptr_t mask, int cnt UNUSED)
1.1       misho    1686: {
                   1687:   p->mrtdump = mask;
                   1688: }
                   1689: 
                   1690: static void
1.1.1.2 ! misho    1691: proto_apply_cmd_symbol(struct symbol *s, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
1.1       misho    1692: {
                   1693:   if (s->class != SYM_PROTO)
                   1694:     {
                   1695:       cli_msg(9002, "%s is not a protocol", s->name);
                   1696:       return;
                   1697:     }
                   1698: 
                   1699:   cmd(((struct proto_config *)s->def)->proto, arg, 0);
                   1700:   cli_msg(0, "");
                   1701: }
                   1702: 
                   1703: static void
1.1.1.2 ! misho    1704: proto_apply_cmd_patt(char *patt, void (* cmd)(struct proto *, uintptr_t, int), uintptr_t arg)
1.1       misho    1705: {
                   1706:   int cnt = 0;
                   1707: 
                   1708:   node *nn;
                   1709:   WALK_LIST(nn, proto_list)
                   1710:     {
                   1711:       struct proto *p = SKIP_BACK(struct proto, glob_node, nn);
                   1712: 
                   1713:       if (!patt || patmatch(patt, p->name))
                   1714:        cmd(p, arg, cnt++);
                   1715:     }
                   1716: 
                   1717:   if (!cnt)
                   1718:     cli_msg(8003, "No protocols match");
                   1719:   else
                   1720:     cli_msg(0, "");
                   1721: }
                   1722: 
                   1723: void
1.1.1.2 ! misho    1724: proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int),
        !          1725:                int restricted, uintptr_t arg)
1.1       misho    1726: {
                   1727:   if (restricted && cli_access_restricted())
                   1728:     return;
                   1729: 
                   1730:   if (ps.patt)
                   1731:     proto_apply_cmd_patt(ps.ptr, cmd, arg);
                   1732:   else
                   1733:     proto_apply_cmd_symbol(ps.ptr, cmd, arg);
                   1734: }
                   1735: 
                   1736: struct proto *
                   1737: proto_get_named(struct symbol *sym, struct protocol *pr)
                   1738: {
                   1739:   struct proto *p, *q;
                   1740: 
                   1741:   if (sym)
                   1742:     {
                   1743:       if (sym->class != SYM_PROTO)
                   1744:        cf_error("%s: Not a protocol", sym->name);
                   1745:       p = ((struct proto_config *)sym->def)->proto;
                   1746:       if (!p || p->proto != pr)
                   1747:        cf_error("%s: Not a %s protocol", sym->name, pr->name);
                   1748:     }
                   1749:   else
                   1750:     {
                   1751:       p = NULL;
                   1752:       WALK_LIST(q, active_proto_list)
                   1753:        if (q->proto == pr)
                   1754:          {
                   1755:            if (p)
                   1756:              cf_error("There are multiple %s protocols running", pr->name);
                   1757:            p = q;
                   1758:          }
                   1759:       if (!p)
                   1760:        cf_error("There is no %s protocol running", pr->name);
                   1761:     }
                   1762:   return p;
                   1763: }

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