1/* 2 * OSPF Interface 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 "thread.h" 26#include "linklist.h" 27#include "prefix.h" 28#include "if.h" 29#include "table.h" 30#include "memory.h" 31#include "command.h" 32#include "stream.h" 33#include "log.h" 34 35#include "ospfd/ospf_spf.h" 36#include "ospfd/ospf_interface.h" 37#include "ospfd/ospf_ism.h" 38#include "ospfd/ospf_asbr.h" 39#include "ospfd/ospf_lsa.h" 40#include "ospfd/ospf_lsdb.h" 41#include "ospfd/ospf_neighbor.h" 42#include "ospfd/ospf_nsm.h" 43#include "ospfd/ospf_packet.h" 44#include "ospfd/ospf_abr.h" 45#include "ospfd/ospfd.h" 46#include "ospfd/ospf_network.h" 47#include "ospfd/ospf_dump.h" 48#ifdef HAVE_SNMP 49#include "ospfd/ospf_snmp.h" 50#endif /* HAVE_SNMP */ 51 52 53int 54ospf_if_get_output_cost (struct ospf_interface *oi) 55{ 56 /* If all else fails, use default OSPF cost */ 57 u_int32_t cost; 58 u_int32_t bw, refbw; 59 60 bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH; 61 refbw = ospf_top ? ospf_top->ref_bandwidth : OSPF_DEFAULT_REF_BANDWIDTH; 62 63 /* A specifed ip ospf cost overrides a calculated one. */ 64 if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) || 65 OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd)) 66 cost = OSPF_IF_PARAM (oi, output_cost_cmd); 67 /* See if a cost can be calculated from the zebra processes 68 interface bandwidth field. */ 69 else 70 { 71 cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5); 72 if (cost < 1) 73 cost = 1; 74 else if (cost > 65535) 75 cost = 65535; 76 } 77 78 return cost; 79} 80 81void 82ospf_if_recalculate_output_cost (struct interface *ifp) 83{ 84 u_int32_t newcost; 85 struct route_node *rn; 86 87 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) 88 { 89 struct ospf_interface *oi; 90 91 if ( (oi = rn->info) == NULL) 92 continue; 93 94 newcost = ospf_if_get_output_cost (oi); 95 96 /* Is actual output cost changed? */ 97 if (oi->output_cost != newcost) 98 { 99 oi->output_cost = newcost; 100 ospf_router_lsa_timer_add (oi->area); 101 } 102 } 103} 104 105void 106ospf_if_reset_variables (struct ospf_interface *oi) 107{ 108 /* Set default values. */ 109 /* don't clear this flag. oi->flag = OSPF_IF_DISABLE; */ 110 111 if (oi->vl_data) 112 oi->type = OSPF_IFTYPE_VIRTUALLINK; 113 else 114 /* preserve network-type */ 115 if (oi->type != OSPF_IFTYPE_NBMA) 116 oi->type = OSPF_IFTYPE_BROADCAST; 117 118 oi->state = ISM_Down; 119 120 oi->crypt_seqnum = 0; 121 122 /* This must be short, (less than RxmtInterval) 123 - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being 124 held back for too long - MAG */ 125 oi->v_ls_ack = 1; 126} 127 128void 129ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi) 130{ 131 struct route_node *rn; 132 struct prefix p; 133 134 p = *oi->address; 135 p.prefixlen = IPV4_MAX_PREFIXLEN; 136 137 rn = route_node_get (IF_OIFS (ifp), &p); 138 assert (! rn->info); 139 rn->info = oi; 140} 141 142void 143ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi) 144{ 145 struct route_node *rn; 146 struct prefix p; 147 148 p = *oi->address; 149 p.prefixlen = IPV4_MAX_PREFIXLEN; 150 151 rn = route_node_lookup (IF_OIFS (oi->ifp), &p); 152 assert (rn); 153 assert (rn->info); 154 rn->info = NULL; 155 route_unlock_node (rn); 156 route_unlock_node (rn); 157} 158 159struct ospf_interface * 160ospf_if_new (struct interface *ifp, struct prefix *p) 161{ 162 struct ospf_interface *oi; 163 164 oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface)); 165 memset (oi, 0, sizeof (struct ospf_interface)); 166 167 /* Set zebra interface pointer. */ 168 oi->ifp = ifp; 169 oi->address = p; 170 171 ospf_add_to_if (ifp, oi); 172 listnode_add (ospf_top->oiflist, oi); 173 174 /* Clear self-originated network-LSA. */ 175 oi->network_lsa_self = NULL; 176 177 /* Initialize neighbor list. */ 178 oi->nbrs = route_table_init (); 179 180 /* Initialize static neighbor list. */ 181 oi->nbr_nbma = list_new (); 182 183 /* Initialize Link State Acknowledgment list. */ 184 oi->ls_ack = list_new (); 185 oi->ls_ack_direct.ls_ack = list_new (); 186 187 /* Set default values. */ 188 ospf_if_reset_variables (oi); 189 190 /* Add pseudo neighbor. */ 191 oi->nbr_self = ospf_nbr_new (oi); 192 oi->nbr_self->state = NSM_TwoWay; 193 /* oi->nbr_self->router_id = ospf_top->router_id; */ 194 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); 195 oi->nbr_self->options = OSPF_OPTION_E; 196 197 oi->ls_upd_queue = route_table_init (); 198 oi->t_ls_upd_event = NULL; 199 oi->t_ls_ack_direct = NULL; 200 201#ifdef HAVE_OPAQUE_LSA 202 ospf_opaque_type9_lsa_init (oi); 203#endif /* HAVE_OPAQUE_LSA */ 204 205 oi->ospf = ospf_top; 206 207 return oi; 208} 209 210/* Restore an interface to its pre UP state 211 Used from ism_interface_down only */ 212void 213ospf_if_cleanup (struct ospf_interface *oi) 214{ 215 struct route_node *rn; 216 listnode node; 217 struct ospf_neighbor *nbr; 218 219 /* oi->nbrs and oi->nbr_nbma should be deletete on InterafceDown event */ 220 /* delete all static neighbors attached to this interface */ 221 for (node = listhead (oi->nbr_nbma); node; ) 222 { 223 struct ospf_nbr_nbma *nbr_nbma = getdata (node); 224 nextnode (node); 225 226 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll); 227 228 if (nbr_nbma->nbr) 229 { 230 nbr_nbma->nbr->nbr_nbma = NULL; 231 nbr_nbma->nbr = NULL; 232 } 233 234 nbr_nbma->oi = NULL; 235 236 listnode_delete (oi->nbr_nbma, nbr_nbma); 237 } 238 239 /* send Neighbor event KillNbr to all associated neighbors. */ 240 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) 241 if ((nbr = rn->info) != NULL) 242 if (nbr != oi->nbr_self) 243 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr); 244 245 /* Cleanup Link State Acknowlegdment list. */ 246 for (node = listhead (oi->ls_ack); node; nextnode (node)) 247 ospf_lsa_unlock (node->data); 248 list_delete_all_node (oi->ls_ack); 249 250 oi->crypt_seqnum = 0; 251 252 /* Empty link state update queue */ 253 ospf_ls_upd_queue_empty (oi); 254 255 /* Handle pseudo neighbor. */ 256 ospf_nbr_delete (oi->nbr_self); 257 oi->nbr_self = ospf_nbr_new (oi); 258 oi->nbr_self->state = NSM_TwoWay; 259 oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); 260 oi->nbr_self->options = OSPF_OPTION_E; 261 262 ospf_lsa_unlock (oi->network_lsa_self); 263 oi->network_lsa_self = NULL; 264 OSPF_TIMER_OFF (oi->t_network_lsa_self); 265} 266 267void 268ospf_if_free (struct ospf_interface *oi) 269{ 270 ospf_if_down (oi); 271 272 assert (oi->state == ISM_Down); 273 274#ifdef HAVE_OPAQUE_LSA 275 ospf_opaque_type9_lsa_term (oi); 276#endif /* HAVE_OPAQUE_LSA */ 277 278 /* Free Pseudo Neighbour */ 279 ospf_nbr_delete (oi->nbr_self); 280 281 route_table_finish (oi->nbrs); 282 route_table_finish (oi->ls_upd_queue); 283 284 /* Free any lists that should be freed */ 285 list_free (oi->nbr_nbma); 286 287 list_free (oi->ls_ack); 288 list_free (oi->ls_ack_direct.ls_ack); 289 290 ospf_delete_from_if (oi->ifp, oi); 291 292 listnode_delete (ospf_top->oiflist, oi); 293 listnode_delete (oi->area->oiflist, oi); 294 295 memset (oi, 0, sizeof (*oi)); 296 XFREE (MTYPE_OSPF_IF, oi); 297} 298 299 300/* 301* check if interface with given address is configured and 302* return it if yes. 303*/ 304struct ospf_interface * 305ospf_if_is_configured (struct in_addr *address) 306{ 307 listnode node; 308 struct ospf_interface *oi; 309 struct prefix *addr; 310 311 for (node = listhead (ospf_top->oiflist); node; nextnode (node)) 312 if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK) 313 { 314 if (oi->type == OSPF_IFTYPE_POINTOPOINT) 315 addr = oi->connected->destination; 316 else 317 addr = oi->address; 318 319 if (IPV4_ADDR_SAME (address, &addr->u.prefix4)) 320 return oi; 321 } 322 323 return NULL; 324} 325 326int 327ospf_if_is_up (struct ospf_interface *oi) 328{ 329 return if_is_up (oi->ifp); 330} 331 332struct ospf_interface * 333ospf_if_lookup_by_local_addr (struct interface *ifp, struct in_addr address) 334{ 335 listnode node; 336 struct ospf_interface *oi; 337 338 for (node = listhead (ospf_top->oiflist); node; nextnode (node)) 339 if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK) 340 { 341 if (ifp && oi->ifp != ifp) 342 continue; 343 344 if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4)) 345 return oi; 346 } 347 348 return NULL; 349} 350 351struct ospf_interface * 352ospf_if_lookup_by_prefix (struct prefix_ipv4 *p) 353{ 354 listnode node; 355 struct ospf_interface *oi; 356 struct prefix ptmp; 357 358 /* Check each Interface. */ 359 for (node = listhead (ospf_top->oiflist); node; nextnode (node)) { 360 if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK) 361 { 362 if (oi->type == OSPF_IFTYPE_POINTOPOINT) { 363 prefix_copy (&ptmp, oi->connected->destination); 364 ptmp.prefixlen = IPV4_MAX_BITLEN; 365 } 366 else 367 prefix_copy (&ptmp, oi->address); 368 369 apply_mask (&ptmp); 370 if (prefix_same (&ptmp, (struct prefix *) p)) 371 return oi; 372 } 373 } 374 return NULL; 375} 376 377/* determine receiving interface by source of packet */ 378struct ospf_interface * 379ospf_if_lookup_recv_interface (struct in_addr src) 380{ 381 listnode node; 382 struct prefix_ipv4 addr; 383 struct ospf_interface *oi, *match; 384 385 addr.family = AF_INET; 386 addr.prefix = src; 387 addr.prefixlen = IPV4_MAX_BITLEN; 388 389 match = NULL; 390 391 for (node = listhead (ospf_top->oiflist); node; nextnode (node)) 392 { 393 oi = getdata (node); 394 395 if (oi->type == OSPF_IFTYPE_VIRTUALLINK) 396 continue; 397 398 if (oi->type == OSPF_IFTYPE_POINTOPOINT) 399 { 400 if (IPV4_ADDR_SAME (&oi->connected->destination->u.prefix4, &src)) 401 return oi; 402 } 403 else 404 { 405 if (prefix_match (oi->address, (struct prefix *) &addr)) 406 match = oi; 407 } 408 } 409 410 return match; 411} 412 413void 414ospf_if_stream_set (struct ospf_interface *oi) 415{ 416 /* set output fifo queue. */ 417 if (oi->obuf == NULL) 418 oi->obuf = ospf_fifo_new (); 419} 420 421void 422ospf_if_stream_unset (struct ospf_interface *oi) 423{ 424 if (oi->obuf) 425 { 426 ospf_fifo_free (oi->obuf); 427 oi->obuf = NULL; 428 429 if (oi->on_write_q) 430 { 431 listnode_delete (ospf_top->oi_write_q, oi); 432 oi->on_write_q = 0; 433 } 434 } 435} 436 437struct ospf_if_params * 438ospf_new_if_params () 439{ 440 struct ospf_if_params *oip; 441 442 oip = XMALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params)); 443 memset (oip, 0, sizeof (struct ospf_if_params)); 444 445 if (!oip) 446 return NULL; 447 448 memset (oip, 0, sizeof (struct ospf_if_params)); 449 450 UNSET_IF_PARAM (oip, output_cost_cmd); 451 UNSET_IF_PARAM (oip, transmit_delay); 452 UNSET_IF_PARAM (oip, retransmit_interval); 453 UNSET_IF_PARAM (oip, passive_interface); 454 UNSET_IF_PARAM (oip, v_hello); 455 UNSET_IF_PARAM (oip, v_wait); 456 UNSET_IF_PARAM (oip, priority); 457 UNSET_IF_PARAM (oip, type); 458 UNSET_IF_PARAM (oip, auth_simple); 459 UNSET_IF_PARAM (oip, auth_crypt); 460 UNSET_IF_PARAM (oip, auth_type); 461 462 oip->auth_crypt = list_new (); 463 464 return oip; 465} 466 467void 468ospf_del_if_params (struct ospf_if_params *oip) 469{ 470 list_delete (oip->auth_crypt); 471 XFREE (MTYPE_OSPF_IF_PARAMS, oip); 472} 473 474void 475ospf_free_if_params (struct interface *ifp, struct in_addr addr) 476{ 477 struct ospf_if_params *oip; 478 struct prefix_ipv4 p; 479 struct route_node *rn; 480 p.prefixlen = IPV4_MAX_PREFIXLEN; 481 p.prefix = addr; 482 rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); 483 if (!rn || !rn->info) 484 return; 485 486 oip = rn->info; 487 route_unlock_node (rn); 488 489 if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) && 490 !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) && 491 !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) && 492 !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) && 493 !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) && 494 !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) && 495 !OSPF_IF_PARAM_CONFIGURED (oip, priority) && 496 !OSPF_IF_PARAM_CONFIGURED (oip, type) && 497 !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) && 498 !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) && 499 listcount (oip->auth_crypt) == 0) 500 { 501 ospf_del_if_params (oip); 502 rn->info = NULL; 503 route_unlock_node (rn); 504 } 505} 506 507struct ospf_if_params * 508ospf_lookup_if_params (struct interface *ifp, struct in_addr addr) 509{ 510 struct prefix_ipv4 p; 511 struct route_node *rn; 512 513 p.prefixlen = IPV4_MAX_PREFIXLEN; 514 p.prefix = addr; 515 516 rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); 517 518 if (rn) 519 { 520 route_unlock_node (rn); 521 return rn->info; 522 } 523 524 return NULL; 525} 526 527struct ospf_if_params * 528ospf_get_if_params (struct interface *ifp, struct in_addr addr) 529{ 530 struct prefix_ipv4 p; 531 struct route_node *rn; 532 533 p.family = AF_INET; 534 p.prefixlen = IPV4_MAX_PREFIXLEN; 535 p.prefix = addr; 536 537 rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p); 538 539 if (rn->info == NULL) 540 rn->info = ospf_new_if_params (); 541 else 542 route_unlock_node (rn); 543 544 return rn->info; 545} 546 547void 548ospf_if_update_params (struct interface *ifp, struct in_addr addr) 549{ 550 struct route_node *rn; 551 struct ospf_interface *oi; 552 553 for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) 554 { 555 if ((oi = rn->info) == NULL) 556 continue; 557 558 if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr)) 559 oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); 560 } 561} 562 563int 564ospf_if_new_hook (struct interface *ifp) 565{ 566 int rc = 0; 567 568 ifp->info = XMALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info)); 569 memset (ifp->info, 0, sizeof (struct ospf_if_info)); 570 571 IF_OIFS (ifp) = route_table_init (); 572 IF_OIFS_PARAMS (ifp) = route_table_init (); 573 574 IF_DEF_PARAMS (ifp) = ospf_new_if_params (); 575 576 SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay); 577 IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; 578 579 SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval); 580 IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; 581 582 SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority); 583 IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT; 584 585 SET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface); 586 IF_DEF_PARAMS (ifp)->passive_interface = OSPF_IF_ACTIVE; 587 588 SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello); 589 IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; 590 591 SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait); 592 IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT; 593 594 SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple); 595 memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE); 596 597 SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_crypt); 598 IF_DEF_PARAMS (ifp)->auth_crypt = list_new (); 599 600 SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type); 601 IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET; 602 603#ifdef HAVE_OPAQUE_LSA 604 rc = ospf_opaque_new_if (ifp); 605#endif /* HAVE_OPAQUE_LSA */ 606 return rc; 607} 608 609int 610ospf_if_delete_hook (struct interface *ifp) 611{ 612 int rc = 0; 613#ifdef HAVE_OPAQUE_LSA 614 rc = ospf_opaque_del_if (ifp); 615#endif /* HAVE_OPAQUE_LSA */ 616 route_table_finish (IF_OIFS (ifp)); 617 route_table_finish (IF_OIFS_PARAMS (ifp)); 618 XFREE (MTYPE_OSPF_IF_INFO, ifp->info); 619 ifp->info = NULL; 620 621 return rc; 622} 623 624int 625ospf_if_is_enable (struct ospf_interface *oi) 626{ 627 if (!if_is_loopback (oi->ifp)) 628 if (if_is_up (oi->ifp)) 629 return 1; 630 631 return 0; 632} 633 634int 635ospf_if_up (struct ospf_interface *oi) 636{ 637 if (oi == NULL) 638 return 0; 639 640 if (oi->type == OSPF_IFTYPE_LOOPBACK) 641 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd); 642 else 643 { 644 if (oi->type != OSPF_IFTYPE_VIRTUALLINK) 645 ospf_if_add_allspfrouters (ospf_top, oi->address, oi->ifp->ifindex); 646 ospf_if_stream_set (oi); 647 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp); 648 } 649 650 return 1; 651} 652 653int 654ospf_if_down (struct ospf_interface *oi) 655{ 656 if (oi == NULL) 657 return 0; 658 659 OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); 660 /* Shutdown packet reception and sending */ 661 ospf_if_stream_unset (oi); 662 if (oi->type != OSPF_IFTYPE_VIRTUALLINK) 663 ospf_if_drop_allspfrouters (ospf_top, oi->address, oi->ifp->ifindex); 664 665 666 return 1; 667} 668 669 670/* Virtual Link related functions. */ 671 672struct ospf_vl_data * 673ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer) 674{ 675 struct ospf_vl_data *vl_data; 676 677 vl_data = XMALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data)); 678 memset (vl_data, 0, sizeof (struct ospf_vl_data)); 679 680 vl_data->vl_peer.s_addr = vl_peer.s_addr; 681 vl_data->vl_area_id = area->area_id; 682 vl_data->format = area->format; 683 684 return vl_data; 685} 686 687void 688ospf_vl_data_free (struct ospf_vl_data *vl_data) 689{ 690 XFREE (MTYPE_OSPF_VL_DATA, vl_data); 691} 692 693u_int vlink_count = 0; 694 695struct ospf_interface * 696ospf_vl_new (struct ospf_vl_data *vl_data) 697{ 698 struct ospf_interface * voi; 699 struct interface * vi; 700 char ifname[INTERFACE_NAMSIZ + 1]; 701 struct ospf_area *area; 702 struct in_addr area_id; 703 struct connected *co; 704 struct prefix_ipv4 *p; 705 706 if (IS_DEBUG_OSPF_EVENT) 707 zlog_info ("ospf_vl_new(): Start"); 708 if (vlink_count == OSPF_VL_MAX_COUNT) 709 { 710 if (IS_DEBUG_OSPF_EVENT) 711 zlog_info ("ospf_vl_new(): Alarm: " 712 "cannot create more than OSPF_MAX_VL_COUNT virtual links"); 713 return NULL; 714 } 715 716 if (IS_DEBUG_OSPF_EVENT) 717 zlog_info ("ospf_vl_new(): creating pseudo zebra interface"); 718 719 vi = if_create (); 720 co = connected_new (); 721 co->ifp = vi; 722 listnode_add (vi->connected, co); 723 724 p = prefix_ipv4_new (); 725 p->family = AF_INET; 726 p->prefix.s_addr = 0; 727 p->prefixlen = 0; 728 729 co->address = (struct prefix *)p; 730 731 voi = ospf_if_new (vi, co->address); 732 if (voi == NULL) 733 { 734 if (IS_DEBUG_OSPF_EVENT) 735 zlog_info ("ospf_vl_new(): Alarm: OSPF int structure is not created"); 736 return NULL; 737 } 738 voi->connected = co; 739 voi->vl_data = vl_data; 740 voi->ifp->mtu = OSPF_VL_MTU; 741 voi->type = OSPF_IFTYPE_VIRTUALLINK; 742 743 sprintf (ifname, "VLINK%d", vlink_count++); 744 if (IS_DEBUG_OSPF_EVENT) 745 zlog_info ("ospf_vl_new(): Created name: %s", ifname); 746 strncpy (vi->name, ifname, IFNAMSIZ); 747 if (IS_DEBUG_OSPF_EVENT) 748 zlog_info ("ospf_vl_new(): set if->name to %s", vi->name); 749 750 area_id.s_addr = 0; 751 area = ospf_area_get (area_id, OSPF_AREA_ID_FORMAT_ADDRESS); 752 voi->area = area; 753 754 if (IS_DEBUG_OSPF_EVENT) 755 zlog_info ("ospf_vl_new(): set associated area to the backbone"); 756 757 ospf_area_add_if (voi->area, voi); 758 759 ospf_if_stream_set (voi); 760 761 if (IS_DEBUG_OSPF_EVENT) 762 zlog_info ("ospf_vl_new(): Stop"); 763 return voi; 764} 765 766void 767ospf_vl_if_delete (struct ospf_vl_data *vl_data) 768{ 769 struct interface *ifp = vl_data->vl_oi->ifp; 770 vl_data->vl_oi->address->u.prefix4.s_addr = 0; 771 vl_data->vl_oi->address->prefixlen = 0; 772 ospf_if_free (vl_data->vl_oi); 773 if_delete (ifp); 774 vlink_count--; 775} 776 777struct ospf_vl_data * 778ospf_vl_lookup (struct ospf_area *area, struct in_addr vl_peer) 779{ 780 struct ospf_vl_data *vl_data; 781 listnode node; 782 783 for (node = listhead (ospf_top->vlinks); node; nextnode (node)) 784 if ((vl_data = getdata (node)) != NULL) 785 if (vl_data->vl_peer.s_addr == vl_peer.s_addr && 786 IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) 787 return vl_data; 788 789 return NULL; 790} 791 792void 793ospf_vl_shutdown (struct ospf_vl_data *vl_data) 794{ 795 struct ospf_interface *oi; 796 797 if ((oi = vl_data->vl_oi) == NULL) 798 return; 799 800 oi->address->u.prefix4.s_addr = 0; 801 oi->address->prefixlen = 0; 802 803 UNSET_FLAG (oi->ifp->flags, IFF_UP); 804 /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */ 805 OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown); 806} 807 808void 809ospf_vl_add (struct ospf_vl_data *vl_data) 810{ 811 listnode_add (ospf_top->vlinks, vl_data); 812#ifdef HAVE_SNMP 813 ospf_snmp_vl_add (vl_data); 814#endif /* HAVE_SNMP */ 815} 816 817void 818ospf_vl_delete (struct ospf_vl_data *vl_data) 819{ 820 ospf_vl_shutdown (vl_data); 821 ospf_vl_if_delete (vl_data); 822 823#ifdef HAVE_SNMP 824 ospf_snmp_vl_delete (vl_data); 825#endif /* HAVE_SNMP */ 826 listnode_delete (ospf_top->vlinks, vl_data); 827 828 ospf_vl_data_free (vl_data); 829} 830 831void 832ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v) 833{ 834 int changed = 0; 835 struct ospf_interface *voi; 836 listnode node; 837 struct vertex_nexthop *nh; 838 int i; 839 struct router_lsa *rl; 840 841 voi = vl_data->vl_oi; 842 843 if (voi->output_cost != v->distance) 844 { 845 voi->output_cost = v->distance; 846 changed = 1; 847 } 848 849 for (node = listhead (v->nexthop); node; nextnode (node)) 850 if ((nh = getdata (node)) != NULL) 851 { 852 vl_data->out_oi = (struct ospf_interface *) nh->oi; 853 854 voi->address->u.prefix4 = vl_data->out_oi->address->u.prefix4; 855 voi->address->prefixlen = vl_data->out_oi->address->prefixlen; 856 857 break; /* We take the first interface. */ 858 } 859 860 rl = (struct router_lsa *)v->lsa; 861 862 for (i = 0; i < ntohs (rl->links); i++) 863 { 864 switch (rl->link[i].type) 865 { 866 case LSA_LINK_TYPE_VIRTUALLINK: 867 if (IS_DEBUG_OSPF_EVENT) 868 zlog_info ("found back link through VL"); 869 case LSA_LINK_TYPE_TRANSIT: 870 case LSA_LINK_TYPE_POINTOPOINT: 871 vl_data->peer_addr = rl->link[i].link_data; 872 if (IS_DEBUG_OSPF_EVENT) 873 zlog_info ("%s peer address is %s\n", 874 vl_data->vl_oi->ifp->name, inet_ntoa(vl_data->peer_addr)); 875 return; 876 } 877 } 878} 879 880 881void 882ospf_vl_up_check (struct ospf_area * area, struct in_addr rid, 883 struct vertex *v) 884{ 885 listnode node; 886 struct ospf_vl_data *vl_data; 887 struct ospf_interface *oi; 888 889 if (IS_DEBUG_OSPF_EVENT) 890 { 891 zlog_info ("ospf_vl_up_check(): Start"); 892 zlog_info ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid)); 893 zlog_info ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id)); 894 } 895 896 for (node = listhead (ospf_top->vlinks); node; nextnode (node)) 897 { 898 if ((vl_data = getdata (node)) == NULL) 899 continue; 900 901 if (IS_DEBUG_OSPF_EVENT) 902 { 903 zlog_info ("ospf_vl_up_check(): considering VL, name: %s", 904 vl_data->vl_oi->ifp->name); 905 zlog_info ("ospf_vl_up_check(): VL area: %s, peer ID: %s", 906 inet_ntoa (vl_data->vl_area_id), 907 inet_ntoa (vl_data->vl_peer)); 908 } 909 910 if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) && 911 IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) 912 { 913 oi = vl_data->vl_oi; 914 SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED); 915 916 if (IS_DEBUG_OSPF_EVENT) 917 zlog_info ("ospf_vl_up_check(): this VL matched"); 918 919 if (oi->state == ISM_Down) 920 { 921 if (IS_DEBUG_OSPF_EVENT) 922 zlog_info ("ospf_vl_up_check(): VL is down, waking it up"); 923 SET_FLAG (oi->ifp->flags, IFF_UP); 924 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp); 925 } 926 927 ospf_vl_set_params (vl_data, v); 928 } 929 } 930} 931 932void 933ospf_vl_unapprove () 934{ 935 listnode node; 936 struct ospf_vl_data *vl_data; 937 938 for (node = listhead (ospf_top->vlinks); node; nextnode (node)) 939 if ((vl_data = getdata (node)) != NULL) 940 UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED); 941} 942 943void 944ospf_vl_shut_unapproved () 945{ 946 listnode node; 947 struct ospf_vl_data *vl_data; 948 949 for (node = listhead (ospf_top->vlinks); node; nextnode (node)) 950 if ((vl_data = getdata (node)) != NULL) 951 if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED)) 952 ospf_vl_shutdown (vl_data); 953} 954 955int 956ospf_full_virtual_nbrs (struct ospf_area *area) 957{ 958 if (IS_DEBUG_OSPF_EVENT) 959 { 960 zlog_info ("counting fully adjacent virtual neighbors in area %s", 961 inet_ntoa (area->area_id)); 962 zlog_info ("there are %d of them", area->full_vls); 963 } 964 965 return area->full_vls; 966} 967 968int 969ospf_vls_in_area (struct ospf_area *area) 970{ 971 listnode node; 972 struct ospf_vl_data *vl_data; 973 int c = 0; 974 975 for (node = listhead (ospf_top->vlinks); node; nextnode (node)) 976 if ((vl_data = getdata (node)) != NULL) 977 if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) 978 c++; 979 980 return c; 981} 982 983 984struct crypt_key * 985ospf_crypt_key_new () 986{ 987 struct crypt_key *ck; 988 989 ck = XMALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key)); 990 memset (ck, 0, sizeof (struct crypt_key)); 991 992 return ck; 993} 994 995void 996ospf_crypt_key_add (list crypt, struct crypt_key *ck) 997{ 998 listnode_add (crypt, ck); 999} 1000 1001struct crypt_key * 1002ospf_crypt_key_lookup (list auth_crypt, u_char key_id) 1003{ 1004 listnode node; 1005 struct crypt_key *ck; 1006 1007 for (node = listhead (auth_crypt); node; nextnode (node)) 1008 { 1009 ck = getdata (node); 1010 if (ck->key_id == key_id) 1011 return ck; 1012 } 1013 1014 return NULL; 1015} 1016 1017int 1018ospf_crypt_key_delete (list auth_crypt, u_char key_id) 1019{ 1020 listnode node; 1021 struct crypt_key *ck; 1022 1023 for (node = listhead (auth_crypt); node; nextnode (node)) 1024 { 1025 ck = getdata (node); 1026 if (ck->key_id == key_id) 1027 { 1028 listnode_delete (auth_crypt, ck); 1029 return 1; 1030 } 1031 } 1032 1033 return 0; 1034} 1035 1036void 1037ospf_if_init () 1038{ 1039 /* Initialize Zebra interface data structure. */ 1040 if_init (); 1041 if_add_hook (IF_NEW_HOOK, ospf_if_new_hook); 1042 if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook); 1043} 1044