]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_neighbor.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / ospfd / ospf_neighbor.c
index fc86cd09f4547a13260f0bed38c487db1f7ca4cf..a58bd93b6e8fbc0f5e167139ab8edf94f99b82c7 100644 (file)
  * for all cases except Virtual-link and PointToPoint interfaces, where
  * neighbours are indexed by router-ID instead.
  */
-static void
-ospf_nbr_key (struct ospf_interface *oi, struct ospf_neighbor *nbr,
-              struct prefix *key)
+static void ospf_nbr_key(struct ospf_interface *oi, struct ospf_neighbor *nbr,
+                        struct prefix *key)
 {
-  key->family = AF_INET;
-  key->prefixlen = IPV4_MAX_BITLEN;
-
-  /* vlinks are indexed by router-id */
-  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
-      oi->type == OSPF_IFTYPE_POINTOPOINT)
-    key->u.prefix4 = nbr->router_id;
-  else
-    key->u.prefix4 = nbr->src;
-  return;
+       key->family = AF_INET;
+       key->prefixlen = IPV4_MAX_BITLEN;
+
+       /* vlinks are indexed by router-id */
+       if (oi->type == OSPF_IFTYPE_VIRTUALLINK
+           || oi->type == OSPF_IFTYPE_POINTOPOINT)
+               key->u.prefix4 = nbr->router_id;
+       else
+               key->u.prefix4 = nbr->src;
+       return;
 }
 
-struct ospf_neighbor *
-ospf_nbr_new (struct ospf_interface *oi)
+struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi)
 {
-  struct ospf_neighbor *nbr;
+       struct ospf_neighbor *nbr;
 
-  /* Allcate new neighbor. */
-  nbr = XCALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor));
+       /* Allcate new neighbor. */
+       nbr = XCALLOC(MTYPE_OSPF_NEIGHBOR, sizeof(struct ospf_neighbor));
 
-  /* Relate neighbor to the interface. */
-  nbr->oi = oi;
+       /* Relate neighbor to the interface. */
+       nbr->oi = oi;
 
-  /* Set default values. */
-  nbr->state = NSM_Down;
+       /* Set default values. */
+       nbr->state = NSM_Down;
 
-  /* Set inheritance values. */
-  nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait);
-  nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval);
-  nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval);
-  nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval);
-  nbr->priority = -1;
+       /* Set inheritance values. */
+       nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait);
+       nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval);
+       nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval);
+       nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval);
+       nbr->priority = -1;
 
-  /* DD flags. */
-  nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I;
+       /* DD flags. */
+       nbr->dd_flags = OSPF_DD_FLAG_MS | OSPF_DD_FLAG_M | OSPF_DD_FLAG_I;
 
-  /* Last received and sent DD. */
-  nbr->last_send = NULL;
+       /* Last received and sent DD. */
+       nbr->last_send = NULL;
 
-  nbr->nbr_nbma = NULL;
+       nbr->nbr_nbma = NULL;
 
-  ospf_lsdb_init (&nbr->db_sum);
-  ospf_lsdb_init (&nbr->ls_rxmt);
-  ospf_lsdb_init (&nbr->ls_req);
+       ospf_lsdb_init(&nbr->db_sum);
+       ospf_lsdb_init(&nbr->ls_rxmt);
+       ospf_lsdb_init(&nbr->ls_req);
 
-  nbr->crypt_seqnum = 0;
+       nbr->crypt_seqnum = 0;
 
-  ospf_bfd_info_nbr_create(oi, nbr);
-  return nbr;
+       ospf_bfd_info_nbr_create(oi, nbr);
+       return nbr;
 }
 
