/* Delete specified OSPF neighbor from interface. */ 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); } else zlog_info("Can't find neighbor %s in the interface %s", inet_ntoa(nbr->src), IF_NAME(oi)); route_unlock_node(rn); } /* Free ospf_neighbor structure. */ ospf_nbr_free(nbr); }
/* Add self to nbr list. */ 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. */ zlog_warn( "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; }
/* Add self to nbr list. */ void ospf_nbr_add_self (struct ospf_interface *oi) { struct prefix p; struct route_node *rn; /* Initial state */ oi->nbr_self->address = *oi->address; oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); oi->nbr_self->router_id = oi->ospf->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; }
/* Delete specified OSPF neighbor from interface. */ 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); } 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); }