Annotation of embedaddon/quagga/ospf6d/ospf6_neighbor.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2003 Yasuhiro Ohara
                      3:  *
                      4:  * This file is part of GNU Zebra.
                      5:  *
                      6:  * GNU Zebra is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2, or (at your option) any
                      9:  * later version.
                     10:  *
                     11:  * GNU Zebra is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU General Public License
                     17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
                     18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
                     19:  * Boston, MA 02111-1307, USA.  
                     20:  */
                     21: 
                     22: #include <zebra.h>
                     23: 
                     24: #include "log.h"
                     25: #include "memory.h"
                     26: #include "thread.h"
                     27: #include "linklist.h"
                     28: #include "vty.h"
                     29: #include "command.h"
                     30: 
                     31: #include "ospf6_proto.h"
                     32: #include "ospf6_lsa.h"
                     33: #include "ospf6_lsdb.h"
                     34: #include "ospf6_message.h"
                     35: #include "ospf6_top.h"
                     36: #include "ospf6_area.h"
                     37: #include "ospf6_interface.h"
                     38: #include "ospf6_neighbor.h"
                     39: #include "ospf6_intra.h"
                     40: #include "ospf6_flood.h"
                     41: #include "ospf6d.h"
                     42: 
                     43: unsigned char conf_debug_ospf6_neighbor = 0;
                     44: 
                     45: const char *ospf6_neighbor_state_str[] =
                     46: { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
                     47:   "Loading", "Full", NULL };
                     48: 
                     49: int
                     50: ospf6_neighbor_cmp (void *va, void *vb)
                     51: {
                     52:   struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
                     53:   struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
                     54:   return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);
                     55: }
                     56: 
                     57: struct ospf6_neighbor *
                     58: ospf6_neighbor_lookup (u_int32_t router_id,
                     59:                        struct ospf6_interface *oi)
                     60: {
                     61:   struct listnode *n;
                     62:   struct ospf6_neighbor *on;
                     63: 
                     64:   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, n, on))
                     65:     if (on->router_id == router_id)
                     66:       return on;
                     67:   
                     68:   return (struct ospf6_neighbor *) NULL;
                     69: }
                     70: 
                     71: /* create ospf6_neighbor */
                     72: struct ospf6_neighbor *
                     73: ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
                     74: {
                     75:   struct ospf6_neighbor *on;
                     76:   char buf[16];
                     77: 
                     78:   on = (struct ospf6_neighbor *)
                     79:     XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
                     80:   if (on == NULL)
                     81:     {
                     82:       zlog_warn ("neighbor: malloc failed");
                     83:       return NULL;
                     84:     }
                     85: 
                     86:   memset (on, 0, sizeof (struct ospf6_neighbor));
                     87:   inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
                     88:   snprintf (on->name, sizeof (on->name), "%s%%%s",
                     89:             buf, oi->interface->name);
                     90:   on->ospf6_if = oi;
                     91:   on->state = OSPF6_NEIGHBOR_DOWN;
                     92:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
                     93:   on->router_id = router_id;
                     94: 
                     95:   on->summary_list = ospf6_lsdb_create (on);
                     96:   on->request_list = ospf6_lsdb_create (on);
                     97:   on->retrans_list = ospf6_lsdb_create (on);
                     98: 
                     99:   on->dbdesc_list = ospf6_lsdb_create (on);
                    100:   on->lsreq_list = ospf6_lsdb_create (on);
                    101:   on->lsupdate_list = ospf6_lsdb_create (on);
                    102:   on->lsack_list = ospf6_lsdb_create (on);
                    103: 
                    104:   listnode_add_sort (oi->neighbor_list, on);
                    105:   return on;
                    106: }
                    107: 
                    108: void
                    109: ospf6_neighbor_delete (struct ospf6_neighbor *on)
                    110: {
                    111:   struct ospf6_lsa *lsa;
                    112: 
                    113:   ospf6_lsdb_remove_all (on->summary_list);
                    114:   ospf6_lsdb_remove_all (on->request_list);
                    115:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    116:        lsa = ospf6_lsdb_next (lsa))
                    117:     {
                    118:       ospf6_decrement_retrans_count (lsa);
                    119:       ospf6_lsdb_remove (lsa, on->retrans_list);
                    120:     }
                    121: 
                    122:   ospf6_lsdb_remove_all (on->dbdesc_list);
                    123:   ospf6_lsdb_remove_all (on->lsreq_list);
                    124:   ospf6_lsdb_remove_all (on->lsupdate_list);
                    125:   ospf6_lsdb_remove_all (on->lsack_list);
                    126: 
                    127:   ospf6_lsdb_delete (on->summary_list);
                    128:   ospf6_lsdb_delete (on->request_list);
                    129:   ospf6_lsdb_delete (on->retrans_list);
                    130: 
                    131:   ospf6_lsdb_delete (on->dbdesc_list);
                    132:   ospf6_lsdb_delete (on->lsreq_list);
                    133:   ospf6_lsdb_delete (on->lsupdate_list);
                    134:   ospf6_lsdb_delete (on->lsack_list);
                    135: 
                    136:   THREAD_OFF (on->inactivity_timer);
                    137: 
                    138:   THREAD_OFF (on->thread_send_dbdesc);
                    139:   THREAD_OFF (on->thread_send_lsreq);
                    140:   THREAD_OFF (on->thread_send_lsupdate);
                    141:   THREAD_OFF (on->thread_send_lsack);
                    142: 
                    143:   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
                    144: }
                    145: 
                    146: static void
                    147: ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on)
                    148: {
                    149:   u_char prev_state;
                    150: 
                    151:   prev_state = on->state;
                    152:   on->state = next_state;
                    153: 
                    154:   if (prev_state == next_state)
                    155:     return;
                    156: 
                    157:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
                    158: 
                    159:   /* log */
                    160:   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
                    161:     {
                    162:       zlog_debug ("Neighbor state change %s: [%s]->[%s]", on->name,
                    163:                  ospf6_neighbor_state_str[prev_state],
                    164:                  ospf6_neighbor_state_str[next_state]);
                    165:     }
                    166: 
                    167:   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
                    168:     {
                    169:       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
                    170:       if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
                    171:         {
                    172:           OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
                    173:           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
                    174:         }
                    175:       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
                    176:     }
                    177: 
                    178:   if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
                    179:        prev_state == OSPF6_NEIGHBOR_LOADING) &&
                    180:       (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
                    181:        next_state != OSPF6_NEIGHBOR_LOADING))
                    182:     ospf6_maxage_remove (on->ospf6_if->area->ospf6);
                    183: }
                    184: 
                    185: /* RFC2328 section 10.4 */
                    186: static int
                    187: need_adjacency (struct ospf6_neighbor *on)
                    188: {
                    189:   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
                    190:       on->ospf6_if->state == OSPF6_INTERFACE_DR ||
                    191:       on->ospf6_if->state == OSPF6_INTERFACE_BDR)
                    192:     return 1;
                    193: 
                    194:   if (on->ospf6_if->drouter == on->router_id ||
                    195:       on->ospf6_if->bdrouter == on->router_id)
                    196:     return 1;
                    197: 
                    198:   return 0;
                    199: }
                    200: 
                    201: int
                    202: hello_received (struct thread *thread)
                    203: {
                    204:   struct ospf6_neighbor *on;
                    205: 
                    206:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    207:   assert (on);
                    208: 
                    209:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    210:     zlog_debug ("Neighbor Event %s: *HelloReceived*", on->name);
                    211: 
                    212:   /* reset Inactivity Timer */
                    213:   THREAD_OFF (on->inactivity_timer);
                    214:   on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
                    215:                                            on->ospf6_if->dead_interval);
                    216: 
                    217:   if (on->state <= OSPF6_NEIGHBOR_DOWN)
                    218:     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
                    219: 
                    220:   return 0;
                    221: }
                    222: 
                    223: int
                    224: twoway_received (struct thread *thread)
                    225: {
                    226:   struct ospf6_neighbor *on;
                    227: 
                    228:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    229:   assert (on);
                    230: 
                    231:   if (on->state > OSPF6_NEIGHBOR_INIT)
                    232:     return 0;
                    233: 
                    234:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    235:     zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name);
                    236: 
                    237:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
                    238: 
                    239:   if (! need_adjacency (on))
                    240:     {
                    241:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
                    242:       return 0;
                    243:     }
                    244: 
                    245:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
                    246:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
                    247:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
                    248:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
                    249: 
                    250:   THREAD_OFF (on->thread_send_dbdesc);
                    251:   on->thread_send_dbdesc =
                    252:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    253: 
                    254:   return 0;
                    255: }
                    256: 
                    257: int
                    258: negotiation_done (struct thread *thread)
                    259: {
                    260:   struct ospf6_neighbor *on;
                    261:   struct ospf6_lsa *lsa;
                    262: 
                    263:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    264:   assert (on);
                    265: 
                    266:   if (on->state != OSPF6_NEIGHBOR_EXSTART)
                    267:     return 0;
                    268: 
                    269:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    270:     zlog_debug ("Neighbor Event %s: *NegotiationDone*", on->name);
                    271: 
                    272:   /* clear ls-list */
                    273:   ospf6_lsdb_remove_all (on->summary_list);
                    274:   ospf6_lsdb_remove_all (on->request_list);
                    275:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    276:        lsa = ospf6_lsdb_next (lsa))
                    277:     {
                    278:       ospf6_decrement_retrans_count (lsa);
                    279:       ospf6_lsdb_remove (lsa, on->retrans_list);
                    280:     }
                    281: 
                    282:   /* Interface scoped LSAs */
                    283:   for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
                    284:        lsa = ospf6_lsdb_next (lsa))
                    285:     {
                    286:       if (OSPF6_LSA_IS_MAXAGE (lsa))
                    287:         {
                    288:           ospf6_increment_retrans_count (lsa);
                    289:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
                    290:         }
                    291:       else
                    292:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
                    293:     }
                    294: 
                    295:   /* Area scoped LSAs */
                    296:   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
                    297:        lsa = ospf6_lsdb_next (lsa))
                    298:     {
                    299:       if (OSPF6_LSA_IS_MAXAGE (lsa))
                    300:         {
                    301:           ospf6_increment_retrans_count (lsa);
                    302:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
                    303:         }
                    304:       else
                    305:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
                    306:     }
                    307: 
                    308:   /* AS scoped LSAs */
                    309:   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
                    310:        lsa = ospf6_lsdb_next (lsa))
                    311:     {
                    312:       if (OSPF6_LSA_IS_MAXAGE (lsa))
                    313:         {
                    314:           ospf6_increment_retrans_count (lsa);
                    315:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
                    316:         }
                    317:       else
                    318:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
                    319:     }
                    320: 
                    321:   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
                    322:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on);
                    323: 
                    324:   return 0;
                    325: }
                    326: 
                    327: int
                    328: exchange_done (struct thread *thread)
                    329: {
                    330:   struct ospf6_neighbor *on;
                    331: 
                    332:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    333:   assert (on);
                    334: 
                    335:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
                    336:     return 0;
                    337: 
                    338:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    339:     zlog_debug ("Neighbor Event %s: *ExchangeDone*", on->name);
                    340: 
                    341:   THREAD_OFF (on->thread_send_dbdesc);
                    342:   ospf6_lsdb_remove_all (on->dbdesc_list);
                    343: 
                    344: /* XXX
                    345:   thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
                    346:                     on->ospf6_if->dead_interval);
                    347: */
                    348: 
                    349:   if (on->request_list->count == 0)
                    350:     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
                    351:   else
                    352:     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on);
                    353: 
                    354:   return 0;
                    355: }
                    356: 
                    357: int
                    358: loading_done (struct thread *thread)
                    359: {
                    360:   struct ospf6_neighbor *on;
                    361: 
                    362:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    363:   assert (on);
                    364: 
                    365:   if (on->state != OSPF6_NEIGHBOR_LOADING)
                    366:     return 0;
                    367: 
                    368:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    369:     zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name);
                    370: 
                    371:   assert (on->request_list->count == 0);
                    372: 
                    373:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on);
                    374: 
                    375:   return 0;
                    376: }
                    377: 
                    378: int
                    379: adj_ok (struct thread *thread)
                    380: {
                    381:   struct ospf6_neighbor *on;
                    382:   struct ospf6_lsa *lsa;
                    383: 
                    384:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    385:   assert (on);
                    386: 
                    387:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    388:     zlog_debug ("Neighbor Event %s: *AdjOK?*", on->name);
                    389: 
                    390:   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
                    391:     {
                    392:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
                    393:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
                    394:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
                    395:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
                    396: 
                    397:       THREAD_OFF (on->thread_send_dbdesc);
                    398:       on->thread_send_dbdesc =
                    399:         thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    400: 
                    401:     }
                    402:   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
                    403:            ! need_adjacency (on))
                    404:     {
                    405:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on);
                    406:       ospf6_lsdb_remove_all (on->summary_list);
                    407:       ospf6_lsdb_remove_all (on->request_list);
                    408:       for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    409:            lsa = ospf6_lsdb_next (lsa))
                    410:         {
                    411:           ospf6_decrement_retrans_count (lsa);
                    412:           ospf6_lsdb_remove (lsa, on->retrans_list);
                    413:         }
                    414:     }
                    415: 
                    416:   return 0;
                    417: }
                    418: 
                    419: int
                    420: seqnumber_mismatch (struct thread *thread)
                    421: {
                    422:   struct ospf6_neighbor *on;
                    423:   struct ospf6_lsa *lsa;
                    424: 
                    425:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    426:   assert (on);
                    427: 
                    428:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
                    429:     return 0;
                    430: 
                    431:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    432:     zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
                    433: 
                    434:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
                    435:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
                    436:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
                    437:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
                    438: 
                    439:   ospf6_lsdb_remove_all (on->summary_list);
                    440:   ospf6_lsdb_remove_all (on->request_list);
                    441:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    442:        lsa = ospf6_lsdb_next (lsa))
                    443:     {
                    444:       ospf6_decrement_retrans_count (lsa);
                    445:       ospf6_lsdb_remove (lsa, on->retrans_list);
                    446:     }
                    447: 
                    448:   THREAD_OFF (on->thread_send_dbdesc);
                    449:   on->thread_send_dbdesc =
                    450:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    451: 
                    452:   return 0;
                    453: }
                    454: 
                    455: int
                    456: bad_lsreq (struct thread *thread)
                    457: {
                    458:   struct ospf6_neighbor *on;
                    459:   struct ospf6_lsa *lsa;
                    460: 
                    461:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    462:   assert (on);
                    463: 
                    464:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
                    465:     return 0;
                    466: 
                    467:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    468:     zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name);
                    469: 
                    470:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on);
                    471:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
                    472:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
                    473:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
                    474: 
                    475:   ospf6_lsdb_remove_all (on->summary_list);
                    476:   ospf6_lsdb_remove_all (on->request_list);
                    477:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    478:        lsa = ospf6_lsdb_next (lsa))
                    479:     {
                    480:       ospf6_decrement_retrans_count (lsa);
                    481:       ospf6_lsdb_remove (lsa, on->retrans_list);
                    482:     }
                    483: 
                    484:   THREAD_OFF (on->thread_send_dbdesc);
                    485:   on->thread_send_dbdesc =
                    486:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
                    487: 
                    488:   return 0;
                    489: }
                    490: 
                    491: int
                    492: oneway_received (struct thread *thread)
                    493: {
                    494:   struct ospf6_neighbor *on;
                    495:   struct ospf6_lsa *lsa;
                    496: 
                    497:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    498:   assert (on);
                    499: 
                    500:   if (on->state < OSPF6_NEIGHBOR_TWOWAY)
                    501:     return 0;
                    502: 
                    503:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    504:     zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name);
                    505: 
                    506:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on);
                    507:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
                    508: 
                    509:   ospf6_lsdb_remove_all (on->summary_list);
                    510:   ospf6_lsdb_remove_all (on->request_list);
                    511:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    512:        lsa = ospf6_lsdb_next (lsa))
                    513:     {
                    514:       ospf6_decrement_retrans_count (lsa);
                    515:       ospf6_lsdb_remove (lsa, on->retrans_list);
                    516:     }
                    517: 
                    518:   THREAD_OFF (on->thread_send_dbdesc);
                    519:   THREAD_OFF (on->thread_send_lsreq);
                    520:   THREAD_OFF (on->thread_send_lsupdate);
                    521:   THREAD_OFF (on->thread_send_lsack);
                    522: 
                    523:   return 0;
                    524: }
                    525: 
                    526: int
                    527: inactivity_timer (struct thread *thread)
                    528: {
                    529:   struct ospf6_neighbor *on;
                    530: 
                    531:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
                    532:   assert (on);
                    533: 
                    534:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    535:     zlog_debug ("Neighbor Event %s: *InactivityTimer*", on->name);
                    536: 
                    537:   on->inactivity_timer = NULL;
                    538:   on->drouter = on->prev_drouter = 0;
                    539:   on->bdrouter = on->prev_bdrouter = 0;
                    540: 
                    541:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on);
                    542:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
                    543: 
                    544:   listnode_delete (on->ospf6_if->neighbor_list, on);
                    545:   ospf6_neighbor_delete (on);
                    546: 
                    547:   return 0;
                    548: }
                    549: 
                    550: 
                    551: 
                    552: /* vty functions */
                    553: /* show neighbor structure */
                    554: static void
                    555: ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
                    556: {
                    557:   char router_id[16];
                    558:   char duration[16];
                    559:   struct timeval now, res;
                    560:   char nstate[16];
                    561:   char deadtime[16];
                    562:   long h, m, s;
                    563: 
                    564:   /* Router-ID (Name) */
                    565:   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
                    566: #ifdef HAVE_GETNAMEINFO
                    567:   {
                    568:   }
                    569: #endif /*HAVE_GETNAMEINFO*/
                    570: 
                    571:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                    572: 
                    573:   /* Dead time */
                    574:   h = m = s = 0;
                    575:   if (on->inactivity_timer)
                    576:     {
                    577:       s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec;
                    578:       h = s / 3600;
                    579:       s -= h * 3600;
                    580:       m = s / 60;
                    581:       s -= m * 60;
                    582:     }
                    583:   snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
                    584: 
                    585:   /* Neighbor State */
                    586:   if (if_is_pointopoint (on->ospf6_if->interface))
                    587:     snprintf (nstate, sizeof (nstate), "PointToPoint");
                    588:   else
                    589:     {
                    590:       if (on->router_id == on->drouter)
                    591:         snprintf (nstate, sizeof (nstate), "DR");
                    592:       else if (on->router_id == on->bdrouter)
                    593:         snprintf (nstate, sizeof (nstate), "BDR");
                    594:       else
                    595:         snprintf (nstate, sizeof (nstate), "DROther");
                    596:     }
                    597: 
                    598:   /* Duration */
                    599:   timersub (&now, &on->last_changed, &res);
                    600:   timerstring (&res, duration, sizeof (duration));
                    601: 
                    602:   /*
                    603:   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
                    604:            "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
                    605:            "I/F", "State", VNL);
                    606:   */
                    607: 
                    608:   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
                    609:            router_id, on->priority, deadtime,
                    610:            ospf6_neighbor_state_str[on->state], nstate, duration,
                    611:            on->ospf6_if->interface->name,
                    612:            ospf6_interface_state_str[on->ospf6_if->state], VNL);
                    613: }
                    614: 
                    615: static void
                    616: ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
                    617: {
                    618:   char router_id[16];
                    619:   char drouter[16], bdrouter[16];
                    620:   char duration[16];
                    621:   struct timeval now, res;
                    622: 
                    623: /*
                    624:     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
                    625:              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
                    626:              "State", VNL);
                    627: */
                    628: 
                    629:   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
                    630:   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
                    631:   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
                    632: 
                    633:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                    634:   timersub (&now, &on->last_changed, &res);
                    635:   timerstring (&res, duration, sizeof (duration));
                    636: 
                    637:   vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
                    638:            router_id, ospf6_neighbor_state_str[on->state],
                    639:            duration, drouter, bdrouter, on->ospf6_if->interface->name,
                    640:            ospf6_interface_state_str[on->ospf6_if->state],
                    641:            VNL);
                    642: }
                    643: 
                    644: static void
                    645: ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
                    646: {
                    647:   char drouter[16], bdrouter[16];
                    648:   char linklocal_addr[64], duration[32];
                    649:   struct timeval now, res;
                    650:   struct ospf6_lsa *lsa;
                    651: 
                    652:   inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
                    653:              sizeof (linklocal_addr));
                    654:   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
                    655:   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
                    656: 
                    657:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
                    658:   timersub (&now, &on->last_changed, &res);
                    659:   timerstring (&res, duration, sizeof (duration));
                    660: 
                    661:   vty_out (vty, " Neighbor %s%s", on->name,
                    662:            VNL);
                    663:   vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
                    664:            on->ospf6_if->area->name,
                    665:            on->ospf6_if->interface->name,
                    666:            on->ospf6_if->interface->ifindex,
                    667:            VNL);
                    668:   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
                    669:            on->ifindex, linklocal_addr,
                    670:            VNL);
                    671:   vty_out (vty, "    State %s for a duration of %s%s",
                    672:            ospf6_neighbor_state_str[on->state], duration,
                    673:            VNL);
                    674:   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
                    675:            drouter, bdrouter, on->priority,
                    676:            VNL);
                    677:   vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
                    678:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
                    679:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
                    680:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
                    681:             "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
                    682:            VNL);
                    683: 
                    684:   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
                    685:            VNL);
                    686:   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
                    687:        lsa = ospf6_lsdb_next (lsa))
                    688:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    689: 
                    690:   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
                    691:            VNL);
                    692:   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
                    693:        lsa = ospf6_lsdb_next (lsa))
                    694:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    695: 
                    696:   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
                    697:            VNL);
                    698:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
                    699:        lsa = ospf6_lsdb_next (lsa))
                    700:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    701: 
                    702:   timerclear (&res);
                    703:   if (on->thread_send_dbdesc)
                    704:     timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
                    705:   timerstring (&res, duration, sizeof (duration));
                    706:   vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
                    707:            on->dbdesc_list->count, duration,
                    708:            (on->thread_send_dbdesc ? "on" : "off"),
                    709:            VNL);
                    710:   for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
                    711:        lsa = ospf6_lsdb_next (lsa))
                    712:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    713: 
                    714:   timerclear (&res);
                    715:   if (on->thread_send_lsreq)
                    716:     timersub (&on->thread_send_lsreq->u.sands, &now, &res);
                    717:   timerstring (&res, duration, sizeof (duration));
                    718:   vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
                    719:            on->lsreq_list->count, duration,
                    720:            (on->thread_send_lsreq ? "on" : "off"),
                    721:            VNL);
                    722:   for (lsa = ospf6_lsdb_head (on->lsreq_list); lsa;
                    723:        lsa = ospf6_lsdb_next (lsa))
                    724:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    725: 
                    726:   timerclear (&res);
                    727:   if (on->thread_send_lsupdate)
                    728:     timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
                    729:   timerstring (&res, duration, sizeof (duration));
                    730:   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
                    731:            on->lsupdate_list->count, duration,
                    732:            (on->thread_send_lsupdate ? "on" : "off"),
                    733:            VNL);
                    734:   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
                    735:        lsa = ospf6_lsdb_next (lsa))
                    736:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    737: 
                    738:   timerclear (&res);
                    739:   if (on->thread_send_lsack)
                    740:     timersub (&on->thread_send_lsack->u.sands, &now, &res);
                    741:   timerstring (&res, duration, sizeof (duration));
                    742:   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
                    743:            on->lsack_list->count, duration,
                    744:            (on->thread_send_lsack ? "on" : "off"),
                    745:            VNL);
                    746:   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
                    747:        lsa = ospf6_lsdb_next (lsa))
                    748:     vty_out (vty, "      %s%s", lsa->name, VNL);
                    749: 
                    750: }
                    751: 
                    752: DEFUN (show_ipv6_ospf6_neighbor,
                    753:        show_ipv6_ospf6_neighbor_cmd,
                    754:        "show ipv6 ospf6 neighbor",
                    755:        SHOW_STR
                    756:        IP6_STR
                    757:        OSPF6_STR
                    758:        "Neighbor list\n"
                    759:       )
                    760: {
                    761:   struct ospf6_neighbor *on;
                    762:   struct ospf6_interface *oi;
                    763:   struct ospf6_area *oa;
                    764:   struct listnode *i, *j, *k;
                    765:   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
                    766: 
                    767:   OSPF6_CMD_CHECK_RUNNING ();
                    768:   showfunc = ospf6_neighbor_show;
                    769: 
                    770:   if (argc)
                    771:     {
                    772:       if (! strncmp (argv[0], "de", 2))
                    773:         showfunc = ospf6_neighbor_show_detail;
                    774:       else if (! strncmp (argv[0], "dr", 2))
                    775:         showfunc = ospf6_neighbor_show_drchoice;
                    776:     }
                    777: 
                    778:   if (showfunc == ospf6_neighbor_show)
                    779:     vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
                    780:              "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
                    781:              "I/F", "State", VNL);
                    782:   else if (showfunc == ospf6_neighbor_show_drchoice)
                    783:     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
                    784:              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
                    785:              "State", VNL);
                    786: 
                    787:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
                    788:     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
                    789:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
                    790:         (*showfunc) (vty, on);
                    791: 
                    792:   return CMD_SUCCESS;
                    793: }
                    794: 
                    795: ALIAS (show_ipv6_ospf6_neighbor,
                    796:        show_ipv6_ospf6_neighbor_detail_cmd,
                    797:        "show ipv6 ospf6 neighbor (detail|drchoice)",
                    798:        SHOW_STR
                    799:        IP6_STR
                    800:        OSPF6_STR
                    801:        "Neighbor list\n"
                    802:        "Display details\n"
                    803:        "Display DR choices\n"
                    804:       )
                    805: 
                    806: DEFUN (show_ipv6_ospf6_neighbor_one,
                    807:        show_ipv6_ospf6_neighbor_one_cmd,
                    808:        "show ipv6 ospf6 neighbor A.B.C.D",
                    809:        SHOW_STR
                    810:        IP6_STR
                    811:        OSPF6_STR
                    812:        "Neighbor list\n"
                    813:        "Specify Router-ID as IPv4 address notation\n"
                    814:       )
                    815: {
                    816:   struct ospf6_neighbor *on;
                    817:   struct ospf6_interface *oi;
                    818:   struct ospf6_area *oa;
                    819:   struct listnode *i, *j, *k;
                    820:   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
                    821:   u_int32_t router_id;
                    822: 
                    823:   OSPF6_CMD_CHECK_RUNNING ();
                    824:   showfunc = ospf6_neighbor_show_detail;
                    825: 
                    826:   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
                    827:     {
                    828:       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
                    829:                VNL);
                    830:       return CMD_SUCCESS;
                    831:     }
                    832: 
                    833:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
                    834:     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
                    835:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
                    836:         (*showfunc) (vty, on);
                    837:   
                    838:   return CMD_SUCCESS;
                    839: }
                    840: 
                    841: void
                    842: ospf6_neighbor_init (void)
                    843: {
                    844:   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
                    845:   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
                    846:   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
                    847:   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
                    848: }
                    849: 
                    850: DEFUN (debug_ospf6_neighbor,
                    851:        debug_ospf6_neighbor_cmd,
                    852:        "debug ospf6 neighbor",
                    853:        DEBUG_STR
                    854:        OSPF6_STR
                    855:        "Debug OSPFv3 Neighbor\n"
                    856:       )
                    857: {
                    858:   unsigned char level = 0;
                    859:   if (argc)
                    860:     {
                    861:       if (! strncmp (argv[0], "s", 1))
                    862:         level = OSPF6_DEBUG_NEIGHBOR_STATE;
                    863:       if (! strncmp (argv[0], "e", 1))
                    864:         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
                    865:     }
                    866:   else
                    867:     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
                    868: 
                    869:   OSPF6_DEBUG_NEIGHBOR_ON (level);
                    870:   return CMD_SUCCESS;
                    871: }
                    872: 
                    873: ALIAS (debug_ospf6_neighbor,
                    874:        debug_ospf6_neighbor_detail_cmd,
                    875:        "debug ospf6 neighbor (state|event)",
                    876:        DEBUG_STR
                    877:        OSPF6_STR
                    878:        "Debug OSPFv3 Neighbor\n"
                    879:        "Debug OSPFv3 Neighbor State Change\n"
                    880:        "Debug OSPFv3 Neighbor Event\n"
                    881:       )
                    882: 
                    883: DEFUN (no_debug_ospf6_neighbor,
                    884:        no_debug_ospf6_neighbor_cmd,
                    885:        "no debug ospf6 neighbor",
                    886:        NO_STR
                    887:        DEBUG_STR
                    888:        OSPF6_STR
                    889:        "Debug OSPFv3 Neighbor\n"
                    890:       )
                    891: {
                    892:   unsigned char level = 0;
                    893:   if (argc)
                    894:     {
                    895:       if (! strncmp (argv[0], "s", 1))
                    896:         level = OSPF6_DEBUG_NEIGHBOR_STATE;
                    897:       if (! strncmp (argv[0], "e", 1))
                    898:         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
                    899:     }
                    900:   else
                    901:     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
                    902: 
                    903:   OSPF6_DEBUG_NEIGHBOR_OFF (level);
                    904:   return CMD_SUCCESS;
                    905: }
                    906: 
                    907: ALIAS (no_debug_ospf6_neighbor,
                    908:        no_debug_ospf6_neighbor_detail_cmd,
                    909:        "no debug ospf6 neighbor (state|event)",
                    910:        NO_STR
                    911:        DEBUG_STR
                    912:        OSPF6_STR
                    913:        "Debug OSPFv3 Neighbor\n"
                    914:        "Debug OSPFv3 Neighbor State Change\n"
                    915:        "Debug OSPFv3 Neighbor Event\n"
                    916:       )
                    917: 
                    918: int
                    919: config_write_ospf6_debug_neighbor (struct vty *vty)
                    920: {
                    921:   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
                    922:       IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    923:     vty_out (vty, "debug ospf6 neighbor%s", VNL);
                    924:   else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
                    925:     vty_out (vty, "debug ospf6 neighbor state%s", VNL);
                    926:   else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
                    927:     vty_out (vty, "debug ospf6 neighbor event%s", VNL);
                    928:   return 0;
                    929: }
                    930: 
                    931: void
                    932: install_element_ospf6_debug_neighbor (void)
                    933: {
                    934:   install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
                    935:   install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
                    936:   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
                    937:   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
                    938:   install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
                    939:   install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
                    940:   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
                    941:   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
                    942: }
                    943: 
                    944: 
                    945: 

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