-void
-ospf_nbr_free (struct ospf_neighbor *nbr)
+void ospf_nbr_free(struct ospf_neighbor *nbr)
 {
-  /* Free DB summary list. */
-  if (ospf_db_summary_count (nbr))
-    ospf_db_summary_clear (nbr);
-    /* ospf_db_summary_delete_all (nbr); */
-
-  /* Free ls request list. */
-  if (ospf_ls_request_count (nbr))
-    ospf_ls_request_delete_all (nbr);
-
-  /* Free retransmit list. */
-  if (ospf_ls_retransmit_count (nbr))
-    ospf_ls_retransmit_clear (nbr);
-
-  /* Cleanup LSDBs. */
-  ospf_lsdb_cleanup (&nbr->db_sum);
-  ospf_lsdb_cleanup (&nbr->ls_req);
-  ospf_lsdb_cleanup (&nbr->ls_rxmt);
-  
-  /* Clear last send packet. */
-  if (nbr->last_send)
-    ospf_packet_free (nbr->last_send);
-
-  if (nbr->nbr_nbma)
-    {
-      nbr->nbr_nbma->nbr = NULL;
-      nbr->nbr_nbma = NULL;
-    }
-
-  /* Cancel all timers. */
-  OSPF_NSM_TIMER_OFF (nbr->t_inactivity);
-  OSPF_NSM_TIMER_OFF (nbr->t_db_desc);
-  OSPF_NSM_TIMER_OFF (nbr->t_ls_req);
-  OSPF_NSM_TIMER_OFF (nbr->t_ls_upd);
-
-  /* Cancel all events. *//* Thread lookup cost would be negligible. */
-  thread_cancel_event (master, nbr);
-
-  ospf_bfd_info_free(&nbr->bfd_info);
-  XFREE (MTYPE_OSPF_NEIGHBOR, nbr);
+       /* Free DB summary list. */
+       if (ospf_db_summary_count(nbr))
+               ospf_db_summary_clear(nbr);
+       /* ospf_db_summary_delete_all (nbr); */
+
+       /* Free ls request list. */
+       if (ospf_ls_request_count(nbr))
+               ospf_ls_request_delete_all(nbr);
+
+       /* Free retransmit list. */
+       if (ospf_ls_retransmit_count(nbr))
+               ospf_ls_retransmit_clear(nbr);
+
+       /* Cleanup LSDBs. */
+       ospf_lsdb_cleanup(&nbr->db_sum);
+       ospf_lsdb_cleanup(&nbr->ls_req);
+       ospf_lsdb_cleanup(&nbr->ls_rxmt);
+
+       /* Clear last send packet. */
+       if (nbr->last_send)
+               ospf_packet_free(nbr->last_send);
+
+       if (nbr->nbr_nbma) {
+               nbr->nbr_nbma->nbr = NULL;
+               nbr->nbr_nbma = NULL;
+       }
+
+       /* Cancel all timers. */
+       OSPF_NSM_TIMER_OFF(nbr->t_inactivity);
+       OSPF_NSM_TIMER_OFF(nbr->t_db_desc);
+       OSPF_NSM_TIMER_OFF(nbr->t_ls_req);
+       OSPF_NSM_TIMER_OFF(nbr->t_ls_upd);
+
+       /* Cancel all events. */ /* Thread lookup cost would be negligible. */
+       thread_cancel_event(master, nbr);
+
+       ospf_bfd_info_free(&nbr->bfd_info);
+       XFREE(MTYPE_OSPF_NEIGHBOR, nbr);
 }
 
 /* Delete specified OSPF neighbor from interface. */
