back to topotato report
topotato coverage report
Current view: top level - ospf6d - ospf6_neighbor.c (source / functions) Hit Total Coverage
Test: test_ospf6_p2xp.py::PtMPBasic Lines: 343 887 38.7 %
Date: 2023-02-24 18:38:14 Functions: 31 53 58.5 %

          Line data    Source code
       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 along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <zebra.h>
      22             : 
      23             : #include "log.h"
      24             : #include "memory.h"
      25             : #include "thread.h"
      26             : #include "linklist.h"
      27             : #include "vty.h"
      28             : #include "command.h"
      29             : #include "lib/bfd.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             : #include "ospf6_bfd.h"
      43             : #include "ospf6_abr.h"
      44             : #include "ospf6_asbr.h"
      45             : #include "ospf6_lsa.h"
      46             : #include "ospf6_spf.h"
      47             : #include "ospf6_zebra.h"
      48             : #include "ospf6_gr.h"
      49             : #include "ospf6_vlink.h"
      50             : #include "lib/json.h"
      51             : 
      52          12 : DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor");
      53          12 : DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR_P2XP_CFG,
      54             :                     "OSPF6 PtP/PtMP neighbor config");
      55             : 
      56             : static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
      57             :                                       const struct ospf6_if_p2xp_neighcfg *b);
      58             : 
      59           9 : DECLARE_RBTREE_UNIQ(ospf6_if_p2xp_neighcfgs, struct ospf6_if_p2xp_neighcfg,
      60             :                     item, ospf6_if_p2xp_neighcfg_cmp);
      61             : 
      62             : static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost);
      63             : 
      64          78 : DEFINE_HOOK(ospf6_neighbor_change,
      65             :             (struct ospf6_neighbor * on, int state, int next_state),
      66             :             (on, state, next_state));
      67             : 
      68             : unsigned char conf_debug_ospf6_neighbor = 0;
      69             : 
      70             : const char *const ospf6_neighbor_state_str[] = {
      71             :         "None",    "Down",     "Attempt", "Init", "Twoway",
      72             :         "ExStart", "ExChange", "Loading", "Full", NULL};
      73             : 
      74             : const char *const ospf6_neighbor_event_str[] = {
      75             :         "NoEvent",      "HelloReceived", "2-WayReceived",   "NegotiationDone",
      76             :         "ExchangeDone", "LoadingDone",   "AdjOK?",          "SeqNumberMismatch",
      77             :         "BadLSReq",     "1-WayReceived", "InactivityTimer", "VLinkUnreachable",
      78             :         "VLinkReachable",
      79             : };
      80             : 
      81           3 : int ospf6_neighbor_cmp(void *va, void *vb)
      82             : {
      83           3 :         struct ospf6_neighbor *ona = (struct ospf6_neighbor *)va;
      84           3 :         struct ospf6_neighbor *onb = (struct ospf6_neighbor *)vb;
      85             : 
      86           3 :         if (ona->router_id == onb->router_id)
      87             :                 return 0;
      88             : 
      89           3 :         return (ntohl(ona->router_id) < ntohl(onb->router_id)) ? -1 : 1;
      90             : }
      91             : 
      92         462 : struct ospf6_neighbor *ospf6_neighbor_lookup(uint32_t router_id,
      93             :                                              struct ospf6_interface *oi)
      94             : {
      95         462 :         struct listnode *n;
      96         462 :         struct ospf6_neighbor *on;
      97             : 
      98        1112 :         for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, n, on))
      99         634 :                 if (on->router_id == router_id)
     100         446 :                         return on;
     101             : 
     102             :         return (struct ospf6_neighbor *)NULL;
     103             : }
     104             : 
     105           0 : struct ospf6_neighbor *ospf6_area_neighbor_lookup(struct ospf6_area *area,
     106             :                                                   uint32_t router_id)
     107             : {
     108           0 :         struct ospf6_interface *oi;
     109           0 :         struct ospf6_neighbor *nbr;
     110           0 :         struct listnode *node;
     111             : 
     112           0 :         for (ALL_LIST_ELEMENTS_RO(area->if_list, node, oi)) {
     113           0 :                 nbr = ospf6_neighbor_lookup(router_id, oi);
     114           0 :                 if (nbr)
     115           0 :                         return nbr;
     116             :         }
     117             : 
     118             :         return NULL;
     119             : }
     120             : 
     121          16 : static void ospf6_neighbor_clear_ls_lists(struct ospf6_neighbor *on)
     122             : {
     123          16 :         struct ospf6_lsa *lsa;
     124          16 :         struct ospf6_lsa *lsanext;
     125             : 
     126          16 :         ospf6_lsdb_remove_all(on->summary_list);
     127          16 :         if (on->last_ls_req) {
     128           0 :                 ospf6_lsa_unlock(on->last_ls_req);
     129           0 :                 on->last_ls_req = NULL;
     130             :         }
     131          16 :         ospf6_lsdb_remove_all(on->request_list);
     132          29 :         for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
     133          13 :                 ospf6_decrement_retrans_count(lsa);
     134          13 :                 ospf6_lsdb_remove(lsa, on->retrans_list);
     135             :         }
     136          16 : }
     137             : 
     138             : /* create ospf6_neighbor */
     139           8 : struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
     140             :                                              struct ospf6_interface *oi)
     141             : {
     142           8 :         struct ospf6_neighbor *on;
     143           8 :         char buf[16];
     144           8 :         int type;
     145             : 
     146           8 :         on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor));
     147           8 :         inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
     148           8 :         snprintfrr(on->name, sizeof(on->name), "%s%%%pOI", buf, oi);
     149           8 :         on->ospf6_if = oi;
     150           8 :         on->state = OSPF6_NEIGHBOR_DOWN;
     151           8 :         on->state_change = 0;
     152           8 :         monotime(&on->last_changed);
     153           8 :         on->router_id = router_id;
     154             : 
     155           8 :         on->summary_list = ospf6_lsdb_create(on);
     156           8 :         on->request_list = ospf6_lsdb_create(on);
     157           8 :         on->retrans_list = ospf6_lsdb_create(on);
     158             : 
     159           8 :         on->dbdesc_list = ospf6_lsdb_create(on);
     160           8 :         on->lsupdate_list = ospf6_lsdb_create(on);
     161           8 :         on->lsack_list = ospf6_lsdb_create(on);
     162             : 
     163          56 :         for (type = 0; type < OSPF6_MESSAGE_TYPE_MAX; type++) {
     164          48 :                 on->seqnum_l[type] = 0;
     165          48 :                 on->seqnum_h[type] = 0;
     166             :         }
     167             : 
     168           8 :         on->auth_present = false;
     169             : 
     170           8 :         listnode_add_sort(oi->neighbor_list, on);
     171             : 
     172           8 :         ospf6_bfd_info_nbr_create(oi, on);
     173           8 :         return on;
     174             : }
     175             : 
     176           8 : void ospf6_neighbor_delete(struct ospf6_neighbor *on)
     177             : {
     178           8 :         assertf(!on->vlink, "on->name=%pSQ on->router_id=%pI4", on->name,
     179             :                 &on->router_id);
     180             : 
     181           8 :         listnode_delete(on->ospf6_if->neighbor_list, on);
     182             : 
     183           8 :         if (on->p2xp_cfg)
     184           0 :                 on->p2xp_cfg->active = NULL;
     185             : 
     186           8 :         ospf6_neighbor_clear_ls_lists(on);
     187             : 
     188           8 :         ospf6_lsdb_remove_all(on->dbdesc_list);
     189           8 :         ospf6_lsdb_remove_all(on->lsupdate_list);
     190           8 :         ospf6_lsdb_remove_all(on->lsack_list);
     191             : 
     192           8 :         ospf6_lsdb_delete(on->summary_list);
     193           8 :         ospf6_lsdb_delete(on->request_list);
     194           8 :         ospf6_lsdb_delete(on->retrans_list);
     195             : 
     196           8 :         ospf6_lsdb_delete(on->dbdesc_list);
     197           8 :         ospf6_lsdb_delete(on->lsupdate_list);
     198           8 :         ospf6_lsdb_delete(on->lsack_list);
     199             : 
     200           8 :         THREAD_OFF(on->inactivity_timer);
     201             : 
     202           8 :         THREAD_OFF(on->last_dbdesc_release_timer);
     203             : 
     204           8 :         THREAD_OFF(on->thread_send_dbdesc);
     205           8 :         THREAD_OFF(on->thread_send_lsreq);
     206           8 :         THREAD_OFF(on->thread_send_lsupdate);
     207           8 :         THREAD_OFF(on->thread_send_lsack);
     208           8 :         THREAD_OFF(on->thread_exchange_done);
     209           8 :         THREAD_OFF(on->thread_adj_ok);
     210             : 
     211           8 :         THREAD_OFF(on->gr_helper_info.t_grace_timer);
     212             : 
     213           8 :         bfd_sess_free(&on->bfd_session);
     214           8 :         XFREE(MTYPE_OSPF6_NEIGHBOR, on);
     215           8 : }
     216             : 
     217          90 : void ospf6_neighbor_lladdr_set(struct ospf6_neighbor *on,
     218             :                                const struct in6_addr *addr)
     219             : {
     220          90 :         if (IPV6_ADDR_SAME(addr, &on->linklocal_addr))
     221             :                 return;
     222             : 
     223           8 :         memcpy(&on->linklocal_addr, addr, sizeof(struct in6_addr));
     224             : 
     225           8 :         if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT
     226           8 :             || on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
     227           6 :                 uint32_t prev_cost = ospf6_neighbor_cost(on);
     228             : 
     229           6 :                 p2xp_neigh_refresh(on, prev_cost);
     230             :         }
     231             : }
     232             : 
     233          39 : static void ospf6_neighbor_state_change(uint8_t next_state,
     234             :                                         struct ospf6_neighbor *on, int event)
     235             : {
     236          39 :         uint8_t prev_state;
     237             : 
     238          39 :         prev_state = on->state;
     239          39 :         on->state = next_state;
     240             : 
     241          39 :         if (prev_state == next_state)
     242             :                 return;
     243             : 
     244          39 :         on->state_change++;
     245          39 :         monotime(&on->last_changed);
     246             : 
     247             :         /* log */
     248          39 :         if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) {
     249           0 :                 zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)",
     250             :                            on->name, ospf6_neighbor_state_str[prev_state],
     251             :                            ospf6_neighbor_state_str[next_state],
     252             :                            ospf6_neighbor_event_string(event));
     253             :         }
     254             : 
     255             :         /* Optionally notify about adjacency changes */
     256          39 :         if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
     257             :                        OSPF6_LOG_ADJACENCY_CHANGES)
     258          39 :             && (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
     259             :                            OSPF6_LOG_ADJACENCY_DETAIL)
     260          39 :                 || (next_state == OSPF6_NEIGHBOR_FULL)
     261          39 :                 || (next_state < prev_state)))
     262          16 :                 zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
     263             :                             ospf6_neighbor_state_str[prev_state],
     264             :                             ospf6_neighbor_state_str[next_state],
     265             :                             ospf6_neighbor_event_string(event));
     266             : 
     267          39 :         if (prev_state == OSPF6_NEIGHBOR_FULL
     268          39 :             || next_state == OSPF6_NEIGHBOR_FULL) {
     269           8 :                 if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) {
     270           8 :                         OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
     271           8 :                         if (on->ospf6_if->state == OSPF6_INTERFACE_DR) {
     272           1 :                                 OSPF6_NETWORK_LSA_SCHEDULE(on->ospf6_if);
     273           1 :                                 OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(
     274             :                                         on->ospf6_if);
     275             :                         }
     276             :                 }
     277           8 :                 if (next_state == OSPF6_NEIGHBOR_FULL)
     278           8 :                         on->ospf6_if->area->intra_prefix_originate = 1;
     279             : 
     280           8 :                 if (!OSPF6_GR_IS_ACTIVE_HELPER(on))
     281           8 :                         OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(
     282             :                                 on->ospf6_if->area);
     283             : 
     284             :                 /* note for virtual links:
     285             :                  *   on->ospf6_if->area != on->vlink->area
     286             :                  *   (backbone)            (non-backbone)
     287             :                  */
     288             : 
     289           8 :                 if ((prev_state == OSPF6_NEIGHBOR_LOADING
     290           8 :                      || prev_state == OSPF6_NEIGHBOR_EXCHANGE)
     291           8 :                     && next_state == OSPF6_NEIGHBOR_FULL) {
     292           8 :                         OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if);
     293           8 :                         on->ospf6_if->area->full_nbrs++;
     294           8 :                         if (on->vlink) {
     295           0 :                                 on->vlink->area->virtual_link_full++;
     296           0 :                                 if (on->vlink->area->virtual_link_full == 1)
     297           0 :                                         OSPF6_ROUTER_LSA_SCHEDULE(
     298             :                                                         on->vlink->area);
     299             :                         }
     300             :                 }
     301             : 
     302           8 :                 if (prev_state == OSPF6_NEIGHBOR_FULL) {
     303           0 :                         on->ospf6_if->area->full_nbrs--;
     304           0 :                         if (on->vlink) {
     305           0 :                                 on->vlink->area->virtual_link_full--;
     306           0 :                                 if (!on->vlink->area->virtual_link_full)
     307           0 :                                         OSPF6_ROUTER_LSA_SCHEDULE(
     308             :                                                         on->vlink->area);
     309             :                         }
     310             :                 }
     311             :         }
     312             : 
     313          39 :         if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE
     314          39 :              || prev_state == OSPF6_NEIGHBOR_LOADING)
     315          13 :             && (next_state != OSPF6_NEIGHBOR_EXCHANGE
     316          13 :                 && next_state != OSPF6_NEIGHBOR_LOADING))
     317           8 :                 ospf6_maxage_remove(on->ospf6_if->area->ospf6);
     318             : 
     319          39 :         hook_call(ospf6_neighbor_change, on, next_state, prev_state);
     320          39 :         ospf6_bfd_trigger_event(on, prev_state, next_state);
     321             : }
     322             : 
     323           0 : void ospf6_neighbor_vlink_change(struct ospf6_neighbor *nbr, bool up)
     324             : {
     325           0 :         if (nbr->state <= OSPF6_NEIGHBOR_DOWN && up)
     326           0 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_ATTEMPT, nbr,
     327             :                                             OSPF6_NEIGHBOR_EVENT_VLINK_REACHABLE);
     328           0 :         if (nbr->state > OSPF6_NEIGHBOR_DOWN && !up)
     329           0 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_DOWN, nbr,
     330             :                                             OSPF6_NEIGHBOR_EVENT_VLINK_UNREACHABLE);
     331           0 : }
     332             : 
     333             : /* RFC2328 section 10.4 */
     334          10 : static int need_adjacency(struct ospf6_neighbor *on)
     335             : {
     336          10 :         if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT
     337             :             || on->ospf6_if->state == OSPF6_INTERFACE_POINTTOMULTIPOINT
     338          10 :             || on->ospf6_if->state == OSPF6_INTERFACE_DR
     339           3 :             || on->ospf6_if->state == OSPF6_INTERFACE_BDR
     340           2 :             || on->ospf6_if->state == OSPF6_INTERFACE_VIRTUALLINK)
     341             :                 return 1;
     342             : 
     343           2 :         if (on->ospf6_if->drouter == on->router_id
     344           2 :             || on->ospf6_if->bdrouter == on->router_id)
     345           0 :                 return 1;
     346             : 
     347             :         return 0;
     348             : }
     349             : 
     350          90 : void hello_received(struct thread *thread)
     351             : {
     352          90 :         struct ospf6_neighbor *on;
     353             : 
     354          90 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     355          90 :         assert(on);
     356             : 
     357          90 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     358           0 :                 zlog_debug("Neighbor Event %s: *HelloReceived*", on->name);
     359             : 
     360             :         /* reset Inactivity Timer */
     361          90 :         THREAD_OFF(on->inactivity_timer);
     362          90 :         thread_add_timer(master, inactivity_timer, on,
     363             :                          on->vlink ? on->vlink->dead_interval
     364             :                                    : on->ospf6_if->dead_interval,
     365             :                          &on->inactivity_timer);
     366             : 
     367          90 :         if (on->state <= OSPF6_NEIGHBOR_ATTEMPT)
     368           8 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
     369             :                                             OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
     370          90 : }
     371             : 
     372          89 : void twoway_received(struct thread *thread)
     373             : {
     374          89 :         struct ospf6_neighbor *on;
     375             : 
     376          89 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     377          89 :         assert(on);
     378             : 
     379          89 :         if (on->state > OSPF6_NEIGHBOR_INIT)
     380             :                 return;
     381             : 
     382           8 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     383           0 :                 zlog_debug("Neighbor Event %s: *2Way-Received*", on->name);
     384             : 
     385           8 :         thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
     386             : 
     387           8 :         if (!need_adjacency(on)) {
     388           2 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
     389             :                                             OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
     390           2 :                 return;
     391             :         }
     392             : 
     393           6 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
     394             :                                     OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
     395           6 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
     396           6 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
     397           6 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
     398             : 
     399           6 :         THREAD_OFF(on->thread_send_dbdesc);
     400           6 :         thread_add_event(master, ospf6_dbdesc_send, on, 0,
     401             :                          &on->thread_send_dbdesc);
     402             : }
     403             : 
     404           8 : void negotiation_done(struct thread *thread)
     405             : {
     406           8 :         struct ospf6_neighbor *on;
     407           8 :         struct ospf6_lsa *lsa, *lsanext;
     408             : 
     409           8 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     410           8 :         assert(on);
     411             : 
     412           8 :         if (on->state != OSPF6_NEIGHBOR_EXSTART)
     413           0 :                 return;
     414             : 
     415           8 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     416           0 :                 zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name);
     417             : 
     418             :         /* clear ls-list */
     419           8 :         ospf6_neighbor_clear_ls_lists(on);
     420             : 
     421             :         /* Interface scoped LSAs */
     422           8 :         if (on->ospf6_if->lsdb)
     423          20 :                 for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) {
     424          12 :                         if (OSPF6_LSA_IS_MAXAGE(lsa)) {
     425           0 :                                 ospf6_increment_retrans_count(lsa);
     426           0 :                                 ospf6_lsdb_add(ospf6_lsa_copy(lsa),
     427             :                                                on->retrans_list);
     428             :                         } else
     429          12 :                                 ospf6_lsdb_add(ospf6_lsa_copy(lsa),
     430             :                                                on->summary_list);
     431             :                 }
     432             : 
     433             :         /* Area scoped LSAs */
     434          35 :         for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa, lsanext)) {
     435          27 :                 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
     436           0 :                         ospf6_increment_retrans_count(lsa);
     437           0 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
     438             :                 } else
     439          27 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
     440             :         }
     441             : 
     442             :         /* AS scoped LSAs */
     443           8 :         for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa, lsanext)) {
     444           0 :                 if (OSPF6_LSA_IS_MAXAGE(lsa)) {
     445           0 :                         ospf6_increment_retrans_count(lsa);
     446           0 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
     447             :                 } else
     448           0 :                         ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->summary_list);
     449             :         }
     450             : 
     451           8 :         UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
     452           8 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on,
     453             :                                     OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
     454             : }
     455             : 
     456           4 : static void ospf6_neighbor_last_dbdesc_release(struct thread *thread)
     457             : {
     458           4 :         struct ospf6_neighbor *on = THREAD_ARG(thread);
     459             : 
     460           4 :         assert(on);
     461           4 :         memset(&on->dbdesc_last, 0, sizeof(struct ospf6_dbdesc));
     462           4 : }
     463             : 
     464           8 : void exchange_done(struct thread *thread)
     465             : {
     466           8 :         struct ospf6_neighbor *on;
     467             : 
     468           8 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     469           8 :         assert(on);
     470             : 
     471           8 :         if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
     472             :                 return;
     473             : 
     474           8 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     475           0 :                 zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name);
     476             : 
     477           8 :         THREAD_OFF(on->thread_send_dbdesc);
     478           8 :         ospf6_lsdb_remove_all(on->dbdesc_list);
     479             : 
     480             :         /* RFC 2328 (10.8): Release the last dbdesc after dead_interval */
     481           8 :         if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)) {
     482           4 :                 THREAD_OFF(on->last_dbdesc_release_timer);
     483           4 :                 thread_add_timer(master, ospf6_neighbor_last_dbdesc_release, on,
     484             :                                  on->vlink ? on->vlink->dead_interval
     485             :                                            : on->ospf6_if->dead_interval,
     486             :                                  &on->last_dbdesc_release_timer);
     487             :         }
     488             : 
     489           8 :         if (on->request_list->count == 0)
     490           3 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
     491             :                                             OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
     492             :         else {
     493           5 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_LOADING, on,
     494             :                                             OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
     495             : 
     496           5 :                 thread_add_event(master, ospf6_lsreq_send, on, 0,
     497             :                                  &on->thread_send_lsreq);
     498             :         }
     499             : }
     500             : 
     501             : /* Check loading state. */
     502          25 : void ospf6_check_nbr_loading(struct ospf6_neighbor *on)
     503             : {
     504             : 
     505             :         /* RFC2328 Section 10.9: When the neighbor responds to these requests
     506             :            with the proper Link State Update packet(s), the Link state request
     507             :            list is truncated and a new Link State Request packet is sent.
     508             :         */
     509          25 :         if ((on->state == OSPF6_NEIGHBOR_LOADING)
     510          25 :             || (on->state == OSPF6_NEIGHBOR_EXCHANGE)) {
     511          25 :                 if (on->request_list->count == 0)
     512           8 :                         thread_add_event(master, loading_done, on, 0, NULL);
     513          17 :                 else if (on->last_ls_req == NULL) {
     514           0 :                         THREAD_OFF(on->thread_send_lsreq);
     515           0 :                         thread_add_event(master, ospf6_lsreq_send, on, 0,
     516             :                                          &on->thread_send_lsreq);
     517             :                 }
     518             :         }
     519          25 : }
     520             : 
     521           8 : void loading_done(struct thread *thread)
     522             : {
     523           8 :         struct ospf6_neighbor *on;
     524             : 
     525           8 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     526           8 :         assert(on);
     527             : 
     528           8 :         if (on->state != OSPF6_NEIGHBOR_LOADING)
     529             :                 return;
     530             : 
     531           5 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     532           0 :                 zlog_debug("Neighbor Event %s: *LoadingDone*", on->name);
     533             : 
     534           5 :         assert(on->request_list->count == 0);
     535             : 
     536           5 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
     537             :                                     OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
     538             : }
     539             : 
     540           2 : void adj_ok(struct thread *thread)
     541             : {
     542           2 :         struct ospf6_neighbor *on;
     543             : 
     544           2 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     545           2 :         assert(on);
     546             : 
     547           2 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     548           0 :                 zlog_debug("Neighbor Event %s: *AdjOK?*", on->name);
     549             : 
     550           2 :         if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency(on)) {
     551           2 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
     552             :                                             OSPF6_NEIGHBOR_EVENT_ADJ_OK);
     553           2 :                 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
     554           2 :                 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
     555           2 :                 SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
     556             : 
     557           2 :                 THREAD_OFF(on->thread_send_dbdesc);
     558           2 :                 thread_add_event(master, ospf6_dbdesc_send, on, 0,
     559             :                                  &on->thread_send_dbdesc);
     560             : 
     561           0 :         } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) {
     562           0 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
     563             :                                             OSPF6_NEIGHBOR_EVENT_ADJ_OK);
     564           0 :                 ospf6_neighbor_clear_ls_lists(on);
     565             :         }
     566           2 : }
     567             : 
     568           0 : void seqnumber_mismatch(struct thread *thread)
     569             : {
     570           0 :         struct ospf6_neighbor *on;
     571             : 
     572           0 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     573           0 :         assert(on);
     574             : 
     575           0 :         if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
     576             :                 return;
     577             : 
     578           0 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     579           0 :                 zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name);
     580             : 
     581           0 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
     582             :                                     OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
     583           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
     584           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
     585           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
     586             : 
     587           0 :         ospf6_neighbor_clear_ls_lists(on);
     588             : 
     589           0 :         THREAD_OFF(on->thread_send_dbdesc);
     590           0 :         on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
     591             : 
     592           0 :         thread_add_event(master, ospf6_dbdesc_send, on, 0,
     593             :                          &on->thread_send_dbdesc);
     594             : }
     595             : 
     596           0 : void bad_lsreq(struct thread *thread)
     597             : {
     598           0 :         struct ospf6_neighbor *on;
     599             : 
     600           0 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     601           0 :         assert(on);
     602             : 
     603           0 :         if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
     604             :                 return;
     605             : 
     606           0 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     607           0 :                 zlog_debug("Neighbor Event %s: *BadLSReq*", on->name);
     608             : 
     609           0 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
     610             :                                     OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
     611           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
     612           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
     613           0 :         SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
     614             : 
     615           0 :         ospf6_neighbor_clear_ls_lists(on);
     616             : 
     617           0 :         THREAD_OFF(on->thread_send_dbdesc);
     618           0 :         on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
     619             : 
     620           0 :         thread_add_event(master, ospf6_dbdesc_send, on, 0,
     621             :                          &on->thread_send_dbdesc);
     622             : 
     623             : }
     624             : 
     625           4 : void oneway_received(struct thread *thread)
     626             : {
     627           4 :         struct ospf6_neighbor *on;
     628             : 
     629           4 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     630           4 :         assert(on);
     631             : 
     632           4 :         if (on->state < OSPF6_NEIGHBOR_TWOWAY)
     633             :                 return;
     634             : 
     635           0 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     636           0 :                 zlog_debug("Neighbor Event %s: *1Way-Received*", on->name);
     637             : 
     638           0 :         ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
     639             :                                     OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
     640           0 :         thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
     641             : 
     642           0 :         ospf6_neighbor_clear_ls_lists(on);
     643             : 
     644           0 :         THREAD_OFF(on->thread_send_dbdesc);
     645           0 :         THREAD_OFF(on->thread_send_lsreq);
     646           0 :         THREAD_OFF(on->thread_send_lsupdate);
     647           0 :         THREAD_OFF(on->thread_send_lsack);
     648           0 :         THREAD_OFF(on->thread_exchange_done);
     649           0 :         THREAD_OFF(on->thread_adj_ok);
     650             : }
     651             : 
     652           0 : void inactivity_timer(struct thread *thread)
     653             : {
     654           0 :         struct ospf6_neighbor *on;
     655             : 
     656           0 :         on = (struct ospf6_neighbor *)THREAD_ARG(thread);
     657           0 :         assert(on);
     658             : 
     659           0 :         if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
     660           0 :                 zlog_debug("Neighbor Event %s: *InactivityTimer*", on->name);
     661             : 
     662           0 :         on->drouter = on->prev_drouter = 0;
     663           0 :         on->bdrouter = on->prev_bdrouter = 0;
     664             : 
     665           0 :         if (on->vlink) {
     666           0 :                 ospf6_neighbor_state_change(OSPF6_NEIGHBOR_ATTEMPT, on,
     667             :                                 OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
     668           0 :                 return;
     669             :         }
     670             : 
     671           0 :         if (!OSPF6_GR_IS_ACTIVE_HELPER(on)) {
     672           0 :                 on->drouter = on->prev_drouter = 0;
     673           0 :                 on->bdrouter = on->prev_bdrouter = 0;
     674             : 
     675           0 :                 ospf6_neighbor_state_change(
     676             :                         OSPF6_NEIGHBOR_DOWN, on,
     677             :                         OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
     678           0 :                 thread_add_event(master, neighbor_change, on->ospf6_if, 0,
     679             :                                  NULL);
     680             : 
     681           0 :                 ospf6_neighbor_delete(on);
     682             : 
     683             :         } else {
     684           0 :                 if (IS_DEBUG_OSPF6_GR)
     685           0 :                         zlog_debug(
     686             :                                 "%s, Acting as HELPER for this neighbour, So restart the dead timer.",
     687             :                                 __PRETTY_FUNCTION__);
     688             : 
     689           0 :                 thread_add_timer(master, inactivity_timer, on,
     690             :                                  on->ospf6_if->dead_interval,
     691             :                                  &on->inactivity_timer);
     692             :         }
     693             : }
     694             : 
     695             : /* P2P/P2MP stuff */
     696             : 
     697          24 : uint32_t ospf6_neighbor_cost(struct ospf6_neighbor *on)
     698             : {
     699          24 :         if (on->p2xp_cfg && on->p2xp_cfg->cfg_cost)
     700           0 :                 return on->p2xp_cfg->cost;
     701          24 :         if (on->vlink)
     702           0 :                 return on->vlink->spf_cost;
     703          24 :         return on->ospf6_if->cost;
     704             : }
     705             : 
     706           0 : static int ospf6_if_p2xp_neighcfg_cmp(const struct ospf6_if_p2xp_neighcfg *a,
     707             :                                       const struct ospf6_if_p2xp_neighcfg *b)
     708             : {
     709           0 :         return IPV6_ADDR_CMP(&a->addr, &b->addr);
     710             : }
     711             : 
     712           6 : struct ospf6_if_p2xp_neighcfg *ospf6_if_p2xp_find(struct ospf6_interface *oi,
     713             :                                                   const struct in6_addr *addr)
     714             : {
     715           6 :         struct ospf6_if_p2xp_neighcfg ref;
     716             : 
     717           6 :         if (!oi)
     718             :                 return NULL;
     719             : 
     720           6 :         ref.addr = *addr;
     721           6 :         return ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
     722             : }
     723             : 
     724             : static struct ospf6_if_p2xp_neighcfg *
     725           0 : ospf6_if_p2xp_get(struct ospf6_interface *oi, const struct in6_addr *addr)
     726             : {
     727           0 :         struct ospf6_if_p2xp_neighcfg ref, *ret;
     728             : 
     729           0 :         if (!oi)
     730             :                 return NULL;
     731             : 
     732           0 :         ref.addr = *addr;
     733           0 :         ret = ospf6_if_p2xp_neighcfgs_find(&oi->p2xp_neighs, &ref);
     734           0 :         if (!ret) {
     735           0 :                 ret = XCALLOC(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, sizeof(*ret));
     736           0 :                 ret->addr = *addr;
     737           0 :                 ret->ospf6_if = oi;
     738             : 
     739           0 :                 ospf6_if_p2xp_neighcfgs_add(&oi->p2xp_neighs, ret);
     740             :         }
     741             : 
     742             :         return ret;
     743             : }
     744             : 
     745           0 : static void ospf6_if_p2xp_destroy(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
     746             : {
     747           0 :         THREAD_OFF(p2xp_cfg->t_unicast_hello);
     748           0 :         ospf6_if_p2xp_neighcfgs_del(&p2xp_cfg->ospf6_if->p2xp_neighs, p2xp_cfg);
     749             : 
     750           0 :         XFREE(MTYPE_OSPF6_NEIGHBOR_P2XP_CFG, p2xp_cfg);
     751           0 : }
     752             : 
     753           6 : static void p2xp_neigh_refresh(struct ospf6_neighbor *on, uint32_t prev_cost)
     754             : {
     755           6 :         if (on->p2xp_cfg)
     756           0 :                 on->p2xp_cfg->active = NULL;
     757           6 :         on->p2xp_cfg = ospf6_if_p2xp_find(on->ospf6_if, &on->linklocal_addr);
     758           6 :         if (on->p2xp_cfg)
     759           0 :                 on->p2xp_cfg->active = on;
     760             : 
     761           6 :         if (ospf6_neighbor_cost(on) != prev_cost)
     762           0 :                 OSPF6_ROUTER_LSA_SCHEDULE(on->ospf6_if->area);
     763           6 : }
     764             : 
     765             : /* vty functions */
     766             : 
     767             : #ifndef VTYSH_EXTRACT_PL
     768             : #include "ospf6d/ospf6_neighbor_clippy.c"
     769             : #endif
     770             : 
     771           0 : DEFPY (ipv6_ospf6_p2xp_neigh,
     772             :        ipv6_ospf6_p2xp_neigh_cmd,
     773             :        "[no] ipv6 ospf6 neighbor X:X::X:X",
     774             :        NO_STR
     775             :        IP6_STR
     776             :        OSPF6_STR
     777             :        "Configure static neighbor\n"
     778             :        "Neighbor link-local address\n")
     779             : {
     780           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     781           0 :         struct ospf6_interface *oi = ifp->info;
     782           0 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
     783             : 
     784           0 :         if (!oi) {
     785           0 :                 if (no)
     786             :                         return CMD_SUCCESS;
     787           0 :                 oi = ospf6_interface_create(ifp);
     788             :         }
     789             : 
     790           0 :         if (no) {
     791           0 :                 struct ospf6_neighbor *on;
     792           0 :                 uint32_t prev_cost = 0;
     793             : 
     794           0 :                 p2xp_cfg = ospf6_if_p2xp_find(oi, &neighbor);
     795           0 :                 if (!p2xp_cfg)
     796             :                         return CMD_SUCCESS;
     797             : 
     798           0 :                 on = p2xp_cfg->active;
     799           0 :                 if (on)
     800           0 :                         prev_cost = ospf6_neighbor_cost(on);
     801             : 
     802           0 :                 p2xp_cfg->active = NULL;
     803           0 :                 ospf6_if_p2xp_destroy(p2xp_cfg);
     804             : 
     805           0 :                 if (on) {
     806           0 :                         on->p2xp_cfg = NULL;
     807           0 :                         p2xp_neigh_refresh(on, prev_cost);
     808             :                 }
     809           0 :                 return CMD_SUCCESS;
     810             :         }
     811             : 
     812           0 :         p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
     813           0 :         return CMD_SUCCESS;
     814             : }
     815             : 
     816           0 : DEFPY (ipv6_ospf6_p2xp_neigh_cost,
     817             :        ipv6_ospf6_p2xp_neigh_cost_cmd,
     818             :        "[no] ipv6 ospf6 neighbor X:X::X:X cost (1-65535)",
     819             :        NO_STR
     820             :        IP6_STR
     821             :        OSPF6_STR
     822             :        "Configure static neighbor\n"
     823             :        "Neighbor link-local address\n"
     824             :        "Outgoing metric for this neighbor\n"
     825             :        "Outgoing metric for this neighbor\n")
     826             : {
     827           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     828           0 :         struct ospf6_interface *oi = ifp->info;
     829           0 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
     830             : 
     831           0 :         if (!oi) {
     832           0 :                 if (no)
     833             :                         return CMD_SUCCESS;
     834           0 :                 oi = ospf6_interface_create(ifp);
     835             :         }
     836             : 
     837           0 :         p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
     838             : 
     839           0 :         uint32_t prev_cost;
     840           0 :         if (p2xp_cfg->active)
     841           0 :                 prev_cost = ospf6_neighbor_cost(p2xp_cfg->active);
     842             : 
     843           0 :         if (no) {
     844           0 :                 p2xp_cfg->cfg_cost = false;
     845           0 :                 p2xp_cfg->cost = 0;
     846             :         } else {
     847           0 :                 p2xp_cfg->cfg_cost = true;
     848           0 :                 p2xp_cfg->cost = cost;
     849             :         }
     850             : 
     851           0 :         if (p2xp_cfg->active)
     852           0 :                 p2xp_neigh_refresh(p2xp_cfg->active, prev_cost);
     853             :         return CMD_SUCCESS;
     854             : }
     855             : 
     856             : static void p2xp_unicast_hello_send(struct thread *thread);
     857             : 
     858           0 : static void p2xp_unicast_hello_sched(struct ospf6_if_p2xp_neighcfg *p2xp_cfg)
     859             : {
     860           0 :         if (!p2xp_cfg->poll_interval
     861           0 :             || (p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOMULTIPOINT
     862           0 :                 && p2xp_cfg->ospf6_if->state != OSPF6_INTERFACE_POINTTOPOINT))
     863             :                 /* state check covers DOWN state too */
     864           0 :                 THREAD_OFF(p2xp_cfg->t_unicast_hello);
     865             :         else
     866           0 :                 thread_add_timer(master, p2xp_unicast_hello_send, p2xp_cfg,
     867             :                                  p2xp_cfg->poll_interval,
     868             :                                  &p2xp_cfg->t_unicast_hello);
     869           0 : }
     870             : 
     871           3 : void ospf6_if_p2xp_up(struct ospf6_interface *oi)
     872             : {
     873           3 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
     874             : 
     875           6 :         frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg)
     876           0 :                 p2xp_unicast_hello_sched(p2xp_cfg);
     877           3 : }
     878             : 
     879           0 : static void p2xp_unicast_hello_send(struct thread *thread)
     880             : {
     881           0 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg = THREAD_ARG(thread);
     882           0 :         struct ospf6_interface *oi = p2xp_cfg->ospf6_if;
     883             : 
     884           0 :         if (oi->state != OSPF6_INTERFACE_POINTTOPOINT
     885           0 :             && oi->state != OSPF6_INTERFACE_POINTTOMULTIPOINT)
     886             :                 return;
     887             : 
     888           0 :         p2xp_unicast_hello_sched(p2xp_cfg);
     889             : 
     890           0 :         if (p2xp_cfg->active && p2xp_cfg->active->state >= OSPF6_NEIGHBOR_INIT)
     891             :                 return;
     892             : 
     893           0 :         ospf6_hello_send_addr(oi, NULL, &p2xp_cfg->addr);
     894             : }
     895             : 
     896           0 : DEFPY (ipv6_ospf6_p2xp_neigh_poll_interval,
     897             :        ipv6_ospf6_p2xp_neigh_poll_interval_cmd,
     898             :        "[no] ipv6 ospf6 neighbor X:X::X:X poll-interval (1-65535)",
     899             :        NO_STR
     900             :        IP6_STR
     901             :        OSPF6_STR
     902             :        "Configure static neighbor\n"
     903             :        "Neighbor link-local address\n"
     904             :        "Send unicast hellos to neighbor when down\n"
     905             :        "Unicast hello interval when down (seconds)\n")
     906             : {
     907           0 :         VTY_DECLVAR_CONTEXT(interface, ifp);
     908           0 :         struct ospf6_interface *oi = ifp->info;
     909           0 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
     910             : 
     911           0 :         if (!oi) {
     912           0 :                 if (no)
     913             :                         return CMD_SUCCESS;
     914           0 :                 oi = ospf6_interface_create(ifp);
     915             :         }
     916           0 :         if (no)
     917           0 :                 poll_interval = 0;
     918             : 
     919           0 :         p2xp_cfg = ospf6_if_p2xp_get(oi, &neighbor);
     920           0 :         p2xp_cfg->poll_interval = poll_interval;
     921             : 
     922           0 :         p2xp_unicast_hello_sched(p2xp_cfg);
     923           0 :         return CMD_SUCCESS;
     924             : }
     925             : 
     926             : /* show neighbor structure */
     927          77 : static void ospf6_neighbor_show(struct vty *vty, struct ospf6_neighbor *on,
     928             :                                 json_object *json_array, bool use_json)
     929             : {
     930          77 :         char router_id[16];
     931          77 :         char duration[64];
     932          77 :         struct timeval res;
     933          77 :         char nstate[16];
     934          77 :         char deadtime[64];
     935          77 :         long h, m, s;
     936          77 :         json_object *json_route;
     937             : 
     938             :         /* Router-ID (Name) */
     939          77 :         inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
     940             : #ifdef HAVE_GETNAMEINFO
     941             :         {
     942             :         }
     943             : #endif /*HAVE_GETNAMEINFO*/
     944             : 
     945             :         /* Dead time */
     946          77 :         h = m = s = 0;
     947          77 :         if (on->inactivity_timer) {
     948          77 :                 s = monotime_until(&on->inactivity_timer->u.sands, NULL)
     949             :                     / 1000000LL;
     950          77 :                 h = s / 3600;
     951          77 :                 s -= h * 3600;
     952          77 :                 m = s / 60;
     953          77 :                 s -= m * 60;
     954             :         }
     955          77 :         snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s);
     956             : 
     957             :         /* Neighbor State */
     958          77 :         if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT)
     959           0 :                 snprintf(nstate, sizeof(nstate), "PointToPoint");
     960          77 :         else if (on->ospf6_if->type == OSPF_IFTYPE_POINTOMULTIPOINT)
     961          65 :                 snprintf(nstate, sizeof(nstate), "PtMultipoint");
     962          12 :         else if (on->ospf6_if->type == OSPF_IFTYPE_VIRTUALLINK)
     963           0 :                 snprintf(nstate, sizeof(nstate), "VirtualLink");
     964             :         else {
     965          12 :                 if (on->router_id == on->drouter)
     966          11 :                         snprintf(nstate, sizeof(nstate), "DR");
     967           1 :                 else if (on->router_id == on->bdrouter)
     968           1 :                         snprintf(nstate, sizeof(nstate), "BDR");
     969             :                 else
     970           0 :                         snprintf(nstate, sizeof(nstate), "DROther");
     971             :         }
     972             : 
     973             :         /* Duration */
     974          77 :         monotime_since(&on->last_changed, &res);
     975          77 :         timerstring(&res, duration, sizeof(duration));
     976             : 
     977             :         /*
     978             :         vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]\n",
     979             :                  "Neighbor ID", "Pri", "DeadTime", "State", "IfState",
     980             :         "Duration", "I/F", "State");
     981             :         */
     982          77 :         if (use_json) {
     983          77 :                 json_route = json_object_new_object();
     984             : 
     985          77 :                 json_object_string_add(json_route, "neighborId", router_id);
     986          77 :                 json_object_int_add(json_route, "priority", on->priority);
     987          77 :                 json_object_string_add(json_route, "deadTime", deadtime);
     988          77 :                 json_object_string_add(json_route, "state",
     989          77 :                                        ospf6_neighbor_state_str[on->state]);
     990          77 :                 json_object_string_add(json_route, "ifState", nstate);
     991          77 :                 json_object_string_add(json_route, "duration", duration);
     992          77 :                 json_object_string_add(json_route, "interfaceName",
     993          77 :                                        ospf6_ifname(on->ospf6_if));
     994          77 :                 json_object_string_add(
     995             :                         json_route, "interfaceState",
     996          77 :                         ospf6_interface_state_str[on->ospf6_if->state]);
     997             : 
     998          77 :                 json_object_array_add(json_array, json_route);
     999             :         } else
    1000           0 :                 vty_out(vty, "%-15s %3d %11s %8s/%-12s %11s %pOI[%s]\n",
    1001           0 :                         router_id, on->priority, deadtime,
    1002           0 :                         ospf6_neighbor_state_str[on->state], nstate, duration,
    1003             :                         on->ospf6_if,
    1004           0 :                         ospf6_interface_state_str[on->ospf6_if->state]);
    1005          77 : }
    1006             : 
    1007           0 : static void ospf6_neighbor_show_drchoice(struct vty *vty,
    1008             :                                          struct ospf6_neighbor *on,
    1009             :                                          json_object *json_array, bool use_json)
    1010             : {
    1011           0 :         char router_id[16];
    1012           0 :         char drouter[16], bdrouter[16];
    1013           0 :         char duration[64];
    1014           0 :         struct timeval now, res;
    1015           0 :         json_object *json_route;
    1016             : 
    1017             :         /*
    1018             :             vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]\n",
    1019             :                      "RouterID", "State", "Duration", "DR", "BDR", "I/F",
    1020             :                      "State");
    1021             :         */
    1022             : 
    1023           0 :         inet_ntop(AF_INET, &on->router_id, router_id, sizeof(router_id));
    1024           0 :         inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
    1025           0 :         inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
    1026             : 
    1027           0 :         monotime(&now);
    1028           0 :         timersub(&now, &on->last_changed, &res);
    1029           0 :         timerstring(&res, duration, sizeof(duration));
    1030             : 
    1031           0 :         if (use_json) {
    1032           0 :                 json_route = json_object_new_object();
    1033           0 :                 json_object_string_add(json_route, "routerId", router_id);
    1034           0 :                 json_object_string_add(json_route, "state",
    1035           0 :                                        ospf6_neighbor_state_str[on->state]);
    1036           0 :                 json_object_string_add(json_route, "duration", duration);
    1037           0 :                 json_object_string_add(json_route, "dRouter", drouter);
    1038           0 :                 json_object_string_add(json_route, "bdRouter", bdrouter);
    1039           0 :                 json_object_string_add(json_route, "interfaceName",
    1040           0 :                                        ospf6_ifname(on->ospf6_if));
    1041           0 :                 json_object_string_add(
    1042             :                         json_route, "interfaceState",
    1043           0 :                         ospf6_interface_state_str[on->ospf6_if->state]);
    1044             : 
    1045           0 :                 json_object_array_add(json_array, json_route);
    1046             :         } else
    1047           0 :                 vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %pOI[%s]\n",
    1048           0 :                         router_id, ospf6_neighbor_state_str[on->state],
    1049             :                         duration, drouter, bdrouter, on->ospf6_if,
    1050           0 :                         ospf6_interface_state_str[on->ospf6_if->state]);
    1051           0 : }
    1052             : 
    1053           0 : static void ospf6_neighbor_show_detail(struct vty *vty,
    1054             :                                        struct ospf6_neighbor *on,
    1055             :                                        json_object *json, bool use_json)
    1056             : {
    1057           0 :         char drouter[16], bdrouter[16];
    1058           0 :         char linklocal_addr[64], duration[32];
    1059           0 :         struct timeval now, res;
    1060           0 :         struct ospf6_lsa *lsa, *lsanext;
    1061           0 :         json_object *json_neighbor;
    1062           0 :         json_object *json_array;
    1063           0 :         char db_desc_str[20];
    1064             : 
    1065           0 :         inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr,
    1066             :                   sizeof(linklocal_addr));
    1067           0 :         inet_ntop(AF_INET, &on->drouter, drouter, sizeof(drouter));
    1068           0 :         inet_ntop(AF_INET, &on->bdrouter, bdrouter, sizeof(bdrouter));
    1069             : 
    1070           0 :         monotime(&now);
    1071           0 :         timersub(&now, &on->last_changed, &res);
    1072           0 :         timerstring(&res, duration, sizeof(duration));
    1073             : 
    1074           0 :         if (use_json) {
    1075           0 :                 json_neighbor = json_object_new_object();
    1076           0 :                 json_object_string_add(json_neighbor, "area",
    1077           0 :                                        on->ospf6_if->area->name);
    1078           0 :                 json_object_string_add(json_neighbor, "interface",
    1079           0 :                                        ospf6_ifname(on->ospf6_if));
    1080           0 :                 json_object_int_add(json_neighbor, "interfaceIndex",
    1081           0 :                                     on->ospf6_if->interface->ifindex);
    1082           0 :                 json_object_int_add(json_neighbor, "neighborInterfaceIndex",
    1083           0 :                                     on->ifindex);
    1084           0 :                 json_object_string_add(json_neighbor, "linkLocalAddress",
    1085             :                                        linklocal_addr);
    1086           0 :                 json_object_string_add(json_neighbor, "neighborState",
    1087           0 :                                        ospf6_neighbor_state_str[on->state]);
    1088           0 :                 json_object_string_add(json_neighbor, "neighborStateDuration",
    1089             :                                        duration);
    1090           0 :                 json_object_string_add(json_neighbor, "neighborDRouter",
    1091             :                                        drouter);
    1092           0 :                 json_object_string_add(json_neighbor, "neighborBdRouter",
    1093             :                                        bdrouter);
    1094           0 :                 snprintf(db_desc_str, sizeof(db_desc_str), "%s%s%s",
    1095             :                          (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
    1096             :                                   ? "Initial "
    1097             :                                   : ""),
    1098             :                          (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
    1099             :                                   ? "More"
    1100             :                                   : ""),
    1101           0 :                          (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
    1102             :                                   ? "Master"
    1103             :                                   : "Slave"));
    1104           0 :                 json_object_string_add(json_neighbor, "dbDescStatus",
    1105             :                                        db_desc_str);
    1106             : 
    1107           0 :                 json_object_int_add(json_neighbor, "dbDescSeqNumber",
    1108           0 :                                     (unsigned long)ntohl(on->dbdesc_seqnum));
    1109             : 
    1110           0 :                 json_array = json_object_new_array();
    1111           0 :                 json_object_int_add(json_neighbor, "summaryListCount",
    1112           0 :                                     on->summary_list->count);
    1113           0 :                 for (ALL_LSDB(on->summary_list, lsa, lsanext))
    1114           0 :                         json_object_array_add(
    1115           0 :                                 json_array, json_object_new_string(lsa->name));
    1116           0 :                 json_object_object_add(json_neighbor, "summaryListLsa",
    1117             :                                        json_array);
    1118             : 
    1119           0 :                 json_array = json_object_new_array();
    1120           0 :                 json_object_int_add(json_neighbor, "requestListCount",
    1121           0 :                                     on->request_list->count);
    1122           0 :                 for (ALL_LSDB(on->request_list, lsa, lsanext))
    1123           0 :                         json_object_array_add(
    1124           0 :                                 json_array, json_object_new_string(lsa->name));
    1125           0 :                 json_object_object_add(json_neighbor, "requestListLsa",
    1126             :                                        json_array);
    1127             : 
    1128           0 :                 json_array = json_object_new_array();
    1129           0 :                 json_object_int_add(json_neighbor, "reTransListCount",
    1130           0 :                                     on->retrans_list->count);
    1131           0 :                 for (ALL_LSDB(on->retrans_list, lsa, lsanext))
    1132           0 :                         json_object_array_add(
    1133           0 :                                 json_array, json_object_new_string(lsa->name));
    1134           0 :                 json_object_object_add(json_neighbor, "reTransListLsa",
    1135             :                                        json_array);
    1136             : 
    1137             : 
    1138           0 :                 timerclear(&res);
    1139           0 :                 if (thread_is_scheduled(on->thread_send_dbdesc))
    1140           0 :                         timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
    1141           0 :                 timerstring(&res, duration, sizeof(duration));
    1142           0 :                 json_object_int_add(json_neighbor, "pendingLsaDbDescCount",
    1143           0 :                                     on->dbdesc_list->count);
    1144           0 :                 json_object_string_add(json_neighbor, "pendingLsaDbDescTime",
    1145             :                                        duration);
    1146           0 :                 json_object_string_add(
    1147             :                         json_neighbor, "dbDescSendThread",
    1148           0 :                         (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
    1149             :                                                                      : "off"));
    1150           0 :                 json_array = json_object_new_array();
    1151           0 :                 for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
    1152           0 :                         json_object_array_add(
    1153           0 :                                 json_array, json_object_new_string(lsa->name));
    1154           0 :                 json_object_object_add(json_neighbor, "pendingLsaDbDesc",
    1155             :                                        json_array);
    1156             : 
    1157           0 :                 timerclear(&res);
    1158           0 :                 if (thread_is_scheduled(on->thread_send_lsreq))
    1159           0 :                         timersub(&on->thread_send_lsreq->u.sands, &now, &res);
    1160           0 :                 timerstring(&res, duration, sizeof(duration));
    1161           0 :                 json_object_int_add(json_neighbor, "pendingLsaLsReqCount",
    1162           0 :                                     on->request_list->count);
    1163           0 :                 json_object_string_add(json_neighbor, "pendingLsaLsReqTime",
    1164             :                                        duration);
    1165           0 :                 json_object_string_add(
    1166             :                         json_neighbor, "lsReqSendThread",
    1167           0 :                         (thread_is_scheduled(on->thread_send_lsreq) ? "on"
    1168             :                                                                     : "off"));
    1169           0 :                 json_array = json_object_new_array();
    1170           0 :                 for (ALL_LSDB(on->request_list, lsa, lsanext))
    1171           0 :                         json_object_array_add(
    1172           0 :                                 json_array, json_object_new_string(lsa->name));
    1173           0 :                 json_object_object_add(json_neighbor, "pendingLsaLsReq",
    1174             :                                        json_array);
    1175             : 
    1176             : 
    1177           0 :                 timerclear(&res);
    1178           0 :                 if (thread_is_scheduled(on->thread_send_lsupdate))
    1179           0 :                         timersub(&on->thread_send_lsupdate->u.sands, &now,
    1180             :                                  &res);
    1181           0 :                 timerstring(&res, duration, sizeof(duration));
    1182           0 :                 json_object_int_add(json_neighbor, "pendingLsaLsUpdateCount",
    1183           0 :                                     on->lsupdate_list->count);
    1184           0 :                 json_object_string_add(json_neighbor, "pendingLsaLsUpdateTime",
    1185             :                                        duration);
    1186           0 :                 json_object_string_add(
    1187             :                         json_neighbor, "lsUpdateSendThread",
    1188           0 :                         (thread_is_scheduled(on->thread_send_lsupdate)
    1189             :                                  ? "on"
    1190             :                                  : "off"));
    1191           0 :                 json_array = json_object_new_array();
    1192           0 :                 for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
    1193           0 :                         json_object_array_add(
    1194           0 :                                 json_array, json_object_new_string(lsa->name));
    1195           0 :                 json_object_object_add(json_neighbor, "pendingLsaLsUpdate",
    1196             :                                        json_array);
    1197             : 
    1198           0 :                 timerclear(&res);
    1199           0 :                 if (thread_is_scheduled(on->thread_send_lsack))
    1200           0 :                         timersub(&on->thread_send_lsack->u.sands, &now, &res);
    1201           0 :                 timerstring(&res, duration, sizeof(duration));
    1202           0 :                 json_object_int_add(json_neighbor, "pendingLsaLsAckCount",
    1203           0 :                                     on->lsack_list->count);
    1204           0 :                 json_object_string_add(json_neighbor, "pendingLsaLsAckTime",
    1205             :                                        duration);
    1206           0 :                 json_object_string_add(
    1207             :                         json_neighbor, "lsAckSendThread",
    1208           0 :                         (thread_is_scheduled(on->thread_send_lsack) ? "on"
    1209             :                                                                     : "off"));
    1210           0 :                 json_array = json_object_new_array();
    1211           0 :                 for (ALL_LSDB(on->lsack_list, lsa, lsanext))
    1212           0 :                         json_object_array_add(
    1213           0 :                                 json_array, json_object_new_string(lsa->name));
    1214           0 :                 json_object_object_add(json_neighbor, "pendingLsaLsAck",
    1215             :                                        json_array);
    1216             : 
    1217           0 :                 bfd_sess_show(vty, json_neighbor, on->bfd_session);
    1218             : 
    1219           0 :                 if (on->auth_present == true) {
    1220           0 :                         json_object_string_add(json_neighbor, "authStatus",
    1221             :                                                "enabled");
    1222           0 :                         json_object_int_add(
    1223             :                                 json_neighbor, "recvdHelloHigherSeqNo",
    1224           0 :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]);
    1225           0 :                         json_object_int_add(
    1226             :                                 json_neighbor, "recvdHelloLowerSeqNo",
    1227           0 :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]);
    1228           0 :                         json_object_int_add(
    1229             :                                 json_neighbor, "recvdDBDescHigherSeqNo",
    1230           0 :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]);
    1231           0 :                         json_object_int_add(
    1232             :                                 json_neighbor, "recvdDBDescLowerSeqNo",
    1233           0 :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]);
    1234           0 :                         json_object_int_add(
    1235             :                                 json_neighbor, "recvdLSReqHigherSeqNo",
    1236           0 :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]);
    1237           0 :                         json_object_int_add(
    1238             :                                 json_neighbor, "recvdLSReqLowerSeqNo",
    1239           0 :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]);
    1240           0 :                         json_object_int_add(
    1241             :                                 json_neighbor, "recvdLSUpdHigherSeqNo",
    1242           0 :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]);
    1243           0 :                         json_object_int_add(
    1244             :                                 json_neighbor, "recvdLSUpdLowerSeqNo",
    1245           0 :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]);
    1246           0 :                         json_object_int_add(
    1247             :                                 json_neighbor, "recvdLSAckHigherSeqNo",
    1248           0 :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
    1249           0 :                         json_object_int_add(
    1250             :                                 json_neighbor, "recvdLSAckLowerSeqNo",
    1251           0 :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
    1252             :                 } else
    1253           0 :                         json_object_string_add(json_neighbor, "authStatus",
    1254             :                                                "disabled");
    1255             : 
    1256           0 :                 json_object_object_add(json, on->name, json_neighbor);
    1257             : 
    1258             :         } else {
    1259           0 :                 vty_out(vty, " Neighbor %s\n", on->name);
    1260           0 :                 vty_out(vty, "    Area %s via interface %pOI (ifindex %d)\n",
    1261           0 :                         on->ospf6_if->area->name, on->ospf6_if,
    1262           0 :                         on->ospf6_if->interface->ifindex);
    1263           0 :                 vty_out(vty, "    His IfIndex: %d Link-local address: %s\n",
    1264             :                         on->ifindex, linklocal_addr);
    1265           0 :                 vty_out(vty, "    State %s for a duration of %s\n",
    1266           0 :                         ospf6_neighbor_state_str[on->state], duration);
    1267           0 :                 vty_out(vty, "    His choice of DR/BDR %s/%s, Priority %d\n",
    1268           0 :                         drouter, bdrouter, on->priority);
    1269           0 :                 vty_out(vty, "    DbDesc status: %s%s%s SeqNum: %#lx\n",
    1270             :                         (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
    1271             :                                  ? "Initial "
    1272             :                                  : ""),
    1273             :                         (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT)
    1274             :                                  ? "More "
    1275             :                                  : ""),
    1276           0 :                         (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MSBIT)
    1277             :                                  ? "Master"
    1278             :                                  : "Slave"),
    1279           0 :                         (unsigned long)ntohl(on->dbdesc_seqnum));
    1280             : 
    1281           0 :                 vty_out(vty, "    Summary-List: %d LSAs\n",
    1282           0 :                         on->summary_list->count);
    1283           0 :                 for (ALL_LSDB(on->summary_list, lsa, lsanext))
    1284           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1285             : 
    1286           0 :                 vty_out(vty, "    Request-List: %d LSAs\n",
    1287           0 :                         on->request_list->count);
    1288           0 :                 for (ALL_LSDB(on->request_list, lsa, lsanext))
    1289           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1290             : 
    1291           0 :                 vty_out(vty, "    Retrans-List: %d LSAs\n",
    1292           0 :                         on->retrans_list->count);
    1293           0 :                 for (ALL_LSDB(on->retrans_list, lsa, lsanext))
    1294           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1295             : 
    1296           0 :                 timerclear(&res);
    1297           0 :                 if (thread_is_scheduled(on->thread_send_dbdesc))
    1298           0 :                         timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
    1299           0 :                 timerstring(&res, duration, sizeof(duration));
    1300           0 :                 vty_out(vty,
    1301             :                         "    %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
    1302           0 :                         on->dbdesc_list->count, duration,
    1303           0 :                         (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
    1304             :                                                                      : "off"));
    1305           0 :                 for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
    1306           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1307             : 
    1308           0 :                 timerclear(&res);
    1309           0 :                 if (thread_is_scheduled(on->thread_send_lsreq))
    1310           0 :                         timersub(&on->thread_send_lsreq->u.sands, &now, &res);
    1311           0 :                 timerstring(&res, duration, sizeof(duration));
    1312           0 :                 vty_out(vty,
    1313             :                         "    %d Pending LSAs for LSReq in Time %s [thread %s]\n",
    1314           0 :                         on->request_list->count, duration,
    1315           0 :                         (thread_is_scheduled(on->thread_send_lsreq) ? "on"
    1316             :                                                                     : "off"));
    1317           0 :                 for (ALL_LSDB(on->request_list, lsa, lsanext))
    1318           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1319             : 
    1320           0 :                 timerclear(&res);
    1321           0 :                 if (thread_is_scheduled(on->thread_send_lsupdate))
    1322           0 :                         timersub(&on->thread_send_lsupdate->u.sands, &now,
    1323             :                                  &res);
    1324           0 :                 timerstring(&res, duration, sizeof(duration));
    1325           0 :                 vty_out(vty,
    1326             :                         "    %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
    1327           0 :                         on->lsupdate_list->count, duration,
    1328           0 :                         (thread_is_scheduled(on->thread_send_lsupdate)
    1329             :                                  ? "on"
    1330             :                                  : "off"));
    1331           0 :                 for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
    1332           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1333             : 
    1334           0 :                 timerclear(&res);
    1335           0 :                 if (thread_is_scheduled(on->thread_send_lsack))
    1336           0 :                         timersub(&on->thread_send_lsack->u.sands, &now, &res);
    1337           0 :                 timerstring(&res, duration, sizeof(duration));
    1338           0 :                 vty_out(vty,
    1339             :                         "    %d Pending LSAs for LSAck in Time %s [thread %s]\n",
    1340           0 :                         on->lsack_list->count, duration,
    1341           0 :                         (thread_is_scheduled(on->thread_send_lsack) ? "on"
    1342             :                                                                     : "off"));
    1343           0 :                 for (ALL_LSDB(on->lsack_list, lsa, lsanext))
    1344           0 :                         vty_out(vty, "      %s\n", lsa->name);
    1345             : 
    1346           0 :                 bfd_sess_show(vty, NULL, on->bfd_session);
    1347             : 
    1348           0 :                 if (on->auth_present == true) {
    1349           0 :                         vty_out(vty, "    Authentication header present\n");
    1350           0 :                         vty_out(vty,
    1351             :                                 "\t\t\t hello        DBDesc       LSReq        LSUpd        LSAck\n");
    1352           0 :                         vty_out(vty,
    1353             :                                 "      Higher sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
    1354             :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO],
    1355             :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC],
    1356             :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ],
    1357             :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE],
    1358             :                                 on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
    1359           0 :                         vty_out(vty,
    1360             :                                 "      Lower sequence no  0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
    1361             :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO],
    1362             :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC],
    1363             :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ],
    1364             :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE],
    1365             :                                 on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
    1366             :                 } else
    1367           0 :                         vty_out(vty, "    Authentication header not present\n");
    1368             :         }
    1369           0 : }
    1370             : 
    1371          51 : static void ospf6_neighbor_show_detail_common(struct vty *vty,
    1372             :                                               struct ospf6 *ospf6, bool uj,
    1373             :                                               bool detail, bool drchoice)
    1374             : {
    1375          51 :         struct ospf6_neighbor *on;
    1376          51 :         struct ospf6_interface *oi;
    1377          51 :         struct ospf6_area *oa;
    1378          51 :         struct listnode *i, *j, *k;
    1379          51 :         json_object *json = NULL;
    1380          51 :         json_object *json_array = NULL;
    1381          51 :         void (*showfunc)(struct vty *, struct ospf6_neighbor *,
    1382             :                          json_object *json, bool use_json);
    1383             : 
    1384          51 :         if (detail)
    1385             :                 showfunc = ospf6_neighbor_show_detail;
    1386          51 :         else if (drchoice)
    1387             :                 showfunc = ospf6_neighbor_show_drchoice;
    1388             :         else
    1389          51 :                 showfunc = ospf6_neighbor_show;
    1390             : 
    1391          51 :         if (uj) {
    1392          51 :                 json = json_object_new_object();
    1393          51 :                 json_array = json_object_new_array();
    1394             :         } else {
    1395           0 :                 if (showfunc == ospf6_neighbor_show)
    1396           0 :                         vty_out(vty, "%-15s %3s %11s %8s/%-12s %11s %s[%s]\n",
    1397             :                                 "Neighbor ID", "Pri", "DeadTime", "State",
    1398             :                                 "IfState", "Duration", "I/F", "State");
    1399           0 :                 else if (showfunc == ospf6_neighbor_show_drchoice)
    1400           0 :                         vty_out(vty, "%-15s %8s/%-11s %-15s %-15s %s[%s]\n",
    1401             :                                 "RouterID", "State", "Duration", "DR", "BDR",
    1402             :                                 "I/F", "State");
    1403             :         }
    1404             : 
    1405         153 :         for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
    1406         154 :                 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
    1407         181 :                         for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
    1408          77 :                                 if (showfunc == ospf6_neighbor_show_detail)
    1409           0 :                                         (*showfunc)(vty, on, json, uj);
    1410             :                                 else
    1411          77 :                                         (*showfunc)(vty, on, json_array, uj);
    1412             :                         }
    1413             : 
    1414          51 :         if (uj) {
    1415          51 :                 if (showfunc != ospf6_neighbor_show_detail)
    1416          51 :                         json_object_object_add(json, "neighbors", json_array);
    1417             :                 else
    1418           0 :                         json_object_free(json_array);
    1419          51 :                 vty_json(vty, json);
    1420             :         }
    1421          51 : }
    1422             : 
    1423          51 : DEFUN(show_ipv6_ospf6_neighbor, show_ipv6_ospf6_neighbor_cmd,
    1424             :       "show ipv6 ospf6 [vrf <NAME|all>] neighbor [<detail|drchoice>] [json]",
    1425             :       SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
    1426             :       "All VRFs\n"
    1427             :       "Neighbor list\n"
    1428             :       "Display details\n"
    1429             :       "Display DR choices\n" JSON_STR)
    1430             : {
    1431          51 :         struct ospf6 *ospf6;
    1432          51 :         struct listnode *node;
    1433          51 :         const char *vrf_name = NULL;
    1434          51 :         bool all_vrf = false;
    1435          51 :         int idx_vrf = 0;
    1436          51 :         int idx_type = 4;
    1437          51 :         bool uj = use_json(argc, argv);
    1438          51 :         bool detail = false;
    1439          51 :         bool drchoice = false;
    1440             : 
    1441          51 :         OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
    1442             : 
    1443          51 :         if (argv_find(argv, argc, "detail", &idx_type))
    1444             :                 detail = true;
    1445          51 :         else if (argv_find(argv, argc, "drchoice", &idx_type))
    1446           0 :                 drchoice = true;
    1447             : 
    1448         102 :         for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
    1449          51 :                 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
    1450          51 :                         ospf6_neighbor_show_detail_common(vty, ospf6, uj,
    1451             :                                                           detail, drchoice);
    1452          51 :                         if (!all_vrf)
    1453             :                                 break;
    1454             :                 }
    1455             :         }
    1456             : 
    1457          51 :         OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
    1458             : 
    1459             :         return CMD_SUCCESS;
    1460             : }
    1461             : 
    1462           0 : static int ospf6_neighbor_show_common(struct vty *vty, int argc,
    1463             :                                       struct cmd_token **argv,
    1464             :                                       struct ospf6 *ospf6, int idx_ipv4,
    1465             :                                       bool uj)
    1466             : {
    1467           0 :         struct ospf6_neighbor *on;
    1468           0 :         struct ospf6_interface *oi;
    1469           0 :         struct ospf6_area *oa;
    1470           0 :         struct listnode *i, *j, *k;
    1471           0 :         void (*showfunc)(struct vty *, struct ospf6_neighbor *,
    1472             :                          json_object *json, bool use_json);
    1473           0 :         uint32_t router_id;
    1474           0 :         json_object *json = NULL;
    1475             : 
    1476           0 :         showfunc = ospf6_neighbor_show_detail;
    1477           0 :         if (uj)
    1478           0 :                 json = json_object_new_object();
    1479             : 
    1480           0 :         if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) {
    1481           0 :                 vty_out(vty, "Router-ID is not parsable: %s\n",
    1482           0 :                         argv[idx_ipv4]->arg);
    1483           0 :                 return CMD_SUCCESS;
    1484             :         }
    1485             : 
    1486           0 :         for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa))
    1487           0 :                 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
    1488           0 :                         for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on)) {
    1489           0 :                                 if (router_id == on->router_id)
    1490           0 :                                         (*showfunc)(vty, on, json, uj);
    1491             :                         }
    1492             : 
    1493           0 :         if (uj)
    1494           0 :                 vty_json(vty, json);
    1495             : 
    1496             :         return CMD_SUCCESS;
    1497             : }
    1498             : 
    1499           0 : DEFUN(show_ipv6_ospf6_neighbor_one, show_ipv6_ospf6_neighbor_one_cmd,
    1500             :       "show ipv6 ospf6 [vrf <NAME|all>] neighbor A.B.C.D [json]",
    1501             :       SHOW_STR IP6_STR OSPF6_STR VRF_CMD_HELP_STR
    1502             :       "All VRFs\n"
    1503             :       "Neighbor list\n"
    1504             :       "Specify Router-ID as IPv4 address notation\n" JSON_STR)
    1505             : {
    1506           0 :         int idx_ipv4 = 4;
    1507           0 :         struct ospf6 *ospf6;
    1508           0 :         struct listnode *node;
    1509           0 :         const char *vrf_name = NULL;
    1510           0 :         bool all_vrf = false;
    1511           0 :         int idx_vrf = 0;
    1512           0 :         bool uj = use_json(argc, argv);
    1513             : 
    1514           0 :         OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
    1515           0 :         if (idx_vrf > 0)
    1516           0 :                 idx_ipv4 += 2;
    1517             : 
    1518           0 :         for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
    1519           0 :                 if (all_vrf || strcmp(ospf6->name, vrf_name) == 0) {
    1520           0 :                         ospf6_neighbor_show_common(vty, argc, argv, ospf6,
    1521             :                                                    idx_ipv4, uj);
    1522             : 
    1523           0 :                         if (!all_vrf)
    1524             :                                 break;
    1525             :                 }
    1526             :         }
    1527             : 
    1528           0 :         OSPF6_CMD_CHECK_VRF(uj, all_vrf, ospf6);
    1529             : 
    1530             :         return CMD_SUCCESS;
    1531             : }
    1532             : 
    1533           4 : void ospf6_neighbor_init(void)
    1534             : {
    1535           4 :         install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
    1536           4 :         install_element(VIEW_NODE, &show_ipv6_ospf6_neighbor_one_cmd);
    1537             : 
    1538           4 :         install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cmd);
    1539           4 :         install_element(INTERFACE_NODE, &ipv6_ospf6_p2xp_neigh_cost_cmd);
    1540           4 :         install_element(INTERFACE_NODE,
    1541             :                         &ipv6_ospf6_p2xp_neigh_poll_interval_cmd);
    1542           4 : }
    1543             : 
    1544           0 : DEFUN (debug_ospf6_neighbor,
    1545             :        debug_ospf6_neighbor_cmd,
    1546             :        "debug ospf6 neighbor [<state|event>]",
    1547             :        DEBUG_STR
    1548             :        OSPF6_STR
    1549             :        "Debug OSPFv3 Neighbor\n"
    1550             :        "Debug OSPFv3 Neighbor State Change\n"
    1551             :        "Debug OSPFv3 Neighbor Event\n")
    1552             : {
    1553           0 :         int idx_type = 3;
    1554           0 :         unsigned char level = 0;
    1555             : 
    1556           0 :         if (argc == 4) {
    1557           0 :                 if (!strncmp(argv[idx_type]->arg, "s", 1))
    1558             :                         level = OSPF6_DEBUG_NEIGHBOR_STATE;
    1559           0 :                 else if (!strncmp(argv[idx_type]->arg, "e", 1))
    1560           0 :                         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
    1561             :         } else
    1562             :                 level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
    1563             : 
    1564           0 :         OSPF6_DEBUG_NEIGHBOR_ON(level);
    1565           0 :         return CMD_SUCCESS;
    1566             : }
    1567             : 
    1568             : 
    1569           0 : DEFUN (no_debug_ospf6_neighbor,
    1570             :        no_debug_ospf6_neighbor_cmd,
    1571             :        "no debug ospf6 neighbor [<state|event>]",
    1572             :        NO_STR
    1573             :        DEBUG_STR
    1574             :        OSPF6_STR
    1575             :        "Debug OSPFv3 Neighbor\n"
    1576             :        "Debug OSPFv3 Neighbor State Change\n"
    1577             :        "Debug OSPFv3 Neighbor Event\n")
    1578             : {
    1579           0 :         int idx_type = 4;
    1580           0 :         unsigned char level = 0;
    1581             : 
    1582           0 :         if (argc == 5) {
    1583           0 :                 if (!strncmp(argv[idx_type]->arg, "s", 1))
    1584           0 :                         level = OSPF6_DEBUG_NEIGHBOR_STATE;
    1585           0 :                 if (!strncmp(argv[idx_type]->arg, "e", 1))
    1586           0 :                         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
    1587             :         } else
    1588             :                 level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
    1589             : 
    1590           0 :         OSPF6_DEBUG_NEIGHBOR_OFF(level);
    1591           0 :         return CMD_SUCCESS;
    1592             : }
    1593             : 
    1594             : 
    1595           0 : DEFUN (no_debug_ospf6,
    1596             :        no_debug_ospf6_cmd,
    1597             :        "no debug ospf6",
    1598             :        NO_STR
    1599             :        DEBUG_STR
    1600             :        OSPF6_STR)
    1601             : {
    1602           0 :         unsigned int i;
    1603             : 
    1604           0 :         OSPF6_DEBUG_ABR_OFF();
    1605           0 :         OSPF6_DEBUG_ASBR_OFF();
    1606           0 :         OSPF6_DEBUG_BROUTER_OFF();
    1607           0 :         OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF();
    1608           0 :         OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF();
    1609           0 :         OSPF6_DEBUG_FLOODING_OFF();
    1610           0 :         OSPF6_DEBUG_INTERFACE_OFF();
    1611             : 
    1612           0 :         ospf6_lsa_debug_set_all(false);
    1613             : 
    1614           0 :         for (i = 0; i < 6; i++)
    1615           0 :                 OSPF6_DEBUG_MESSAGE_OFF(i,
    1616             :                                         OSPF6_DEBUG_NEIGHBOR_STATE
    1617             :                                                 | OSPF6_DEBUG_NEIGHBOR_EVENT);
    1618             : 
    1619           0 :         OSPF6_DEBUG_NEIGHBOR_OFF(OSPF6_DEBUG_NEIGHBOR_STATE
    1620             :                                  | OSPF6_DEBUG_NEIGHBOR_EVENT);
    1621           0 :         OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_TABLE);
    1622           0 :         OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTRA);
    1623           0 :         OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_INTER);
    1624           0 :         OSPF6_DEBUG_ROUTE_OFF(OSPF6_DEBUG_ROUTE_MEMORY);
    1625           0 :         OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_PROCESS);
    1626           0 :         OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_TIME);
    1627           0 :         OSPF6_DEBUG_SPF_OFF(OSPF6_DEBUG_SPF_DATABASE);
    1628           0 :         OSPF6_DEBUG_ZEBRA_OFF(OSPF6_DEBUG_ZEBRA_SEND | OSPF6_DEBUG_ZEBRA_RECV);
    1629             : 
    1630           0 :         return CMD_SUCCESS;
    1631             : }
    1632             : 
    1633           0 : int config_write_ospf6_debug_neighbor(struct vty *vty)
    1634             : {
    1635           0 :         if (IS_OSPF6_DEBUG_NEIGHBOR(STATE) && IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
    1636           0 :                 vty_out(vty, "debug ospf6 neighbor\n");
    1637           0 :         else if (IS_OSPF6_DEBUG_NEIGHBOR(STATE))
    1638           0 :                 vty_out(vty, "debug ospf6 neighbor state\n");
    1639           0 :         else if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
    1640           0 :                 vty_out(vty, "debug ospf6 neighbor event\n");
    1641           0 :         return 0;
    1642             : }
    1643             : 
    1644           0 : int config_write_ospf6_p2xp_neighbor(struct vty *vty,
    1645             :                                      struct ospf6_interface *oi)
    1646             : {
    1647           0 :         struct ospf6_if_p2xp_neighcfg *p2xp_cfg;
    1648             : 
    1649           0 :         frr_each (ospf6_if_p2xp_neighcfgs, &oi->p2xp_neighs, p2xp_cfg) {
    1650           0 :                 vty_out(vty, " ipv6 ospf6 neighbor %pI6\n", &p2xp_cfg->addr);
    1651             : 
    1652           0 :                 if (p2xp_cfg->poll_interval)
    1653           0 :                         vty_out(vty,
    1654             :                                 " ipv6 ospf6 neighbor %pI6 poll-interval %u\n",
    1655             :                                 &p2xp_cfg->addr, p2xp_cfg->poll_interval);
    1656             : 
    1657           0 :                 if (p2xp_cfg->cfg_cost)
    1658           0 :                         vty_out(vty, " ipv6 ospf6 neighbor %pI6 cost %u\n",
    1659             :                                 &p2xp_cfg->addr, p2xp_cfg->cost);
    1660             :         }
    1661           0 :         return 0;
    1662             : }
    1663             : 
    1664           4 : void install_element_ospf6_debug_neighbor(void)
    1665             : {
    1666           4 :         install_element(ENABLE_NODE, &debug_ospf6_neighbor_cmd);
    1667           4 :         install_element(ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
    1668           4 :         install_element(ENABLE_NODE, &no_debug_ospf6_cmd);
    1669           4 :         install_element(CONFIG_NODE, &debug_ospf6_neighbor_cmd);
    1670           4 :         install_element(CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
    1671           4 :         install_element(CONFIG_NODE, &no_debug_ospf6_cmd);
    1672           4 : }

Generated by: LCOV version v1.16-topotato