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

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

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