-void
-ospf_nbr_delete (struct ospf_neighbor *nbr)
+void ospf_nbr_delete(struct ospf_neighbor *nbr)
 {
-  struct ospf_interface *oi;
-  struct route_node *rn;
-  struct prefix p;
-
-  oi = nbr->oi;
-  
-  /* get appropriate prefix 'key' */
-  ospf_nbr_key (oi, nbr, &p);
-
-  rn = route_node_lookup (oi->nbrs, &p);
-  if (rn)
-    {
-      /* If lookup for a NBR succeeds, the leaf route_node could
-       * only exist because there is (or was) a nbr there.
-       * If the nbr was deleted, the leaf route_node should have
-       * lost its last refcount too, and be deleted.
-       * Therefore a looked-up leaf route_node in nbrs table
-       * should never have NULL info.
-       */
-      assert (rn->info);
-      
-      if (rn->info)
-       {
-         rn->info = NULL;
-         route_unlock_node (rn);
+       struct ospf_interface *oi;
+       struct route_node *rn;
+       struct prefix p;
+
+       oi = nbr->oi;
+
+       /* get appropriate prefix 'key' */
+       ospf_nbr_key(oi, nbr, &p);
+
+       rn = route_node_lookup(oi->nbrs, &p);
+       if (rn) {
+               /* If lookup for a NBR succeeds, the leaf route_node could
+                * only exist because there is (or was) a nbr there.
+                * If the nbr was deleted, the leaf route_node should have
+                * lost its last refcount too, and be deleted.
+                * Therefore a looked-up leaf route_node in nbrs table
+                * should never have NULL info.
+                */
+               assert(rn->info);
+
+               if (rn->info) {
+                       rn->info = NULL;
+                       route_unlock_node(rn);
+               } else
+                       zlog_info("Can't find neighbor %s in the interface %s",
+                                 inet_ntoa(nbr->src), IF_NAME(oi));
+
+               route_unlock_node(rn);
+       } else {
+               /*
+                * This neighbor was not found, but before we move on and
+                * free the neighbor structre, make sure that it was not
+                * indexed incorrectly and ended up in the "worng" place
+                */
+
+               /* Reverse the lookup rules */
+               if (oi->type == OSPF_IFTYPE_VIRTUALLINK
+                   || oi->type == OSPF_IFTYPE_POINTOPOINT)
+                       p.u.prefix4 = nbr->src;
+               else
+                       p.u.prefix4 = nbr->router_id;
+
+               rn = route_node_lookup(oi->nbrs, &p);
+               if (rn) {
+                       /* We found the neighbor!
+                        * Now make sure it is not the exact same neighbor
+                        * structure that we are about to free
+                        */
+                       if (nbr == rn->info) {
+                               /* Same neighbor, drop the reference to it */
+                               rn->info = NULL;
+                               route_unlock_node(rn);
+                       }
+                       route_unlock_node(rn);
+               }
        }
-      else
-       zlog_info ("Can't find neighbor %s in the interface %s",
-                  inet_ntoa (nbr->src), IF_NAME (oi));
-
-      route_unlock_node (rn);
-    }
-  else
-    {
-      /*
-       * This neighbor was not found, but before we move on and
-       * free the neighbor structre, make sure that it was not
-       * indexed incorrectly and ended up in the "worng" place
-       */
-
-      /* Reverse the lookup rules */
-      if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
-         oi->type == OSPF_IFTYPE_POINTOPOINT)
-       p.u.prefix4 = nbr->src;
-      else
-       p.u.prefix4 = nbr->router_id;
-
-      rn = route_node_lookup (oi->nbrs, &p);
-      if (rn){
-       /* We found the neighbor!
-        * Now make sure it is not the exact same neighbor
-        * structure that we are about to free
-        */
-       if (nbr == rn->info){
-         /* Same neighbor, drop the reference to it */
-         rn->info = NULL;
-         route_unlock_node (rn);
-       }
-       route_unlock_node (rn);
-      }
-    }
 
-  /* Free ospf_neighbor structure. */
-  ospf_nbr_free (nbr);
+       /* Free ospf_neighbor structure. */
+       ospf_nbr_free(nbr);
 }
 
 /* Check myself is in the neighbor list. */
-int
-ospf_nbr_bidirectional (struct in_addr *router_id,
-                       struct in_addr *neighbors, int size)
+int ospf_nbr_bidirectional(struct in_addr *router_id, struct in_addr *neighbors,
+                          int size)
 {
-  int i;
-  int max;
+       int i;
+       int max;
 
-  max = size / sizeof (struct in_addr);
+       max = size / sizeof(struct in_addr);
 
-  for (i = 0; i < max; i ++)
-    if (IPV4_ADDR_SAME (router_id, &neighbors[i]))
-      return 1;
+       for (i = 0; i < max; i++)
+               if (IPV4_ADDR_SAME(router_id, &neighbors[i]))
+                       return 1;
 
-  return 0;
+       return 0;
 }
 
 /* reset nbr_self */
