1/* 2 * OSPF Neighbor functions. 3 * Copyright (C) 1999, 2000 Toshiaki Takada 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published 9 * by the Free Software Foundation; either version 2, or (at your 10 * option) any later version. 11 * 12 * GNU Zebra is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Zebra; see the file COPYING. If not, write to the 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#include "linklist.h" 26#include "prefix.h" 27#include "memory.h" 28#include "command.h" 29#include "thread.h" 30#include "stream.h" 31#include "table.h" 32#include "log.h" 33 34#include "ospfd/ospfd.h" 35#include "ospfd/ospf_interface.h" 36#include "ospfd/ospf_asbr.h" 37#include "ospfd/ospf_lsa.h" 38#include "ospfd/ospf_lsdb.h" 39#include "ospfd/ospf_neighbor.h" 40#include "ospfd/ospf_nsm.h" 41#include "ospfd/ospf_packet.h" 42#include "ospfd/ospf_network.h" 43#include "ospfd/ospf_flood.h" 44#include "ospfd/ospf_dump.h" 45 46/* Fill in the the 'key' as appropriate to retrieve the entry for nbr 47 * from the ospf_interface's nbrs table. Indexed by interface address 48 * for all cases except Virtual-link interfaces, where neighbours are 49 * indexed by router-ID instead. 50 */ 51static void 52ospf_nbr_key (struct ospf_interface *oi, struct ospf_neighbor *nbr, 53 struct prefix *key) 54{ 55 key->family = AF_INET; 56 key->prefixlen = IPV4_MAX_BITLEN; 57 58 /* vlinks are indexed by router-id */ 59 if (oi->type == OSPF_IFTYPE_VIRTUALLINK) 60 key->u.prefix4 = nbr->router_id; 61 else 62 key->u.prefix4 = nbr->src; 63 return; 64} 65 66struct ospf_neighbor * 67ospf_nbr_new (struct ospf_interface *oi) 68{ 69 struct ospf_neighbor *nbr; 70 71 /* Allcate new neighbor. */ 72 nbr = XCALLOC (MTYPE_OSPF_NEIGHBOR, sizeof (struct ospf_neighbor)); 73 74 /* Relate neighbor to the interface. */ 75 nbr->oi = oi; 76 77 /* Set default values. */ 78 nbr->state = NSM_Down; 79 80 /* Set inheritance values. */ 81 nbr->v_inactivity = OSPF_IF_PARAM (oi, v_wait); 82 nbr->v_db_desc = OSPF_IF_PARAM (oi, retransmit_interval); 83 nbr->v_ls_req = OSPF_IF_PARAM (oi, retransmit_interval); 84 nbr->v_ls_upd = OSPF_IF_PARAM (oi, retransmit_interval); 85 nbr->priority = -1; 86 87 /* DD flags. */ 88 nbr->dd_flags = OSPF_DD_FLAG_MS|OSPF_DD_FLAG_M|OSPF_DD_FLAG_I; 89 90 /* Last received and sent DD. */ 91 nbr->last_send = NULL; 92 93 nbr->nbr_nbma = NULL; 94 95 ospf_lsdb_init (&nbr->db_sum); 96 ospf_lsdb_init (&nbr->ls_rxmt); 97 ospf_lsdb_init (&nbr->ls_req); 98 99 nbr->crypt_seqnum = 0; 100 101 return nbr; 102} 103 104void 105ospf_nbr_free (struct ospf_neighbor *nbr) 106{ 107 /* Free DB summary list. */ 108 if (ospf_db_summary_count (nbr)) 109 ospf_db_summary_clear (nbr); 110 /* ospf_db_summary_delete_all (nbr); */ 111 112 /* Free ls request list. */ 113 if (ospf_ls_request_count (nbr)) 114 ospf_ls_request_delete_all (nbr); 115 116 /* Free retransmit list. */ 117 if (ospf_ls_retransmit_count (nbr)) 118 ospf_ls_retransmit_clear (nbr); 119 120 /* Cleanup LSDBs. */ 121 ospf_lsdb_cleanup (&nbr->db_sum); 122 ospf_lsdb_cleanup (&nbr->ls_req); 123 ospf_lsdb_cleanup (&nbr->ls_rxmt); 124 125 /* Clear last send packet. */ 126 if (nbr->last_send) 127 ospf_packet_free (nbr->last_send); 128 129 if (nbr->nbr_nbma) 130 { 131 nbr->nbr_nbma->nbr = NULL; 132 nbr->nbr_nbma = NULL; 133 } 134 135 /* Cancel all timers. */ 136 OSPF_NSM_TIMER_OFF (nbr->t_inactivity); 137 OSPF_NSM_TIMER_OFF (nbr->t_db_desc); 138 OSPF_NSM_TIMER_OFF (nbr->t_ls_req); 139 OSPF_NSM_TIMER_OFF (nbr->t_ls_upd); 140 141 /* Cancel all events. *//* Thread lookup cost would be negligible. */ 142 thread_cancel_event (master, nbr); 143 144 XFREE (MTYPE_OSPF_NEIGHBOR, nbr); 145} 146 147/* Delete specified OSPF neighbor from interface. */ 148void 149ospf_nbr_delete (struct ospf_neighbor *nbr) 150{ 151 struct ospf_interface *oi; 152 struct route_node *rn; 153 struct prefix p; 154 155 oi = nbr->oi; 156 157 /* get appropriate prefix 'key' */ 158 ospf_nbr_key (oi, nbr, &p); 159 160 rn = route_node_lookup (oi->nbrs, &p); 161 if (rn) 162 { 163 /* If lookup for a NBR succeeds, the leaf route_node could 164 * only exist because there is (or was) a nbr there. 165 * If the nbr was deleted, the leaf route_node should have 166 * lost its last refcount too, and be deleted. 167 * Therefore a looked-up leaf route_node in nbrs table 168 * should never have NULL info. 169 */ 170 assert (rn->info); 171 172 if (rn->info) 173 { 174 rn->info = NULL; 175 route_unlock_node (rn); 176 } 177 else 178 zlog_info ("Can't find neighbor %s in the interface %s", 179 inet_ntoa (nbr->src), IF_NAME (oi)); 180 181 route_unlock_node (rn); 182 } 183 184 /* Free ospf_neighbor structure. */ 185 ospf_nbr_free (nbr); 186} 187 188/* Check myself is in the neighbor list. */ 189int 190ospf_nbr_bidirectional (struct in_addr *router_id, 191 struct in_addr *neighbors, int size) 192{ 193 int i; 194 int max; 195 196 max = size / sizeof (struct in_addr); 197 198 for (i = 0; i < max; i ++) 199 if (IPV4_ADDR_SAME (router_id, &neighbors[i])) 200 return 1; 201 202 return 0; 203} 204 205/* Add self to nbr list. */ 206void 207ospf_nbr_add_self (struct ospf_interface *oi) 208{ 209 struct prefix p; 210 struct route_node *rn; 211 212 /* Initial state */ 213 oi->nbr_self->address = *oi->address; 214 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); 215 oi->nbr_self->router_id = oi->ospf->router_id; 216 oi->nbr_self->src = oi->address->u.prefix4; 217 oi->nbr_self->state = NSM_TwoWay; 218 219 switch (oi->area->external_routing) 220 { 221 case OSPF_AREA_DEFAULT: 222 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); 223 break; 224 case OSPF_AREA_STUB: 225 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); 226 break; 227 case OSPF_AREA_NSSA: 228 UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); 229 SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); 230 break; 231 } 232 233 /* Add nbr_self to nbrs table */ 234 ospf_nbr_key (oi, oi->nbr_self, &p); 235 236 rn = route_node_get (oi->nbrs, &p); 237 if (rn->info) 238 { 239 /* There is already pseudo neighbor. */ 240 assert (oi->nbr_self == rn->info); 241 route_unlock_node (rn); 242 } 243 else 244 rn->info = oi->nbr_self; 245} 246 247/* Get neighbor count by status. 248 Specify status = 0, get all neighbor other than myself. */ 249int 250ospf_nbr_count (struct ospf_interface *oi, int state) 251{ 252 struct ospf_neighbor *nbr; 253 struct route_node *rn; 254 int count = 0; 255 256 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) 257 if ((nbr = rn->info)) 258 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) 259 if (state == 0 || nbr->state == state) 260 count++; 261 262 return count; 263} 264 265#ifdef HAVE_OPAQUE_LSA 266int 267ospf_nbr_count_opaque_capable (struct ospf_interface *oi) 268{ 269 struct ospf_neighbor *nbr; 270 struct route_node *rn; 271 int count = 0; 272 273 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) 274 if ((nbr = rn->info)) 275 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id)) 276 if (nbr->state == NSM_Full) 277 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O)) 278 count++; 279 280 return count; 281} 282#endif /* HAVE_OPAQUE_LSA */ 283 284/* lookup nbr by address - use this only if you know you must 285 * otherwise use the ospf_nbr_lookup() wrapper, which deals 286 * with virtual link neighbours 287 */ 288struct ospf_neighbor * 289ospf_nbr_lookup_by_addr (struct route_table *nbrs, 290 struct in_addr *addr) 291{ 292 struct prefix p; 293 struct route_node *rn; 294 struct ospf_neighbor *nbr; 295 296 p.family = AF_INET; 297 p.prefixlen = IPV4_MAX_BITLEN; 298 p.u.prefix4 = *addr; 299 300 rn = route_node_lookup (nbrs, &p); 301 if (! rn) 302 return NULL; 303 304 /* See comment in ospf_nbr_delete */ 305 assert (rn->info); 306 307 if (rn->info == NULL) 308 { 309 route_unlock_node (rn); 310 return NULL; 311 } 312 313 nbr = (struct ospf_neighbor *) rn->info; 314 route_unlock_node (rn); 315 316 return nbr; 317} 318 319struct ospf_neighbor * 320ospf_nbr_lookup_by_routerid (struct route_table *nbrs, 321 struct in_addr *id) 322{ 323 struct route_node *rn; 324 struct ospf_neighbor *nbr; 325 326 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 327 if ((nbr = rn->info) != NULL) 328 if (IPV4_ADDR_SAME (&nbr->router_id, id)) 329 { 330 route_unlock_node(rn); 331 return nbr; 332 } 333 334 return NULL; 335} 336 337void 338ospf_renegotiate_optional_capabilities (struct ospf *top) 339{ 340 struct listnode *node; 341 struct ospf_interface *oi; 342 struct route_table *nbrs; 343 struct route_node *rn; 344 struct ospf_neighbor *nbr; 345 346 /* At first, flush self-originated LSAs from routing domain. */ 347 ospf_flush_self_originated_lsas_now (top); 348 349 /* Revert all neighbor status to ExStart. */ 350 for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi)) 351 { 352 if ((nbrs = oi->nbrs) == NULL) 353 continue; 354 355 for (rn = route_top (nbrs); rn; rn = route_next (rn)) 356 { 357 if ((nbr = rn->info) == NULL || nbr == oi->nbr_self) 358 continue; 359 360 if (nbr->state < NSM_ExStart) 361 continue; 362 363 if (IS_DEBUG_OSPF_EVENT) 364 zlog_debug ("Renegotiate optional capabilities with neighbor(%s)", inet_ntoa (nbr->router_id)); 365 366 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch); 367 } 368 } 369 370 return; 371} 372 373 374struct ospf_neighbor * 375ospf_nbr_lookup (struct ospf_interface *oi, struct ip *iph, 376 struct ospf_header *ospfh) 377{ 378 if (oi->type == OSPF_IFTYPE_VIRTUALLINK) 379 return (ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id)); 380 else 381 return (ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src)); 382} 383 384static struct ospf_neighbor * 385ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh, 386 struct prefix *p) 387{ 388 struct ospf_neighbor *nbr; 389 390 nbr = ospf_nbr_new (oi); 391 nbr->state = NSM_Down; 392 nbr->src = p->u.prefix4; 393 memcpy (&nbr->address, p, sizeof (struct prefix)); 394 395 nbr->nbr_nbma = NULL; 396 if (oi->type == OSPF_IFTYPE_NBMA) 397 { 398 struct ospf_nbr_nbma *nbr_nbma; 399 struct listnode *node; 400 401 for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, node, nbr_nbma)) 402 { 403 if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src)) 404 { 405 nbr_nbma->nbr = nbr; 406 nbr->nbr_nbma = nbr_nbma; 407 408 if (nbr_nbma->t_poll) 409 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); 410 411 nbr->state_change = nbr_nbma->state_change + 1; 412 } 413 } 414 } 415 416 /* New nbr, save the crypto sequence number if necessary */ 417 if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC) 418 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum; 419 420 if (IS_DEBUG_OSPF_EVENT) 421 zlog_debug ("NSM[%s:%s]: start", IF_NAME (nbr->oi), 422 inet_ntoa (nbr->router_id)); 423 424 return nbr; 425} 426 427struct ospf_neighbor * 428ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh, 429 struct ip *iph, struct prefix *p) 430{ 431 struct route_node *rn; 432 struct prefix key; 433 struct ospf_neighbor *nbr; 434 435 key.family = AF_INET; 436 key.prefixlen = IPV4_MAX_BITLEN; 437 438 if (oi->type == OSPF_IFTYPE_VIRTUALLINK) 439 key.u.prefix4 = ospfh->router_id; /* index vlink nbrs by router-id */ 440 else 441 key.u.prefix4 = iph->ip_src; 442 443 rn = route_node_get (oi->nbrs, &key); 444 if (rn->info) 445 { 446 route_unlock_node (rn); 447 nbr = rn->info; 448 449 if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) 450 { 451 nbr->src = iph->ip_src; 452 memcpy (&nbr->address, p, sizeof (struct prefix)); 453 } 454 } 455 else 456 { 457 rn->info = nbr = ospf_nbr_add (oi, ospfh, p); 458 } 459 460 nbr->router_id = ospfh->router_id; 461 462 return nbr; 463} 464