1/* 2 * Copyright (C) 1999 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 17 * along with GNU Zebra; see the file COPYING. If not, write to the 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22#include "ospf6d.h" 23 24#include "if.h" 25#include "log.h" 26#include "command.h" 27 28#include "ospf6_lsdb.h" 29 30#include "ospf6_top.h" 31#include "ospf6_area.h" 32#include "ospf6_interface.h" 33 34char *ospf6_interface_state_string[] = 35{ 36 "None", "Down", "Loopback", "Waiting", "PointToPoint", 37 "DROther", "BDR", "DR", NULL 38}; 39 40static void 41ospf6_interface_foreach_neighbor (struct ospf6_interface *o6i, 42 void *arg, int val, 43 void (*func) (void *, int, void *)) 44{ 45 listnode node; 46 struct ospf6_neighbor *nei; 47 48 for (node = listhead (o6i->neighbor_list); node; nextnode (node)) 49 { 50 nei = (struct ospf6_neighbor *) getdata (node); 51 (*func) (arg, val, nei); 52 } 53} 54 55static int 56ospf6_interface_maxage_remover (struct thread *t) 57{ 58 int count; 59 struct ospf6_interface *o6i = (struct ospf6_interface *) THREAD_ARG (t); 60 61 o6i->maxage_remover = (struct thread *) NULL; 62 63 count = 0; 64 o6i->foreach_nei (o6i, &count, NBS_EXCHANGE, ospf6_count_state); 65 o6i->foreach_nei (o6i, &count, NBS_LOADING, ospf6_count_state); 66 if (count != 0) 67 return 0; 68 69 ospf6_lsdb_remove_maxage (o6i->lsdb); 70 return 0; 71} 72 73void 74ospf6_interface_schedule_maxage_remover (void *arg, int val, void *obj) 75{ 76 struct ospf6_interface *o6i = (struct ospf6_interface *) obj; 77 78 if (o6i->maxage_remover != NULL) 79 return; 80 81 o6i->maxage_remover = 82 thread_add_event (master, ospf6_interface_maxage_remover, o6i, 0); 83} 84 85/* Create new ospf6 interface structure */ 86struct ospf6_interface * 87ospf6_interface_create (struct interface *ifp) 88{ 89 struct ospf6_interface *o6i; 90 91 o6i = (struct ospf6_interface *) 92 XMALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface)); 93 94 if (o6i) 95 memset (o6i, 0, sizeof (struct ospf6_interface)); 96 else 97 { 98 zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex); 99 return (struct ospf6_interface *) NULL; 100 } 101 102 o6i->instance_id = 0; 103 o6i->if_id = ifp->ifindex; 104 o6i->lladdr = (struct in6_addr *) NULL; 105 o6i->area = (struct ospf6_area *) NULL; 106 o6i->state = IFS_DOWN; 107 o6i->flag = 0; 108 o6i->neighbor_list = list_new (); 109 110 o6i->ack_list = ospf6_lsdb_create (); 111 o6i->lsdb = ospf6_lsdb_create (); 112 113 o6i->transdelay = 1; 114 o6i->priority = 1; 115 o6i->hello_interval = 10; 116 o6i->dead_interval = 40; 117 o6i->rxmt_interval = 5; 118 o6i->cost = 1; 119 o6i->ifmtu = 1280; 120 121 o6i->foreach_nei = ospf6_interface_foreach_neighbor; 122 123 /* link both */ 124 o6i->interface = ifp; 125 ifp->info = o6i; 126 127 CALL_ADD_HOOK (&interface_hook, o6i); 128 129 return o6i; 130} 131 132void 133ospf6_interface_delete (struct ospf6_interface *o6i) 134{ 135 listnode n; 136 struct ospf6_neighbor *o6n; 137 138 CALL_REMOVE_HOOK (&interface_hook, o6i); 139 140 for (n = listhead (o6i->neighbor_list); n; nextnode (n)) 141 { 142 o6n = (struct ospf6_neighbor *) getdata (n); 143 ospf6_neighbor_delete (o6n); 144 } 145 list_delete (o6i->neighbor_list); 146 147 if (o6i->thread_send_hello) 148 { 149 thread_cancel (o6i->thread_send_hello); 150 o6i->thread_send_hello = NULL; 151 } 152 if (o6i->thread_send_lsack_delayed) 153 { 154 thread_cancel (o6i->thread_send_lsack_delayed); 155 o6i->thread_send_lsack_delayed = NULL; 156 } 157 158 ospf6_lsdb_delete (o6i->ack_list); 159 ospf6_lsdb_remove_all (o6i->lsdb); 160 ospf6_lsdb_delete (o6i->lsdb); 161 162 /* cut link */ 163 o6i->interface->info = NULL; 164 165 /* plist_name */ 166 if (o6i->plist_name) 167 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name); 168 169 XFREE (MTYPE_OSPF6_IF, o6i); 170} 171 172static struct in6_addr * 173ospf6_interface_update_linklocal_address (struct interface *ifp) 174{ 175 listnode n; 176 struct connected *c; 177 struct in6_addr *l = (struct in6_addr *) NULL; 178 179 /* for each connected address */ 180 for (n = listhead (ifp->connected); n; nextnode (n)) 181 { 182 c = (struct connected *) getdata (n); 183 184 /* if family not AF_INET6, ignore */ 185 if (c->address->family != AF_INET6) 186 continue; 187 188 /* linklocal scope check */ 189 if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6)) 190 l = &c->address->u.prefix6; 191 } 192 return l; 193} 194 195void 196ospf6_interface_if_add (struct interface *ifp) 197{ 198 struct ospf6_interface *o6i; 199 200 o6i = (struct ospf6_interface *) ifp->info; 201 if (!o6i) 202 return; 203 204 o6i->if_id = ifp->ifindex; 205 206 ospf6_interface_address_update (ifp); 207 208 /* interface start */ 209 if (o6i->area) 210 thread_add_event (master, interface_up, o6i, 0); 211} 212 213void 214ospf6_interface_if_del (struct interface *ifp) 215{ 216 struct ospf6_interface *o6i; 217 218 o6i = (struct ospf6_interface *) ifp->info; 219 if (!o6i) 220 return; 221 222 /* interface stop */ 223 if (o6i->area) 224 thread_execute (master, interface_down, o6i, 0); 225 226 listnode_delete (o6i->area->if_list, o6i); 227 o6i->area = (struct ospf6_area *) NULL; 228 229 /* cut link */ 230 o6i->interface = NULL; 231 ifp->info = NULL; 232 233 ospf6_interface_delete (o6i); 234} 235 236void 237ospf6_interface_state_update (struct interface *ifp) 238{ 239 struct ospf6_interface *o6i; 240 241 o6i = (struct ospf6_interface *) ifp->info; 242 if (! o6i) 243 return; 244 if (! o6i->area) 245 return; 246 247 if (if_is_up (ifp)) 248 thread_add_event (master, interface_up, o6i, 0); 249 else 250 thread_add_event (master, interface_down, o6i, 0); 251 252 return; 253} 254 255void 256ospf6_interface_address_update (struct interface *ifp) 257{ 258 struct ospf6_interface *o6i; 259 260 o6i = (struct ospf6_interface *) ifp->info; 261 if (! o6i) 262 return; 263 264 /* reset linklocal pointer */ 265 o6i->lladdr = ospf6_interface_update_linklocal_address (ifp); 266 267 /* if area is null, can't make link-lsa */ 268 if (! o6i->area) 269 return; 270 271 /* create new Link-LSA */ 272 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 273 274 CALL_CHANGE_HOOK (&interface_hook, o6i); 275} 276 277struct ospf6_interface * 278ospf6_interface_lookup_by_index (int ifindex) 279{ 280 struct ospf6_interface *o6i; 281 struct interface *ifp; 282 283 ifp = if_lookup_by_index (ifindex); 284 285 if (! ifp) 286 return (struct ospf6_interface *) NULL; 287 288 o6i = (struct ospf6_interface *) ifp->info; 289 return o6i; 290} 291 292struct ospf6_interface * 293ospf6_interface_lookup_by_name (char *ifname) 294{ 295 struct ospf6_interface *o6i; 296 struct interface *ifp; 297 298 ifp = if_lookup_by_name (ifname); 299 300 if (! ifp) 301 return (struct ospf6_interface *) NULL; 302 303 o6i = (struct ospf6_interface *) ifp->info; 304 return o6i; 305} 306 307int 308ospf6_interface_count_neighbor_in_state (u_char state, 309 struct ospf6_interface *o6i) 310{ 311 listnode n; 312 struct ospf6_neighbor *o6n; 313 int count = 0; 314 315 for (n = listhead (o6i->neighbor_list); n; nextnode (n)) 316 { 317 o6n = (struct ospf6_neighbor *) getdata (n); 318 if (o6n->state == state) 319 count++; 320 } 321 return count; 322} 323 324int 325ospf6_interface_count_full_neighbor (struct ospf6_interface *o6i) 326{ 327 listnode n; 328 struct ospf6_neighbor *o6n; 329 int count = 0; 330 331 for (n = listhead (o6i->neighbor_list); n; nextnode (n)) 332 { 333 o6n = (struct ospf6_neighbor *) getdata (n); 334 if (o6n->state == NBS_FULL) 335 count++; 336 } 337 return count; 338} 339 340int 341ospf6_interface_is_enabled (unsigned int ifindex) 342{ 343 struct ospf6_interface *o6i; 344 345 o6i = ospf6_interface_lookup_by_index (ifindex); 346 if (! o6i) 347 return 0; 348 349 if (! o6i->area) 350 return 0; 351 352 if (o6i->state <= IFS_DOWN) 353 return 0; 354 355 return 1; 356} 357 358void 359ospf6_interface_delayed_ack_add (struct ospf6_lsa *lsa, 360 struct ospf6_interface *o6i) 361{ 362 struct ospf6_lsa *summary; 363 summary = ospf6_lsa_summary_create (lsa->header); 364 ospf6_lsdb_add (summary, o6i->ack_list); 365} 366 367void 368ospf6_interface_delayed_ack_remove (struct ospf6_lsa *lsa, 369 struct ospf6_interface *o6i) 370{ 371 struct ospf6_lsa *summary; 372 summary = ospf6_lsdb_lookup_lsdb (lsa->header->type, lsa->header->id, 373 lsa->header->adv_router, o6i->ack_list); 374 ospf6_lsdb_remove (summary, o6i->ack_list); 375} 376 377/* show specified interface structure */ 378int 379ospf6_interface_show (struct vty *vty, struct interface *iface) 380{ 381 struct ospf6_interface *ospf6_interface; 382 struct connected *c; 383 struct prefix *p; 384 listnode i; 385 char strbuf[64], dr[32], bdr[32]; 386 char *updown[3] = {"down", "up", NULL}; 387 char *type; 388 389 /* check physical interface type */ 390 if (if_is_loopback (iface)) 391 type = "LOOPBACK"; 392 else if (if_is_broadcast (iface)) 393 type = "BROADCAST"; 394 else if (if_is_pointopoint (iface)) 395 type = "POINTOPOINT"; 396 else 397 type = "UNKNOWN"; 398 399 vty_out (vty, "%s is %s, type %s%s", 400 iface->name, updown[if_is_up (iface)], type, 401 VTY_NEWLINE); 402 vty_out (vty, " Interface ID: %d%s", iface->ifindex, VTY_NEWLINE); 403 404 if (iface->info == NULL) 405 { 406 vty_out (vty, " OSPF not enabled on this interface%s", VTY_NEWLINE); 407 return 0; 408 } 409 else 410 ospf6_interface = (struct ospf6_interface *) iface->info; 411 412 vty_out (vty, " Internet Address:%s", VTY_NEWLINE); 413 for (i = listhead (iface->connected); i; nextnode (i)) 414 { 415 c = (struct connected *)getdata (i); 416 p = c->address; 417 prefix2str (p, strbuf, sizeof (strbuf)); 418 switch (p->family) 419 { 420 case AF_INET: 421 vty_out (vty, " inet : %s%s", strbuf, 422 VTY_NEWLINE); 423 break; 424 case AF_INET6: 425 vty_out (vty, " inet6: %s%s", strbuf, 426 VTY_NEWLINE); 427 break; 428 default: 429 vty_out (vty, " ??? : %s%s", strbuf, 430 VTY_NEWLINE); 431 break; 432 } 433 } 434 435 if (ospf6_interface->area) 436 { 437 inet_ntop (AF_INET, &ospf6_interface->area->ospf6->router_id, 438 strbuf, sizeof (strbuf)); 439 vty_out (vty, " Instance ID %d, Router ID %s%s", 440 ospf6_interface->instance_id, strbuf, 441 VTY_NEWLINE); 442 inet_ntop (AF_INET, &ospf6_interface->area->area_id, 443 strbuf, sizeof (strbuf)); 444 vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, 445 ospf6_interface->cost, VTY_NEWLINE); 446 } 447 else 448 vty_out (vty, " Not Attached to Area%s", VTY_NEWLINE); 449 450 vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s", 451 ospf6_interface_state_string[ospf6_interface->state], 452 ospf6_interface->transdelay, 453 ospf6_interface->priority, 454 VTY_NEWLINE); 455 vty_out (vty, " Timer intervals configured:%s", VTY_NEWLINE); 456 vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s", 457 ospf6_interface->hello_interval, 458 ospf6_interface->dead_interval, 459 ospf6_interface->rxmt_interval, 460 VTY_NEWLINE); 461 462 inet_ntop (AF_INET, &ospf6_interface->dr, dr, sizeof (dr)); 463 inet_ntop (AF_INET, &ospf6_interface->bdr, bdr, sizeof (bdr)); 464 vty_out (vty, " DR:%s BDR:%s%s", dr, bdr, VTY_NEWLINE); 465 466 vty_out (vty, " Number of I/F scoped LSAs is %u%s", 467 ospf6_interface->lsdb->count, VTY_NEWLINE); 468 vty_out (vty, " %-16s %5d times, %-16s %5d times%s", 469 "DRElection", ospf6_interface->ospf6_stat_dr_election, 470 "DelayedLSAck", ospf6_interface->ospf6_stat_delayed_lsack, 471 VTY_NEWLINE); 472 473 return 0; 474} 475 476void 477ospf6_interface_statistics_show (struct vty *vty, struct ospf6_interface *o6i) 478{ 479 struct timeval now, uptime; 480 u_long recv_total, send_total; 481 u_long bps_total_avg, bps_tx_avg, bps_rx_avg; 482 int i; 483 484 gettimeofday (&now, (struct timezone *) NULL); 485 ospf6_timeval_sub (&now, &ospf6->starttime, &uptime); 486 487 recv_total = send_total = 0; 488 for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++) 489 { 490 recv_total += o6i->message_stat[i].recv_octet; 491 send_total += o6i->message_stat[i].send_octet; 492 } 493 bps_total_avg = (recv_total + send_total) * 8 / uptime.tv_sec; 494 bps_tx_avg = send_total * 8 / uptime.tv_sec; 495 bps_rx_avg = recv_total * 8 / uptime.tv_sec; 496 497 vty_out (vty, " Statistics of interface %s%s", 498 o6i->interface->name, VTY_NEWLINE); 499 vty_out (vty, " Number of Neighbor: %d%s", 500 listcount (o6i->neighbor_list), VTY_NEWLINE); 501 502 vty_out (vty, " %-8s %6s %6s %8s %8s%s", 503 "Type", "tx", "rx", "tx-byte", "rx-byte", VTY_NEWLINE); 504 for (i = 0; i < OSPF6_MESSAGE_TYPE_MAX; i++) 505 { 506 vty_out (vty, " %-8s %6d %6d %8d %8d%s", 507 ospf6_message_type_string[i], 508 o6i->message_stat[i].send, 509 o6i->message_stat[i].recv, 510 o6i->message_stat[i].send_octet, 511 o6i->message_stat[i].recv_octet, 512 VTY_NEWLINE); 513 } 514 515 vty_out (vty, " Average Link bandwidth: %ldbps" 516 " (Tx: %ldbps Rx: %ldbps)%s", 517 bps_total_avg, bps_tx_avg, bps_rx_avg, VTY_NEWLINE); 518} 519 520/* show interface */ 521DEFUN (show_ipv6_ospf6_interface, 522 show_ipv6_ospf6_interface_ifname_cmd, 523 "show ipv6 ospf6 interface IFNAME", 524 SHOW_STR 525 IP6_STR 526 OSPF6_STR 527 INTERFACE_STR 528 IFNAME_STR 529 ) 530{ 531 struct interface *ifp; 532 listnode i; 533 534 if (argc) 535 { 536 ifp = if_lookup_by_name (argv[0]); 537 if (!ifp) 538 { 539 vty_out (vty, "No such Interface: %s%s", argv[0], 540 VTY_NEWLINE); 541 return CMD_WARNING; 542 } 543 ospf6_interface_show (vty, ifp); 544 } 545 else 546 { 547 for (i = listhead (iflist); i; nextnode (i)) 548 { 549 ifp = (struct interface *)getdata (i); 550 ospf6_interface_show (vty, ifp); 551 } 552 } 553 return CMD_SUCCESS; 554} 555 556ALIAS (show_ipv6_ospf6_interface, 557 show_ipv6_ospf6_interface_cmd, 558 "show ipv6 ospf6 interface", 559 SHOW_STR 560 IP6_STR 561 OSPF6_STR 562 INTERFACE_STR 563 ) 564 565/* interface variable set command */ 566DEFUN (ipv6_ospf6_cost, 567 ipv6_ospf6_cost_cmd, 568 "ipv6 ospf6 cost COST", 569 IP6_STR 570 OSPF6_STR 571 "Interface cost\n" 572 "<1-65535> Cost\n" 573 ) 574{ 575 struct ospf6_interface *o6i; 576 struct interface *ifp; 577 578 ifp = (struct interface *)vty->index; 579 assert (ifp); 580 581 o6i = (struct ospf6_interface *)ifp->info; 582 if (!o6i) 583 o6i = ospf6_interface_create (ifp); 584 assert (o6i); 585 586 if (o6i->cost == strtol (argv[0], NULL, 10)) 587 return CMD_SUCCESS; 588 589 o6i->cost = strtol (argv[0], NULL, 10); 590 591 /* execute LSA hooks */ 592 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 593 594 CALL_CHANGE_HOOK (&interface_hook, o6i); 595 596 return CMD_SUCCESS; 597} 598 599/* interface variable set command */ 600DEFUN (ipv6_ospf6_hellointerval, 601 ipv6_ospf6_hellointerval_cmd, 602 "ipv6 ospf6 hello-interval HELLO_INTERVAL", 603 IP6_STR 604 OSPF6_STR 605 "Time between HELLO packets\n" 606 SECONDS_STR 607 ) 608{ 609 struct ospf6_interface *ospf6_interface; 610 struct interface *ifp; 611 612 ifp = (struct interface *) vty->index; 613 assert (ifp); 614 ospf6_interface = (struct ospf6_interface *) ifp->info; 615 if (!ospf6_interface) 616 ospf6_interface = ospf6_interface_create (ifp); 617 assert (ospf6_interface); 618 619 ospf6_interface->hello_interval = strtol (argv[0], NULL, 10); 620 return CMD_SUCCESS; 621} 622 623/* interface variable set command */ 624DEFUN (ipv6_ospf6_deadinterval, 625 ipv6_ospf6_deadinterval_cmd, 626 "ipv6 ospf6 dead-interval ROUTER_DEAD_INTERVAL", 627 IP6_STR 628 OSPF6_STR 629 "Interval after which a neighbor is declared dead\n" 630 SECONDS_STR 631 ) 632{ 633 struct ospf6_interface *ospf6_interface; 634 struct interface *ifp; 635 636 ifp = (struct interface *) vty->index; 637 assert (ifp); 638 ospf6_interface = (struct ospf6_interface *) ifp->info; 639 if (!ospf6_interface) 640 ospf6_interface = ospf6_interface_create (ifp); 641 assert (ospf6_interface); 642 643 ospf6_interface->dead_interval = strtol (argv[0], NULL, 10); 644 return CMD_SUCCESS; 645} 646 647/* interface variable set command */ 648DEFUN (ipv6_ospf6_transmitdelay, 649 ipv6_ospf6_transmitdelay_cmd, 650 "ipv6 ospf6 transmit-delay TRANSMITDELAY", 651 IP6_STR 652 OSPF6_STR 653 "Link state transmit delay\n" 654 SECONDS_STR 655 ) 656{ 657 struct ospf6_interface *ospf6_interface; 658 struct interface *ifp; 659 660 ifp = (struct interface *) vty->index; 661 assert (ifp); 662 ospf6_interface = (struct ospf6_interface *) ifp->info; 663 if (!ospf6_interface) 664 ospf6_interface = ospf6_interface_create (ifp); 665 assert (ospf6_interface); 666 667 ospf6_interface->transdelay = strtol (argv[0], NULL, 10); 668 return CMD_SUCCESS; 669} 670 671/* interface variable set command */ 672DEFUN (ipv6_ospf6_retransmitinterval, 673 ipv6_ospf6_retransmitinterval_cmd, 674 "ipv6 ospf6 retransmit-interval RXMTINTERVAL", 675 IP6_STR 676 OSPF6_STR 677 "Time between retransmitting lost link state advertisements\n" 678 SECONDS_STR 679 ) 680{ 681 struct ospf6_interface *ospf6_interface; 682 struct interface *ifp; 683 684 ifp = (struct interface *) vty->index; 685 assert (ifp); 686 ospf6_interface = (struct ospf6_interface *) ifp->info; 687 if (!ospf6_interface) 688 ospf6_interface = ospf6_interface_create (ifp); 689 assert (ospf6_interface); 690 691 ospf6_interface->rxmt_interval = strtol (argv[0], NULL, 10); 692 return CMD_SUCCESS; 693} 694 695/* interface variable set command */ 696DEFUN (ipv6_ospf6_priority, 697 ipv6_ospf6_priority_cmd, 698 "ipv6 ospf6 priority PRIORITY", 699 IP6_STR 700 OSPF6_STR 701 "Router priority\n" 702 "<0-255> Priority\n" 703 ) 704{ 705 struct ospf6_interface *ospf6_interface; 706 struct interface *ifp; 707 708 ifp = (struct interface *) vty->index; 709 assert (ifp); 710 ospf6_interface = (struct ospf6_interface *) ifp->info; 711 if (!ospf6_interface) 712 ospf6_interface = ospf6_interface_create (ifp); 713 assert (ospf6_interface); 714 715 ospf6_interface->priority = strtol (argv[0], NULL, 10); 716 717 if (ospf6_interface->area) 718 ifs_change (dr_election (ospf6_interface), "Priority reconfigured", 719 ospf6_interface); 720 721 return CMD_SUCCESS; 722} 723 724DEFUN (ipv6_ospf6_instance, 725 ipv6_ospf6_instance_cmd, 726 "ipv6 ospf6 instance-id INSTANCE", 727 IP6_STR 728 OSPF6_STR 729 "Instance ID\n" 730 "<0-255> Instance ID\n" 731 ) 732{ 733 struct ospf6_interface *ospf6_interface; 734 struct interface *ifp; 735 736 ifp = (struct interface *)vty->index; 737 assert (ifp); 738 739 ospf6_interface = (struct ospf6_interface *)ifp->info; 740 if (!ospf6_interface) 741 ospf6_interface = ospf6_interface_create (ifp); 742 assert (ospf6_interface); 743 744 ospf6_interface->instance_id = strtol (argv[0], NULL, 10); 745 return CMD_SUCCESS; 746} 747 748DEFUN (ipv6_ospf6_passive, 749 ipv6_ospf6_passive_cmd, 750 "ipv6 ospf6 passive", 751 IP6_STR 752 OSPF6_STR 753 "passive interface: No Adjacency will be formed on this I/F\n" 754 ) 755{ 756 struct ospf6_interface *o6i; 757 struct interface *ifp; 758 listnode node; 759 struct ospf6_neighbor *o6n; 760 761 ifp = (struct interface *) vty->index; 762 assert (ifp); 763 o6i = (struct ospf6_interface *) ifp->info; 764 if (! o6i) 765 o6i = ospf6_interface_create (ifp); 766 assert (o6i); 767 768 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 769 if (o6i->thread_send_hello) 770 { 771 thread_cancel (o6i->thread_send_hello); 772 o6i->thread_send_hello = (struct thread *) NULL; 773 } 774 775 for (node = listhead (o6i->neighbor_list); node; nextnode (node)) 776 { 777 o6n = getdata (node); 778 if (o6n->inactivity_timer) 779 thread_cancel (o6n->inactivity_timer); 780 thread_execute (master, inactivity_timer, o6n, 0); 781 } 782 783 return CMD_SUCCESS; 784} 785 786DEFUN (no_ipv6_ospf6_passive, 787 no_ipv6_ospf6_passive_cmd, 788 "no ipv6 ospf6 passive", 789 NO_STR 790 IP6_STR 791 OSPF6_STR 792 "passive interface: No Adjacency will be formed on this I/F\n" 793 ) 794{ 795 struct ospf6_interface *o6i; 796 struct interface *ifp; 797 798 ifp = (struct interface *) vty->index; 799 assert (ifp); 800 o6i = (struct ospf6_interface *) ifp->info; 801 if (! o6i) 802 o6i = ospf6_interface_create (ifp); 803 assert (o6i); 804 805 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE); 806 if (o6i->thread_send_hello == NULL) 807 thread_add_event (master, ospf6_send_hello, o6i, 0); 808 809 return CMD_SUCCESS; 810} 811 812 813DEFUN (ipv6_ospf6_advertise_force_prefix, 814 ipv6_ospf6_advertise_force_prefix_cmd, 815 "ipv6 ospf6 advertise force-prefix", 816 IP6_STR 817 OSPF6_STR 818 "Advertising options\n" 819 "Force advertising prefix, applicable if Loopback or P-to-P\n" 820 ) 821{ 822 struct ospf6_interface *o6i; 823 struct interface *ifp; 824 825 ifp = (struct interface *) vty->index; 826 assert (ifp); 827 o6i = (struct ospf6_interface *) ifp->info; 828 if (! o6i) 829 o6i = ospf6_interface_create (ifp); 830 assert (o6i); 831 832 if (! if_is_loopback (ifp) && ! if_is_pointopoint (ifp)) 833 { 834 vty_out (vty, "Interface not Loopback nor PointToPoint%s", 835 VTY_NEWLINE); 836 return CMD_ERR_NOTHING_TODO; 837 } 838 839 SET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX); 840 841 /* execute LSA hooks */ 842 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 843 844 CALL_CHANGE_HOOK (&interface_hook, o6i); 845 846 return CMD_SUCCESS; 847} 848 849DEFUN (no_ipv6_ospf6_advertise_force_prefix, 850 no_ipv6_ospf6_advertise_force_prefix_cmd, 851 "no ipv6 ospf6 advertise force-prefix", 852 NO_STR 853 IP6_STR 854 OSPF6_STR 855 "Advertising options\n" 856 "Force to advertise prefix, applicable if Loopback or P-to-P\n" 857 ) 858{ 859 struct ospf6_interface *o6i; 860 struct interface *ifp; 861 862 ifp = (struct interface *) vty->index; 863 assert (ifp); 864 o6i = (struct ospf6_interface *) ifp->info; 865 if (! o6i) 866 o6i = ospf6_interface_create (ifp); 867 assert (o6i); 868 869 UNSET_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX); 870 871 /* execute LSA hooks */ 872 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 873 874 CALL_CHANGE_HOOK (&interface_hook, o6i); 875 876 return CMD_SUCCESS; 877} 878 879DEFUN (ipv6_ospf6_advertise_prefix_list, 880 ipv6_ospf6_advertise_prefix_list_cmd, 881 "ipv6 ospf6 advertise prefix-list WORD", 882 IP6_STR 883 OSPF6_STR 884 "Advertising options\n" 885 "Filter prefix using prefix-list\n" 886 "Prefix list name\n" 887 ) 888{ 889 struct ospf6_interface *o6i; 890 struct interface *ifp; 891 892 ifp = (struct interface *) vty->index; 893 assert (ifp); 894 o6i = (struct ospf6_interface *) ifp->info; 895 if (! o6i) 896 o6i = ospf6_interface_create (ifp); 897 assert (o6i); 898 899 if (o6i->plist_name) 900 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name); 901 o6i->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]); 902 903 /* execute LSA hooks */ 904 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 905 906 CALL_CHANGE_HOOK (&interface_hook, o6i); 907 908 return CMD_SUCCESS; 909} 910 911DEFUN (no_ipv6_ospf6_advertise_prefix_list, 912 no_ipv6_ospf6_advertise_prefix_list_cmd, 913 "no ipv6 ospf6 advertise prefix-list", 914 NO_STR 915 IP6_STR 916 OSPF6_STR 917 "Advertising options\n" 918 "Filter prefix using prefix-list\n" 919 ) 920{ 921 struct ospf6_interface *o6i; 922 struct interface *ifp; 923 924 ifp = (struct interface *) vty->index; 925 assert (ifp); 926 o6i = (struct ospf6_interface *) ifp->info; 927 if (! o6i) 928 o6i = ospf6_interface_create (ifp); 929 assert (o6i); 930 931 if (o6i->plist_name) 932 { 933 XFREE (MTYPE_PREFIX_LIST_STR, o6i->plist_name); 934 o6i->plist_name = NULL; 935 } 936 937 /* execute LSA hooks */ 938 CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, o6i); 939 940 CALL_CHANGE_HOOK (&interface_hook, o6i); 941 942 return CMD_SUCCESS; 943} 944 945int 946ospf6_interface_config_write (struct vty *vty) 947{ 948 listnode i; 949 struct ospf6_interface *o6i; 950 struct interface *ifp; 951 952 for (i = listhead (iflist); i; nextnode (i)) 953 { 954 ifp = (struct interface *) getdata (i); 955 o6i = (struct ospf6_interface *) ifp->info; 956 if (! o6i) 957 continue; 958 959 vty_out (vty, "interface %s%s", 960 o6i->interface->name, VTY_NEWLINE); 961 vty_out (vty, " ipv6 ospf6 cost %d%s", 962 o6i->cost, VTY_NEWLINE); 963 vty_out (vty, " ipv6 ospf6 hello-interval %d%s", 964 o6i->hello_interval, VTY_NEWLINE); 965 vty_out (vty, " ipv6 ospf6 dead-interval %d%s", 966 o6i->dead_interval, VTY_NEWLINE); 967 vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s", 968 o6i->rxmt_interval, VTY_NEWLINE); 969 vty_out (vty, " ipv6 ospf6 priority %d%s", 970 o6i->priority, VTY_NEWLINE); 971 vty_out (vty, " ipv6 ospf6 transmit-delay %d%s", 972 o6i->transdelay, VTY_NEWLINE); 973 vty_out (vty, " ipv6 ospf6 instance-id %d%s", 974 o6i->instance_id, VTY_NEWLINE); 975 976 if (CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_FORCE_PREFIX)) 977 vty_out (vty, " ipv6 ospf6 advertise force-prefix%s", VTY_NEWLINE); 978 if (o6i->plist_name) 979 vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s", 980 o6i->plist_name, VTY_NEWLINE); 981 982 if (CHECK_FLAG (o6i->flag, OSPF6_INTERFACE_FLAG_PASSIVE)) 983 vty_out (vty, " ipv6 ospf6 passive%s", VTY_NEWLINE); 984 985 vty_out (vty, "!%s", VTY_NEWLINE); 986 } 987 return 0; 988} 989 990struct cmd_node interface_node = 991{ 992 INTERFACE_NODE, 993 "%s(config-if)# ", 994}; 995 996void 997ospf6_interface_init () 998{ 999 /* Install interface node. */ 1000 install_node (&interface_node, ospf6_interface_config_write); 1001 1002 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd); 1003 install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); 1004 install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd); 1005 install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd); 1006 1007 install_default (INTERFACE_NODE); 1008 install_element (INTERFACE_NODE, &interface_desc_cmd); 1009 install_element (INTERFACE_NODE, &no_interface_desc_cmd); 1010 install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd); 1011 install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd); 1012 install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd); 1013 install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd); 1014 install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd); 1015 install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd); 1016 install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd); 1017 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_force_prefix_cmd); 1018 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_force_prefix_cmd); 1019 install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd); 1020 install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd); 1021 install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd); 1022 install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd); 1023} 1024 1025 1026