-void
-ospf_nbr_self_reset (struct ospf_interface *oi, struct in_addr router_id)
+void ospf_nbr_self_reset(struct ospf_interface *oi, struct in_addr router_id)
 {
-  if (oi->nbr_self)
-    ospf_nbr_delete (oi->nbr_self);
+       if (oi->nbr_self)
+               ospf_nbr_delete(oi->nbr_self);
 
-  oi->nbr_self = ospf_nbr_new (oi);
-  ospf_nbr_add_self (oi, router_id);
+       oi->nbr_self = ospf_nbr_new(oi);
+       ospf_nbr_add_self(oi, router_id);
 }
 
 /* Add self to nbr list. */
-void
-ospf_nbr_add_self (struct ospf_interface *oi, struct in_addr router_id)
+void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id)
 {
-  struct prefix p;
-  struct route_node *rn;
-
-  if (!oi->nbr_self)
-    oi->nbr_self = ospf_nbr_new (oi);
-
-  /* Initial state */
-  oi->nbr_self->address = *oi->address;
-  oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
-  oi->nbr_self->router_id = router_id;
-  oi->nbr_self->src = oi->address->u.prefix4;
-  oi->nbr_self->state = NSM_TwoWay;
-  
-  switch (oi->area->external_routing)
-    {
-      case OSPF_AREA_DEFAULT:
-        SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
-        break;
-      case OSPF_AREA_STUB:
-        UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
-        break;
-      case OSPF_AREA_NSSA:
-        UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
-        SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
-        break;
-    }
-  
-  /* Add nbr_self to nbrs table */
-  ospf_nbr_key (oi, oi->nbr_self, &p);
-  
-  rn = route_node_get (oi->nbrs, &p);
-  if (rn->info)
-    {
-      /* There is already pseudo neighbor. */
-      assert (oi->nbr_self == rn->info);
-      route_unlock_node (rn);
-    }
-  else
-    rn->info = oi->nbr_self;
+       struct prefix p;
+       struct route_node *rn;
+
+       if (!oi->nbr_self)
+               oi->nbr_self = ospf_nbr_new(oi);
+
+       /* Initial state */
+       oi->nbr_self->address = *oi->address;
+       oi->nbr_self->priority = OSPF_IF_PARAM(oi, priority);
+       oi->nbr_self->router_id = router_id;
+       oi->nbr_self->src = oi->address->u.prefix4;
+       oi->nbr_self->state = NSM_TwoWay;
+
+       switch (oi->area->external_routing) {
+       case OSPF_AREA_DEFAULT:
+               SET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
+               break;
+       case OSPF_AREA_STUB:
+               UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
+               break;
+       case OSPF_AREA_NSSA:
+               UNSET_FLAG(oi->nbr_self->options, OSPF_OPTION_E);
+               SET_FLAG(oi->nbr_self->options, OSPF_OPTION_NP);
+               break;
+       }
+
+       /* Add nbr_self to nbrs table */
+       ospf_nbr_key(oi, oi->nbr_self, &p);
+
+       rn = route_node_get(oi->nbrs, &p);
+       if (rn->info) {
+               /* There is already pseudo neighbor. */
+               if (IS_DEBUG_OSPF_EVENT)
+                       zlog_debug(
+                               "router_id %s already present in neighbor table. node refcount %u",
+                               inet_ntoa(router_id), rn->lock);
+               route_unlock_node(rn);
+       } else
+               rn->info = oi->nbr_self;
 }
 
 /* Get neighbor count by status.
    Specify status = 0, get all neighbor other than myself. */
