Annotation of embedaddon/quagga/ospf6d/ospf6_neighbor.c, revision 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>