Annotation of embedaddon/bird/proto/ospf/neighbor.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  *     BIRD -- OSPF
                      3:  *
                      4:  *     (c) 1999--2004 Ondrej Filip <feela@network.cz>
                      5:  *     (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
                      6:  *     (c) 2009--2014 CZ.NIC z.s.p.o.
                      7:  *
                      8:  *     Can be freely distributed and used under the terms of the GNU GPL.
                      9:  */
                     10: 
                     11: #include "ospf.h"
                     12: 
                     13: 
                     14: const char *ospf_ns_names[] = {
                     15:   "Down", "Attempt", "Init", "2-Way", "ExStart", "Exchange", "Loading", "Full"
                     16: };
                     17: 
                     18: const char *ospf_inm_names[] = {
                     19:   "HelloReceived", "Start", "2-WayReceived", "NegotiationDone", "ExchangeDone",
                     20:   "BadLSReq", "LoadingDone", "AdjOK?", "SeqNumberMismatch", "1-WayReceived",
                     21:   "KillNbr", "InactivityTimer", "LLDown"
                     22: };
                     23: 
                     24: 
                     25: static int can_do_adj(struct ospf_neighbor *n);
                     26: static void inactivity_timer_hook(timer * timer);
                     27: static void dbdes_timer_hook(timer *t);
                     28: static void lsrq_timer_hook(timer *t);
                     29: static void lsrt_timer_hook(timer *t);
                     30: static void ackd_timer_hook(timer *t);
                     31: 
                     32: 
                     33: static void
                     34: init_lists(struct ospf_proto *p, struct ospf_neighbor *n)
                     35: {
                     36:   s_init_list(&(n->lsrql));
                     37:   n->lsrqi = SHEAD(n->lsrql);
                     38:   n->lsrqh = ospf_top_new(p, n->pool);
                     39: 
                     40:   s_init_list(&(n->lsrtl));
                     41:   n->lsrth = ospf_top_new(p, n->pool);
                     42: }
                     43: 
                     44: static void
                     45: release_lsrtl(struct ospf_proto *p, struct ospf_neighbor *n)
                     46: {
                     47:   struct top_hash_entry *ret, *en;
                     48: 
                     49:   WALK_SLIST(ret, n->lsrtl)
                     50:   {
                     51:     en = ospf_hash_find_entry(p->gr, ret);
                     52:     if (en)
                     53:       en->ret_count--;
                     54:   }
                     55: }
                     56: 
                     57: /* Resets LSA request and retransmit lists.
                     58:  * We do not reset DB summary list iterator here,
                     59:  * it is reset during entering EXCHANGE state.
                     60:  */
                     61: static void
                     62: reset_lists(struct ospf_proto *p, struct ospf_neighbor *n)
                     63: {
                     64:   release_lsrtl(p, n);
                     65:   ospf_top_free(n->lsrqh);
                     66:   ospf_top_free(n->lsrth);
                     67:   ospf_reset_lsack_queue(n);
                     68: 
                     69:   tm_stop(n->dbdes_timer);
                     70:   tm_stop(n->lsrq_timer);
                     71:   tm_stop(n->lsrt_timer);
                     72:   tm_stop(n->ackd_timer);
                     73: 
                     74:   init_lists(p, n);
                     75: }
                     76: 
                     77: struct ospf_neighbor *
                     78: ospf_neighbor_new(struct ospf_iface *ifa)
                     79: {
                     80:   struct ospf_proto *p = ifa->oa->po;
                     81:   struct pool *pool = rp_new(p->p.pool, "OSPF Neighbor");
                     82:   struct ospf_neighbor *n = mb_allocz(pool, sizeof(struct ospf_neighbor));
                     83: 
                     84:   n->pool = pool;
                     85:   n->ifa = ifa;
                     86:   add_tail(&ifa->neigh_list, NODE n);
                     87:   n->adj = 0;
                     88:   n->csn = 0;
                     89:   n->state = NEIGHBOR_DOWN;
                     90: 
                     91:   init_lists(p, n);
                     92:   s_init(&(n->dbsi), &(p->lsal));
                     93: 
                     94:   init_list(&n->ackl[ACKL_DIRECT]);
                     95:   init_list(&n->ackl[ACKL_DELAY]);
                     96: 
                     97:   n->inactim = tm_new_set(pool, inactivity_timer_hook, n, 0, 0);
                     98:   n->dbdes_timer = tm_new_set(pool, dbdes_timer_hook, n, 0, ifa->rxmtint);
                     99:   n->lsrq_timer = tm_new_set(pool, lsrq_timer_hook, n, 0, ifa->rxmtint);
                    100:   n->lsrt_timer = tm_new_set(pool, lsrt_timer_hook, n, 0, ifa->rxmtint);
                    101:   n->ackd_timer = tm_new_set(pool, ackd_timer_hook, n, 0, ifa->rxmtint / 2);
                    102: 
                    103:   return (n);
                    104: }
                    105: 
                    106: static void
                    107: ospf_neigh_down(struct ospf_neighbor *n)
                    108: {
                    109:   struct ospf_iface *ifa = n->ifa;
                    110:   struct ospf_proto *p = ifa->oa->po;
                    111:   u32 rid = n->rid;
                    112: 
                    113:   if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
                    114:   {
                    115:     struct nbma_node *nn = find_nbma_node(ifa, n->ip);
                    116:     if (nn)
                    117:       nn->found = 0;
                    118:   }
                    119: 
                    120:   s_get(&(n->dbsi));
                    121:   release_lsrtl(p, n);
                    122:   rem_node(NODE n);
                    123:   rfree(n->pool);
                    124: 
                    125:   OSPF_TRACE(D_EVENTS, "Neighbor %R on %s removed", rid, ifa->ifname);
                    126: }
                    127: 
                    128: /**
                    129:  * ospf_neigh_chstate - handles changes related to new or lod state of neighbor
                    130:  * @n: OSPF neighbor
                    131:  * @state: new state
                    132:  *
                    133:  * Many actions have to be taken acording to a change of state of a neighbor. It
                    134:  * starts rxmt timers, call interface state machine etc.
                    135:  */
                    136: static void
                    137: ospf_neigh_chstate(struct ospf_neighbor *n, u8 state)
                    138: {
                    139:   struct ospf_iface *ifa = n->ifa;
                    140:   struct ospf_proto *p = ifa->oa->po;
                    141:   u8 old_state = n->state;
                    142:   int old_fadj = ifa->fadj;
                    143: 
                    144:   if (state == old_state)
                    145:     return;
                    146: 
                    147:   OSPF_TRACE(D_EVENTS, "Neighbor %R on %s changed state from %s to %s",
                    148:             n->rid, ifa->ifname, ospf_ns_names[old_state], ospf_ns_names[state]);
                    149: 
                    150:   n->state = state;
                    151: 
                    152:   /* Increase number of partial adjacencies */
                    153:   if ((state == NEIGHBOR_EXCHANGE) || (state == NEIGHBOR_LOADING))
                    154:     p->padj++;
                    155: 
                    156:   /* Decrease number of partial adjacencies */
                    157:   if ((old_state == NEIGHBOR_EXCHANGE) || (old_state == NEIGHBOR_LOADING))
                    158:     p->padj--;
                    159: 
                    160:   /* Increase number of full adjacencies */
                    161:   if (state == NEIGHBOR_FULL)
                    162:     ifa->fadj++;
                    163: 
                    164:   /* Decrease number of full adjacencies */
                    165:   if (old_state == NEIGHBOR_FULL)
                    166:     ifa->fadj--;
                    167: 
                    168:   if (ifa->fadj != old_fadj)
                    169:   {
                    170:     /* RFC 2328 12.4 Event 4 - neighbor enters/leaves Full state */
                    171:     ospf_notify_rt_lsa(ifa->oa);
                    172:     ospf_notify_net_lsa(ifa);
                    173: 
                    174:     /* RFC 2328 12.4 Event 8 - vlink state change */
                    175:     if (ifa->type == OSPF_IT_VLINK)
                    176:       ospf_notify_rt_lsa(ifa->voa);
                    177:   }
                    178: 
                    179:   if (state == NEIGHBOR_EXSTART)
                    180:   {
                    181:     /* First time adjacency */
                    182:     if (n->adj == 0)
                    183:       n->dds = random_u32();
                    184: 
                    185:     n->dds++;
                    186:     n->myimms = DBDES_IMMS;
                    187: 
                    188:     tm_start(n->dbdes_timer, 0);
                    189:     tm_start(n->ackd_timer, ifa->rxmtint / 2);
                    190:   }
                    191: 
                    192:   if (state > NEIGHBOR_EXSTART)
                    193:     n->myimms &= ~DBDES_I;
                    194: 
                    195:   /* Generate NeighborChange event if needed, see RFC 2328 9.2 */
                    196:   if ((state == NEIGHBOR_2WAY) && (old_state < NEIGHBOR_2WAY))
                    197:     ospf_iface_sm(ifa, ISM_NEICH);
                    198:   if ((state < NEIGHBOR_2WAY) && (old_state >= NEIGHBOR_2WAY))
                    199:     ospf_iface_sm(ifa, ISM_NEICH);
                    200: }
                    201: 
                    202: /**
                    203:  * ospf_neigh_sm - ospf neighbor state machine
                    204:  * @n: neighor
                    205:  * @event: actual event
                    206:  *
                    207:  * This part implements the neighbor state machine as described in 10.3 of
                    208:  * RFC 2328. The only difference is that state %NEIGHBOR_ATTEMPT is not
                    209:  * used. We discover neighbors on nonbroadcast networks in the
                    210:  * same way as on broadcast networks. The only difference is in
                    211:  * sending hello packets. These are sent to IPs listed in
                    212:  * @ospf_iface->nbma_list .
                    213:  */
                    214: void
                    215: ospf_neigh_sm(struct ospf_neighbor *n, int event)
                    216: {
                    217:   struct ospf_proto *p = n->ifa->oa->po;
                    218: 
                    219:   DBG("Neighbor state machine for %R on %s, event %s\n",
                    220:       n->rid, n->ifa->ifname, ospf_inm_names[event]);
                    221: 
                    222:   switch (event)
                    223:   {
                    224:   case INM_START:
                    225:     ospf_neigh_chstate(n, NEIGHBOR_ATTEMPT);
                    226:     /* NBMA are used different way */
                    227:     break;
                    228: 
                    229:   case INM_HELLOREC:
                    230:     if (n->state < NEIGHBOR_INIT)
                    231:       ospf_neigh_chstate(n, NEIGHBOR_INIT);
                    232: 
                    233:     /* Restart inactivity timer */
                    234:     tm_start(n->inactim, n->ifa->deadint);
                    235:     break;
                    236: 
                    237:   case INM_2WAYREC:
                    238:     if (n->state < NEIGHBOR_2WAY)
                    239:       ospf_neigh_chstate(n, NEIGHBOR_2WAY);
                    240:     if ((n->state == NEIGHBOR_2WAY) && can_do_adj(n))
                    241:       ospf_neigh_chstate(n, NEIGHBOR_EXSTART);
                    242:     break;
                    243: 
                    244:   case INM_NEGDONE:
                    245:     if (n->state == NEIGHBOR_EXSTART)
                    246:     {
                    247:       ospf_neigh_chstate(n, NEIGHBOR_EXCHANGE);
                    248: 
                    249:       /* Reset DB summary list iterator */
                    250:       s_get(&(n->dbsi));
                    251:       s_init(&(n->dbsi), &p->lsal);
                    252: 
                    253:       /* Add MaxAge LSA entries to retransmission list */
                    254:       ospf_add_flushed_to_lsrt(p, n);
                    255:     }
                    256:     else
                    257:       bug("NEGDONE and I'm not in EXSTART?");
                    258:     break;
                    259: 
                    260:   case INM_EXDONE:
                    261:     if (!EMPTY_SLIST(n->lsrql))
                    262:       ospf_neigh_chstate(n, NEIGHBOR_LOADING);
                    263:     else
                    264:       ospf_neigh_chstate(n, NEIGHBOR_FULL);
                    265:     break;
                    266: 
                    267:   case INM_LOADDONE:
                    268:     ospf_neigh_chstate(n, NEIGHBOR_FULL);
                    269:     break;
                    270: 
                    271:   case INM_ADJOK:
                    272:     /* Can In build adjacency? */
                    273:     if ((n->state == NEIGHBOR_2WAY) && can_do_adj(n))
                    274:     {
                    275:       ospf_neigh_chstate(n, NEIGHBOR_EXSTART);
                    276:     }
                    277:     else if ((n->state >= NEIGHBOR_EXSTART) && !can_do_adj(n))
                    278:     {
                    279:       reset_lists(p, n);
                    280:       ospf_neigh_chstate(n, NEIGHBOR_2WAY);
                    281:     }
                    282:     break;
                    283: 
                    284:   case INM_SEQMIS:
                    285:   case INM_BADLSREQ:
                    286:     if (n->state >= NEIGHBOR_EXCHANGE)
                    287:     {
                    288:       reset_lists(p, n);
                    289:       ospf_neigh_chstate(n, NEIGHBOR_EXSTART);
                    290:     }
                    291:     break;
                    292: 
                    293:   case INM_KILLNBR:
                    294:   case INM_LLDOWN:
                    295:   case INM_INACTTIM:
                    296:     /* No need for reset_lists() */
                    297:     ospf_neigh_chstate(n, NEIGHBOR_DOWN);
                    298:     ospf_neigh_down(n);
                    299:     break;
                    300: 
                    301:   case INM_1WAYREC:
                    302:     reset_lists(p, n);
                    303:     ospf_neigh_chstate(n, NEIGHBOR_INIT);
                    304:     break;
                    305: 
                    306:   default:
                    307:     bug("%s: INM - Unknown event?", p->p.name);
                    308:     break;
                    309:   }
                    310: }
                    311: 
                    312: static int
                    313: can_do_adj(struct ospf_neighbor *n)
                    314: {
                    315:   struct ospf_iface *ifa = n->ifa;
                    316:   struct ospf_proto *p = ifa->oa->po;
                    317:   int i = 0;
                    318: 
                    319:   switch (ifa->type)
                    320:   {
                    321:   case OSPF_IT_PTP:
                    322:   case OSPF_IT_PTMP:
                    323:   case OSPF_IT_VLINK:
                    324:     i = 1;
                    325:     break;
                    326:   case OSPF_IT_BCAST:
                    327:   case OSPF_IT_NBMA:
                    328:     switch (ifa->state)
                    329:     {
                    330:     case OSPF_IS_DOWN:
                    331:     case OSPF_IS_LOOP:
                    332:       bug("%s: Iface %s in down state?", p->p.name, ifa->ifname);
                    333:       break;
                    334:     case OSPF_IS_WAITING:
                    335:       DBG("%s: Neighbor? on iface %s\n", p->p.name, ifa->ifname);
                    336:       break;
                    337:     case OSPF_IS_DROTHER:
                    338:       if (((n->rid == ifa->drid) || (n->rid == ifa->bdrid))
                    339:          && (n->state >= NEIGHBOR_2WAY))
                    340:        i = 1;
                    341:       break;
                    342:     case OSPF_IS_PTP:
                    343:     case OSPF_IS_BACKUP:
                    344:     case OSPF_IS_DR:
                    345:       if (n->state >= NEIGHBOR_2WAY)
                    346:        i = 1;
                    347:       break;
                    348:     default:
                    349:       bug("%s: Iface %s in unknown state?", p->p.name, ifa->ifname);
                    350:       break;
                    351:     }
                    352:     break;
                    353:   default:
                    354:     bug("%s: Iface %s is unknown type?", p->p.name, ifa->ifname);
                    355:     break;
                    356:   }
                    357:   DBG("%s: Iface %s can_do_adj=%d\n", p->p.name, ifa->ifname, i);
                    358:   return i;
                    359: }
                    360: 
                    361: 
                    362: static inline u32 neigh_get_id(struct ospf_proto *p UNUSED4 UNUSED6, struct ospf_neighbor *n)
                    363: { return ospf_is_v2(p) ? ipa_to_u32(n->ip) : n->rid; }
                    364: 
                    365: static struct ospf_neighbor *
                    366: elect_bdr(struct ospf_proto *p, list nl)
                    367: {
                    368:   struct ospf_neighbor *neigh, *n1, *n2;
                    369:   u32 nid;
                    370: 
                    371:   n1 = NULL;
                    372:   n2 = NULL;
                    373:   WALK_LIST(neigh, nl)                 /* First try those decl. themselves */
                    374:   {
                    375:     nid = neigh_get_id(p, neigh);
                    376: 
                    377:     if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */
                    378:       if (neigh->priority > 0)         /* Eligible */
                    379:        if (neigh->dr != nid)           /* And not decl. itself DR */
                    380:        {
                    381:          if (neigh->bdr == nid)        /* Declaring BDR */
                    382:          {
                    383:            if (n1 != NULL)
                    384:            {
                    385:              if (neigh->priority > n1->priority)
                    386:                n1 = neigh;
                    387:              else if (neigh->priority == n1->priority)
                    388:                if (neigh->rid > n1->rid)
                    389:                  n1 = neigh;
                    390:            }
                    391:            else
                    392:            {
                    393:              n1 = neigh;
                    394:            }
                    395:          }
                    396:          else                  /* And NOT declaring BDR */
                    397:          {
                    398:            if (n2 != NULL)
                    399:            {
                    400:              if (neigh->priority > n2->priority)
                    401:                n2 = neigh;
                    402:              else if (neigh->priority == n2->priority)
                    403:                if (neigh->rid > n2->rid)
                    404:                  n2 = neigh;
                    405:            }
                    406:            else
                    407:            {
                    408:              n2 = neigh;
                    409:            }
                    410:          }
                    411:        }
                    412:   }
                    413:   if (n1 == NULL)
                    414:     n1 = n2;
                    415: 
                    416:   return (n1);
                    417: }
                    418: 
                    419: static struct ospf_neighbor *
                    420: elect_dr(struct ospf_proto *p, list nl)
                    421: {
                    422:   struct ospf_neighbor *neigh, *n;
                    423:   u32 nid;
                    424: 
                    425:   n = NULL;
                    426:   WALK_LIST(neigh, nl)                 /* And now DR */
                    427:   {
                    428:     nid = neigh_get_id(p, neigh);
                    429: 
                    430:     if (neigh->state >= NEIGHBOR_2WAY) /* Higher than 2WAY */
                    431:       if (neigh->priority > 0)         /* Eligible */
                    432:        if (neigh->dr == nid)           /* And declaring itself DR */
                    433:        {
                    434:          if (n != NULL)
                    435:          {
                    436:            if (neigh->priority > n->priority)
                    437:              n = neigh;
                    438:            else if (neigh->priority == n->priority)
                    439:              if (neigh->rid > n->rid)
                    440:                n = neigh;
                    441:          }
                    442:          else
                    443:          {
                    444:            n = neigh;
                    445:          }
                    446:        }
                    447:   }
                    448: 
                    449:   return (n);
                    450: }
                    451: 
                    452: /**
                    453:  * ospf_dr_election - (Backup) Designed Router election
                    454:  * @ifa: actual interface
                    455:  *
                    456:  * When the wait timer fires, it is time to elect (Backup) Designated Router.
                    457:  * Structure describing me is added to this list so every electing router has
                    458:  * the same list. Backup Designated Router is elected before Designated
                    459:  * Router. This process is described in 9.4 of RFC 2328. The function is
                    460:  * supposed to be called only from ospf_iface_sm() as a part of the interface
                    461:  * state machine.
                    462:  */
                    463: void
                    464: ospf_dr_election(struct ospf_iface *ifa)
                    465: {
                    466:   struct ospf_proto *p = ifa->oa->po;
                    467:   struct ospf_neighbor *neigh, *ndr, *nbdr, me;
                    468:   u32 myid = p->router_id;
                    469: 
                    470:   DBG("(B)DR election.\n");
                    471: 
                    472:   me.state = NEIGHBOR_2WAY;
                    473:   me.rid = myid;
                    474:   me.priority = ifa->priority;
                    475:   me.ip = ifa->addr->ip;
                    476: 
                    477:   me.dr  = ospf_is_v2(p) ? ipa_to_u32(ifa->drip) : ifa->drid;
                    478:   me.bdr = ospf_is_v2(p) ? ipa_to_u32(ifa->bdrip) : ifa->bdrid;
                    479:   me.iface_id = ifa->iface_id;
                    480: 
                    481:   add_tail(&ifa->neigh_list, NODE & me);
                    482: 
                    483:   nbdr = elect_bdr(p, ifa->neigh_list);
                    484:   ndr = elect_dr(p, ifa->neigh_list);
                    485: 
                    486:   if (ndr == NULL)
                    487:     ndr = nbdr;
                    488: 
                    489:   /* 9.4. (4) */
                    490:   if (((ifa->drid == myid) && (ndr != &me))
                    491:       || ((ifa->drid != myid) && (ndr == &me))
                    492:       || ((ifa->bdrid == myid) && (nbdr != &me))
                    493:       || ((ifa->bdrid != myid) && (nbdr == &me)))
                    494:   {
                    495:     me.dr = ndr ? neigh_get_id(p, ndr) : 0;
                    496:     me.bdr = nbdr ? neigh_get_id(p, nbdr) : 0;
                    497: 
                    498:     nbdr = elect_bdr(p, ifa->neigh_list);
                    499:     ndr = elect_dr(p, ifa->neigh_list);
                    500: 
                    501:     if (ndr == NULL)
                    502:       ndr = nbdr;
                    503:   }
                    504: 
                    505:   rem_node(NODE & me);
                    506: 
                    507: 
                    508:   u32 old_drid = ifa->drid;
                    509:   u32 old_bdrid = ifa->bdrid;
                    510: 
                    511:   ifa->drid = ndr ? ndr->rid : 0;
                    512:   ifa->drip = ndr ? ndr->ip  : IPA_NONE;
                    513:   ifa->dr_iface_id = ndr ? ndr->iface_id : 0;
                    514: 
                    515:   ifa->bdrid = nbdr ? nbdr->rid : 0;
                    516:   ifa->bdrip = nbdr ? nbdr->ip  : IPA_NONE;
                    517: 
                    518:   DBG("DR=%R, BDR=%R\n", ifa->drid, ifa->bdrid);
                    519: 
                    520:   /* We are part of the interface state machine */
                    521:   if (ifa->drid == myid)
                    522:     ospf_iface_chstate(ifa, OSPF_IS_DR);
                    523:   else if (ifa->bdrid == myid)
                    524:     ospf_iface_chstate(ifa, OSPF_IS_BACKUP);
                    525:   else
                    526:     ospf_iface_chstate(ifa, OSPF_IS_DROTHER);
                    527: 
                    528:   /* Review neighbor adjacencies if DR or BDR changed */
                    529:   if ((ifa->drid != old_drid) || (ifa->bdrid != old_bdrid))
                    530:     WALK_LIST(neigh, ifa->neigh_list)
                    531:       if (neigh->state >= NEIGHBOR_2WAY)
                    532:        ospf_neigh_sm(neigh, INM_ADJOK);
                    533: 
                    534:   /* RFC 2328 12.4 Event 3 - DR change */
                    535:   if (ifa->drid != old_drid)
                    536:     ospf_notify_rt_lsa(ifa->oa);
                    537: }
                    538: 
                    539: struct ospf_neighbor *
                    540: find_neigh(struct ospf_iface *ifa, u32 rid)
                    541: {
                    542:   struct ospf_neighbor *n;
                    543:   WALK_LIST(n, ifa->neigh_list)
                    544:     if (n->rid == rid)
                    545:       return n;
                    546:   return NULL;
                    547: }
                    548: 
                    549: struct ospf_neighbor *
                    550: find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip)
                    551: {
                    552:   struct ospf_neighbor *n;
                    553:   WALK_LIST(n, ifa->neigh_list)
                    554:     if (ipa_equal(n->ip, ip))
                    555:       return n;
                    556:   return NULL;
                    557: }
                    558: 
                    559: static void
                    560: inactivity_timer_hook(timer * timer)
                    561: {
                    562:   struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data;
                    563:   struct ospf_proto *p = n->ifa->oa->po;
                    564: 
                    565:   OSPF_TRACE(D_EVENTS, "Inactivity timer expired for nbr %R on %s",
                    566:             n->rid, n->ifa->ifname);
                    567:   ospf_neigh_sm(n, INM_INACTTIM);
                    568: }
                    569: 
                    570: static void
                    571: ospf_neigh_bfd_hook(struct bfd_request *req)
                    572: {
                    573:   struct ospf_neighbor *n = req->data;
                    574:   struct ospf_proto *p = n->ifa->oa->po;
                    575: 
                    576:   if (req->down)
                    577:   {
                    578:     OSPF_TRACE(D_EVENTS, "BFD session down for nbr %R on %s",
                    579:               n->rid, n->ifa->ifname);
                    580:     ospf_neigh_sm(n, INM_INACTTIM);
                    581:   }
                    582: }
                    583: 
                    584: void
                    585: ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd)
                    586: {
1.1.1.2 ! misho     587:   struct ospf_proto *p = n->ifa->oa->po;
        !           588: 
1.1       misho     589:   if (use_bfd && !n->bfd_req)
1.1.1.2 ! misho     590:     n->bfd_req = bfd_request_session(n->pool, n->ip, n->ifa->addr->ip,
        !           591:                                     n->ifa->iface, p->p.vrf,
1.1       misho     592:                                     ospf_neigh_bfd_hook, n);
                    593: 
                    594:   if (!use_bfd && n->bfd_req)
                    595:   {
                    596:     rfree(n->bfd_req);
                    597:     n->bfd_req = NULL;
                    598:   }
                    599: }
                    600: 
                    601: 
                    602: static void
                    603: dbdes_timer_hook(timer *t)
                    604: {
                    605:   struct ospf_neighbor *n = t->data;
                    606:   struct ospf_proto *p = n->ifa->oa->po;
                    607: 
                    608:   // OSPF_TRACE(D_EVENTS, "DBDES timer expired for nbr %R on %s", n->rid, n->ifa->ifname);
                    609: 
                    610:   if (n->state == NEIGHBOR_EXSTART)
                    611:     ospf_send_dbdes(p, n);
                    612: 
                    613:   if ((n->state == NEIGHBOR_EXCHANGE) && (n->myimms & DBDES_MS))
                    614:     ospf_rxmt_dbdes(p, n);
                    615: }
                    616: 
                    617: static void
                    618: lsrq_timer_hook(timer *t)
                    619: {
                    620:   struct ospf_neighbor *n = t->data;
                    621:   struct ospf_proto *p = n->ifa->oa->po;
                    622: 
                    623:   // OSPF_TRACE(D_EVENTS, "LSRQ timer expired for nbr %R on %s", n->rid, n->ifa->ifname);
                    624: 
                    625:   if ((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrql))
                    626:     ospf_send_lsreq(p, n);
                    627: }
                    628: 
                    629: static void
                    630: lsrt_timer_hook(timer *t)
                    631: {
                    632:   struct ospf_neighbor *n = t->data;
                    633:   struct ospf_proto *p = n->ifa->oa->po;
                    634: 
                    635:   // OSPF_TRACE(D_EVENTS, "LSRT timer expired for nbr %R on %s", n->rid, n->ifa->ifname);
                    636: 
                    637:   if ((n->state >= NEIGHBOR_EXCHANGE) && !EMPTY_SLIST(n->lsrtl))
                    638:     ospf_rxmt_lsupd(p, n);
                    639: }
                    640: 
                    641: static void
                    642: ackd_timer_hook(timer *t)
                    643: {
                    644:   struct ospf_neighbor *n = t->data;
                    645:   struct ospf_proto *p = n->ifa->oa->po;
                    646: 
                    647:   ospf_send_lsack(p, n, ACKL_DELAY);
                    648: }
                    649: 
                    650: 
                    651: void
                    652: ospf_sh_neigh_info(struct ospf_neighbor *n)
                    653: {
                    654:   struct ospf_iface *ifa = n->ifa;
                    655:   char *pos = "PtP  ";
                    656:   char etime[6];
                    657:   int exp, sec, min;
                    658: 
                    659:   exp = n->inactim->expires - now;
                    660:   sec = exp % 60;
                    661:   min = exp / 60;
                    662:   if (min > 59)
                    663:   {
                    664:     bsprintf(etime, "-Inf-");
                    665:   }
                    666:   else
                    667:   {
                    668:     bsprintf(etime, "%02u:%02u", min, sec);
                    669:   }
                    670: 
                    671:   if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA))
                    672:   {
                    673:     if (n->rid == ifa->drid)
                    674:       pos = "DR   ";
                    675:     else if (n->rid == ifa->bdrid)
                    676:       pos = "BDR  ";
                    677:     else
                    678:       pos = "Other";
                    679:   }
                    680: 
                    681:   cli_msg(-1013, "%-1R\t%3u\t%s/%s\t%-5s\t%-10s %-1I", n->rid, n->priority,
                    682:          ospf_ns_names[n->state], pos, etime, ifa->ifname, n->ip);
                    683: }

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