-int
-ospf_nbr_count (struct ospf_interface *oi, int state)
+int ospf_nbr_count(struct ospf_interface *oi, int state)
 {
-  struct ospf_neighbor *nbr;
-  struct route_node *rn;
-  int count = 0;
-
-  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info))
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
-       if (state == 0 || nbr->state == state)
-         count++;
-
-  return count;
+       struct ospf_neighbor *nbr;
+       struct route_node *rn;
+       int count = 0;
+
+       for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
+               if ((nbr = rn->info))
+                       if (!IPV4_ADDR_SAME(&nbr->router_id,
+                                           &oi->ospf->router_id))
+                               if (state == 0 || nbr->state == state)
+                                       count++;
+
+       return count;
 }
 
-int
-ospf_nbr_count_opaque_capable (struct ospf_interface *oi)
+int ospf_nbr_count_opaque_capable(struct ospf_interface *oi)
 {
-  struct ospf_neighbor *nbr;
-  struct route_node *rn;
-  int count = 0;
-
-  for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info))
-      if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
-       if (nbr->state == NSM_Full)
-         if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
-           count++;
-
-  return count;
+       struct ospf_neighbor *nbr;
+       struct route_node *rn;
+       int count = 0;
+
+       for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
+               if ((nbr = rn->info))
+                       if (!IPV4_ADDR_SAME(&nbr->router_id,
+                                           &oi->ospf->router_id))
+                               if (nbr->state == NSM_Full)
+                                       if (CHECK_FLAG(nbr->options,
+                                                      OSPF_OPTION_O))
+                                               count++;
+
+       return count;
 }
 
 /* lookup nbr by address - use this only if you know you must
  * otherwise use the ospf_nbr_lookup() wrapper, which deals
  * with virtual link and PointToPoint neighbours
  */
-struct ospf_neighbor *
-ospf_nbr_lookup_by_addr (struct route_table *nbrs,
-                        struct in_addr *addr)
+struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *nbrs,
+                                             struct in_addr *addr)
 {
-  struct prefix p;
-  struct route_node *rn;
-  struct ospf_neighbor *nbr;
-
-  p.family = AF_INET;
-  p.prefixlen = IPV4_MAX_BITLEN;
-  p.u.prefix4 = *addr;
-
-  rn = route_node_lookup (nbrs, &p);
-  if (! rn)
-    return NULL;
-  
-  /* See comment in ospf_nbr_delete */
-  assert (rn->info);
-
-  if (rn->info == NULL)
-    {
-      route_unlock_node (rn);
-      return NULL;
-    }
-
-  nbr = (struct ospf_neighbor *) rn->info;
-  route_unlock_node (rn);
-
-  return nbr;
+       struct prefix p;
+       struct route_node *rn;
+       struct ospf_neighbor *nbr;
+
+       p.family = AF_INET;
+       p.prefixlen = IPV4_MAX_BITLEN;
+       p.u.prefix4 = *addr;
+
+       rn = route_node_lookup(nbrs, &p);
+       if (!rn)
+               return NULL;
+
+       /* See comment in ospf_nbr_delete */
+       assert(rn->info);
+
+       if (rn->info == NULL) {
+               route_unlock_node(rn);
+               return NULL;
+       }
+
+       nbr = (struct ospf_neighbor *)rn->info;
+       route_unlock_node(rn);
+
+       return nbr;
 }
 
-struct ospf_neighbor *
-ospf_nbr_lookup_by_routerid (struct route_table *nbrs,
-                            struct in_addr *id)
+struct ospf_neighbor *ospf_nbr_lookup_by_routerid(struct route_table *nbrs,
+                                                 struct in_addr *id)
 {
-  struct route_node *rn;
-  struct ospf_neighbor *nbr;
-
-  for (rn = route_top (nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL)
-      if (IPV4_ADDR_SAME (&nbr->router_id, id))
-       {
-         route_unlock_node(rn);
-         return nbr;
+       struct route_node *rn;
+       struct ospf_neighbor *nbr;
+
+       for (rn = route_top(nbrs); rn; rn = route_next(rn))
+               if ((nbr = rn->info) != NULL)
+                       if (IPV4_ADDR_SAME(&nbr->router_id, id)) {
+                               route_unlock_node(rn);
+                               return nbr;
+                       }
+
+       return NULL;
+}
+
+void ospf_renegotiate_optional_capabilities(struct ospf *top)
+{
+       struct listnode *node;
+       struct ospf_interface *oi;
+       struct route_table *nbrs;
+       struct route_node *rn;
+       struct ospf_neighbor *nbr;
+
+       /* At first, flush self-originated LSAs from routing domain. */
+       ospf_flush_self_originated_lsas_now(top);
+
+       /* Revert all neighbor status to ExStart. */
+       for (ALL_LIST_ELEMENTS_RO(top->oiflist, node, oi)) {
+               if ((nbrs = oi->nbrs) == NULL)
+                       continue;
+
+               for (rn = route_top(nbrs); rn; rn = route_next(rn)) {
+                       if ((nbr = rn->info) == NULL || nbr == oi->nbr_self)
+                               continue;
+
+                       if (nbr->state < NSM_ExStart)
+                               continue;
+
+                       if (IS_DEBUG_OSPF_EVENT)
+                               zlog_debug(
+                                       "Renegotiate optional capabilities with neighbor(%s)",
+                                       inet_ntoa(nbr->router_id));
+
+                       OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
+               }
        }
 
-  return NULL;
+       return;
 }
 
-void
-ospf_renegotiate_optional_capabilities (struct ospf *top)
+
+struct ospf_neighbor *ospf_nbr_lookup(struct ospf_interface *oi, struct ip *iph,
+                                     struct ospf_header *ospfh)
 {
-  struct listnode *node;
-  struct ospf_interface *oi;
-  struct route_table *nbrs;
-  struct route_node *rn;
-  struct ospf_neighbor *nbr;
+       if (oi->type == OSPF_IFTYPE_VIRTUALLINK
+           || oi->type == OSPF_IFTYPE_POINTOPOINT)
+               return (ospf_nbr_lookup_by_routerid(oi->nbrs,
+                                                   &ospfh->router_id));
+       else
+               return (ospf_nbr_lookup_by_addr(oi->nbrs, &iph->ip_src));
+}
 
-  /* At first, flush self-originated LSAs from routing domain. */
-  ospf_flush_self_originated_lsas_now (top);
+static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi,
+                                         struct ospf_header *ospfh,
+                                         struct prefix *p)
+{
+       struct ospf_neighbor *nbr;
 
-  /* Revert all neighbor status to ExStart. */
-  for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi))
-    {
-      if ((nbrs = oi->nbrs) == NULL)
-        continue;
+       nbr = ospf_nbr_new(oi);
+       nbr->state = NSM_Down;
+       nbr->src = p->u.prefix4;
+       memcpy(&nbr->address, p, sizeof(struct prefix));
 
-      for (rn = route_top (nbrs); rn; rn = route_next (rn))
-        {
-          if ((nbr = rn->info) == NULL || nbr == oi->nbr_self)
-            continue;
+       nbr->nbr_nbma = NULL;
+       if (oi->type == OSPF_IFTYPE_NBMA) {
+               struct ospf_nbr_nbma *nbr_nbma;
+               struct listnode *node;
 
-          if (nbr->state < NSM_ExStart)
-            continue;
+               for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, node, nbr_nbma)) {
+                       if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src)) {
+                               nbr_nbma->nbr = nbr;
+                               nbr->nbr_nbma = nbr_nbma;
 
-          if (IS_DEBUG_OSPF_EVENT)
-            zlog_debug ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id));
+                               if (nbr_nbma->t_poll)
+                                       OSPF_POLL_TIMER_OFF(nbr_nbma->t_poll);
 
-          OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
-        }
-    }
+                               nbr->state_change = nbr_nbma->state_change + 1;
+                       }
+               }
+       }
 
-  return;
-}
+       /* New nbr, save the crypto sequence number if necessary */
+       if (ntohs(ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
+               nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
 
+       if (IS_DEBUG_OSPF_EVENT)
+               zlog_debug("NSM[%s:%s]: start", IF_NAME(nbr->oi),
+                          inet_ntoa(nbr->router_id));
 
-struct ospf_neighbor *
-ospf_nbr_lookup (struct ospf_interface *oi, struct ip *iph,
-                 struct ospf_header *ospfh)
-{
-  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
-      oi->type == OSPF_IFTYPE_POINTOPOINT)
-    return (ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id));
-  else
-    return (ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src));
+       return nbr;
 }
 
-static struct ospf_neighbor *
-ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh,
-              struct prefix *p)
+struct ospf_neighbor *ospf_nbr_get(struct ospf_interface *oi,
+                                  struct ospf_header *ospfh, struct ip *iph,
+                                  struct prefix *p)
 {
-  struct ospf_neighbor *nbr;
-  
-  nbr = ospf_nbr_new (oi);
-  nbr->state = NSM_Down;
-  nbr->src = p->u.prefix4;
-  memcpy (&nbr->address, p, sizeof (struct prefix));
-
-  nbr->nbr_nbma = NULL;
-  if (oi->type == OSPF_IFTYPE_NBMA)
-    {
-      struct ospf_nbr_nbma *nbr_nbma;
-      struct listnode *node;
-
-      for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, node, nbr_nbma))
-        {
-          if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src))
-            {
-              nbr_nbma->nbr = nbr;
-              nbr->nbr_nbma = nbr_nbma;
-
-              if (nbr_nbma->t_poll)
-                OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
-
-              nbr->state_change = nbr_nbma->state_change + 1;
-            }
-        }
-    }
-      
-  /* New nbr, save the crypto sequence number if necessary */
-  if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
-    nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
-  
-  if (IS_DEBUG_OSPF_EVENT)
-    zlog_debug ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
-               inet_ntoa (nbr->router_id));
-  
-  return nbr;
-}
+       struct route_node *rn;
+       struct prefix key;
+       struct ospf_neighbor *nbr;
+
+       key.family = AF_INET;
+       key.prefixlen = IPV4_MAX_BITLEN;
+
+       if (oi->type == OSPF_IFTYPE_VIRTUALLINK
+           || oi->type == OSPF_IFTYPE_POINTOPOINT)
+               key.u.prefix4 = ospfh->router_id; /* index vlink and ptp nbrs by
+                                                    router-id */
+       else
+               key.u.prefix4 = iph->ip_src;
+
+       rn = route_node_get(oi->nbrs, &key);
+       if (rn->info) {
+               route_unlock_node(rn);
+               nbr = rn->info;
+
+               if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) {
+                       nbr->src = iph->ip_src;
+                       memcpy(&nbr->address, p, sizeof(struct prefix));
+               }
+       } else {
+               rn->info = nbr = ospf_nbr_add(oi, ospfh, p);
+       }
 
-struct ospf_neighbor *
-ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh,
-              struct ip *iph, struct prefix *p)
-{
-  struct route_node *rn;
-  struct prefix key;
-  struct ospf_neighbor *nbr;
-  
-  key.family = AF_INET;
-  key.prefixlen = IPV4_MAX_BITLEN;
-
-  if (oi->type == OSPF_IFTYPE_VIRTUALLINK ||
-      oi->type == OSPF_IFTYPE_POINTOPOINT)
-    key.u.prefix4 = ospfh->router_id;/* index vlink and ptp nbrs by router-id */
-  else
-    key.u.prefix4 = iph->ip_src;
-
-  rn = route_node_get (oi->nbrs, &key);
-  if (rn->info)
-    {
-      route_unlock_node (rn);
-      nbr = rn->info;
-      
-      if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
-        {
-          nbr->src = iph->ip_src;
-          memcpy (&nbr->address, p, sizeof (struct prefix));
-        }
-    }
-  else
-    {
-      rn->info = nbr = ospf_nbr_add (oi, ospfh, p);
-    }
-  
-  nbr->router_id = ospfh->router_id;
-
-  return nbr;
+       nbr->router_id = ospfh->router_id;
+
+       return nbr;
 }