1/* 2 * Copyright (C) 2003 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 <zebra.h> 23 24#include "log.h" 25#include "linklist.h" 26#include "thread.h" 27#include "memory.h" 28#include "if.h" 29#include "prefix.h" 30#include "table.h" 31#include "vty.h" 32#include "command.h" 33 34#include "ospf6_proto.h" 35#include "ospf6_message.h" 36#include "ospf6_route.h" 37#include "ospf6_lsa.h" 38#include "ospf6_lsdb.h" 39 40#include "ospf6_top.h" 41#include "ospf6_area.h" 42#include "ospf6_interface.h" 43#include "ospf6_neighbor.h" 44#include "ospf6_intra.h" 45#include "ospf6_asbr.h" 46#include "ospf6_abr.h" 47#include "ospf6_flood.h" 48#include "ospf6d.h" 49#include "ospf6_spf.h" 50 51unsigned char conf_debug_ospf6_brouter = 0; 52u_int32_t conf_debug_ospf6_brouter_specific_router_id; 53u_int32_t conf_debug_ospf6_brouter_specific_area_id; 54 55/******************************/ 56/* RFC2740 3.4.3.1 Router-LSA */ 57/******************************/ 58 59static char * 60ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen, 61 int pos) 62{ 63 struct ospf6_router_lsa *router_lsa; 64 struct ospf6_router_lsdesc *lsdesc; 65 char *start, *end; 66 char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN]; 67 68 if (lsa) 69 { 70 router_lsa = (struct ospf6_router_lsa *) 71 ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); 72 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa); 73 end = (char *) lsa->header + ntohs (lsa->header->length); 74 75 lsdesc = (struct ospf6_router_lsdesc *) 76 (start + pos*(sizeof (struct ospf6_router_lsdesc))); 77 if ((char *)lsdesc < end) 78 { 79 if (buf && (buflen > INET_ADDRSTRLEN*2)) 80 { 81 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, 82 buf1, sizeof(buf1)); 83 inet_ntop (AF_INET, &lsdesc->neighbor_router_id, 84 buf2, sizeof(buf2)); 85 sprintf (buf, "%s/%s", buf2, buf1); 86 } 87 } 88 else 89 return NULL; 90 } 91 92 return buf; 93} 94 95static int 96ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) 97{ 98 char *start, *end, *current; 99 char buf[32], name[32], bits[16], options[32]; 100 struct ospf6_router_lsa *router_lsa; 101 struct ospf6_router_lsdesc *lsdesc; 102 103 router_lsa = (struct ospf6_router_lsa *) 104 ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); 105 106 ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits)); 107 ospf6_options_printbuf (router_lsa->options, options, sizeof (options)); 108 vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL); 109 110 start = (char *) router_lsa + sizeof (struct ospf6_router_lsa); 111 end = (char *) lsa->header + ntohs (lsa->header->length); 112 for (current = start; current + sizeof (struct ospf6_router_lsdesc) <= end; 113 current += sizeof (struct ospf6_router_lsdesc)) 114 { 115 lsdesc = (struct ospf6_router_lsdesc *) current; 116 117 if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT) 118 snprintf (name, sizeof (name), "Point-To-Point"); 119 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK) 120 snprintf (name, sizeof (name), "Transit-Network"); 121 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK) 122 snprintf (name, sizeof (name), "Stub-Network"); 123 else if (lsdesc->type == OSPF6_ROUTER_LSDESC_VIRTUAL_LINK) 124 snprintf (name, sizeof (name), "Virtual-Link"); 125 else 126 snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type); 127 128 vty_out (vty, " Type: %s Metric: %d%s", 129 name, ntohs (lsdesc->metric), VNL); 130 vty_out (vty, " Interface ID: %s%s", 131 inet_ntop (AF_INET, &lsdesc->interface_id, 132 buf, sizeof (buf)), VNL); 133 vty_out (vty, " Neighbor Interface ID: %s%s", 134 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, 135 buf, sizeof (buf)), VNL); 136 vty_out (vty, " Neighbor Router ID: %s%s", 137 inet_ntop (AF_INET, &lsdesc->neighbor_router_id, 138 buf, sizeof (buf)), VNL); 139 } 140 return 0; 141} 142 143int 144ospf6_router_is_stub_router (struct ospf6_lsa *lsa) 145{ 146 struct ospf6_router_lsa *rtr_lsa; 147 148 if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa)) 149 { 150 rtr_lsa = (struct ospf6_router_lsa *) 151 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 152 153 if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R)) 154 { 155 return (OSPF6_IS_STUB_ROUTER); 156 } 157 else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6)) 158 { 159 return (OSPF6_IS_STUB_ROUTER_V6); 160 } 161 } 162 163 return (OSPF6_NOT_STUB_ROUTER); 164} 165 166int 167ospf6_router_lsa_originate (struct thread *thread) 168{ 169 struct ospf6_area *oa; 170 171 char buffer [OSPF6_MAX_LSASIZE]; 172 struct ospf6_lsa_header *lsa_header; 173 struct ospf6_lsa *lsa; 174 175 u_int32_t link_state_id = 0; 176 struct listnode *node, *nnode; 177 struct listnode *j; 178 struct ospf6_interface *oi; 179 struct ospf6_neighbor *on, *drouter = NULL; 180 struct ospf6_router_lsa *router_lsa; 181 struct ospf6_router_lsdesc *lsdesc; 182 u_int16_t type; 183 u_int32_t router; 184 int count; 185 186 oa = (struct ospf6_area *) THREAD_ARG (thread); 187 oa->thread_router_lsa = NULL; 188 189 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) 190 zlog_debug ("Originate Router-LSA for Area %s", oa->name); 191 192 memset (buffer, 0, sizeof (buffer)); 193 lsa_header = (struct ospf6_lsa_header *) buffer; 194 router_lsa = (struct ospf6_router_lsa *) 195 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 196 197 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6); 198 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E); 199 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC); 200 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N); 201 OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R); 202 OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC); 203 204 if (ospf6_is_router_abr (ospf6)) 205 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); 206 else 207 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); 208 if (ospf6_asbr_is_asbr (ospf6)) 209 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); 210 else 211 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); 212 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V); 213 UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W); 214 215 /* describe links for each interfaces */ 216 lsdesc = (struct ospf6_router_lsdesc *) 217 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)); 218 219 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) 220 { 221 /* Interfaces in state Down or Loopback are not described */ 222 if (oi->state == OSPF6_INTERFACE_DOWN || 223 oi->state == OSPF6_INTERFACE_LOOPBACK) 224 continue; 225 226 /* Nor are interfaces without any full adjacencies described */ 227 count = 0; 228 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) 229 if (on->state == OSPF6_NEIGHBOR_FULL) 230 count++; 231 232 if (count == 0) 233 continue; 234 235 /* Multiple Router-LSA instance according to size limit setting */ 236 if ( (oa->router_lsa_size_limit != 0) 237 && ((caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) - 238 /* XXX warning: comparison between signed and unsigned */ 239 (caddr_t) buffer > oa->router_lsa_size_limit)) 240 { 241 if ((caddr_t) lsdesc == (caddr_t) router_lsa + 242 sizeof (struct ospf6_router_lsa)) 243 { 244 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) 245 zlog_debug ("Size limit setting for Router-LSA too short"); 246 return 0; 247 } 248 249 /* Fill LSA Header */ 250 lsa_header->age = 0; 251 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER); 252 lsa_header->id = htonl (link_state_id); 253 lsa_header->adv_router = oa->ospf6->router_id; 254 lsa_header->seqnum = 255 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 256 lsa_header->adv_router, oa->lsdb); 257 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); 258 259 /* LSA checksum */ 260 ospf6_lsa_checksum (lsa_header); 261 262 /* create LSA */ 263 lsa = ospf6_lsa_create (lsa_header); 264 265 /* Originate */ 266 ospf6_lsa_originate_area (lsa, oa); 267 268 /* Reset setting for consecutive origination */ 269 memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa), 270 0, (caddr_t) lsdesc - (caddr_t) router_lsa); 271 lsdesc = (struct ospf6_router_lsdesc *) 272 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)); 273 link_state_id ++; 274 } 275 276 /* Point-to-Point interfaces */ 277 if (oi->type == OSPF_IFTYPE_POINTOPOINT) 278 { 279 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) 280 { 281 if (on->state != OSPF6_NEIGHBOR_FULL) 282 continue; 283 284 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT; 285 lsdesc->metric = htons (oi->cost); 286 lsdesc->interface_id = htonl (oi->interface->ifindex); 287 lsdesc->neighbor_interface_id = htonl (on->ifindex); 288 lsdesc->neighbor_router_id = on->router_id; 289 290 lsdesc++; 291 } 292 } 293 294 /* Broadcast and NBMA interfaces */ 295 else if (oi->type == OSPF_IFTYPE_BROADCAST) 296 { 297 /* If this router is not DR, 298 and If this router not fully adjacent with DR, 299 this interface is not transit yet: ignore. */ 300 if (oi->state != OSPF6_INTERFACE_DR) 301 { 302 drouter = ospf6_neighbor_lookup (oi->drouter, oi); 303 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL) 304 continue; 305 } 306 307 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK; 308 lsdesc->metric = htons (oi->cost); 309 lsdesc->interface_id = htonl (oi->interface->ifindex); 310 if (oi->state != OSPF6_INTERFACE_DR) 311 { 312 lsdesc->neighbor_interface_id = htonl (drouter->ifindex); 313 lsdesc->neighbor_router_id = drouter->router_id; 314 } 315 else 316 { 317 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex); 318 lsdesc->neighbor_router_id = oi->area->ospf6->router_id; 319 } 320 321 lsdesc++; 322 } 323 else 324 { 325 assert (0); /* Unknown interface type */ 326 } 327 328 /* Virtual links */ 329 /* xxx */ 330 /* Point-to-Multipoint interfaces */ 331 /* xxx */ 332 } 333 334 /* Fill LSA Header */ 335 lsa_header->age = 0; 336 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER); 337 lsa_header->id = htonl (link_state_id); 338 lsa_header->adv_router = oa->ospf6->router_id; 339 lsa_header->seqnum = 340 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 341 lsa_header->adv_router, oa->lsdb); 342 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); 343 344 /* LSA checksum */ 345 ospf6_lsa_checksum (lsa_header); 346 347 /* create LSA */ 348 lsa = ospf6_lsa_create (lsa_header); 349 350 /* Originate */ 351 ospf6_lsa_originate_area (lsa, oa); 352 353 link_state_id ++; 354 355 /* Do premature-aging of rest, undesired Router-LSAs */ 356 type = ntohs (OSPF6_LSTYPE_ROUTER); 357 router = oa->ospf6->router_id; 358 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa; 359 lsa = ospf6_lsdb_type_router_next (type, router, lsa)) 360 { 361 if (ntohl (lsa->header->id) < link_state_id) 362 continue; 363 ospf6_lsa_purge (lsa); 364 } 365 366 return 0; 367} 368 369/*******************************/ 370/* RFC2740 3.4.3.2 Network-LSA */ 371/*******************************/ 372 373static char * 374ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen, 375 int pos) 376{ 377 char *start, *end, *current; 378 struct ospf6_network_lsa *network_lsa; 379 struct ospf6_network_lsdesc *lsdesc; 380 381 if (lsa) 382 { 383 network_lsa = (struct ospf6_network_lsa *) 384 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 385 386 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); 387 end = (char *) lsa->header + ntohs (lsa->header->length); 388 current = start + pos*(sizeof (struct ospf6_network_lsdesc)); 389 390 if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) 391 { 392 lsdesc = (struct ospf6_network_lsdesc *)current; 393 if (buf) 394 inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen); 395 } 396 else 397 return NULL; 398 } 399 400 return (buf); 401} 402 403static int 404ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) 405{ 406 char *start, *end, *current; 407 struct ospf6_network_lsa *network_lsa; 408 struct ospf6_network_lsdesc *lsdesc; 409 char buf[128], options[32]; 410 411 network_lsa = (struct ospf6_network_lsa *) 412 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 413 414 ospf6_options_printbuf (network_lsa->options, options, sizeof (options)); 415 vty_out (vty, " Options: %s%s", options, VNL); 416 417 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); 418 end = (char *) lsa->header + ntohs (lsa->header->length); 419 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end; 420 current += sizeof (struct ospf6_network_lsdesc)) 421 { 422 lsdesc = (struct ospf6_network_lsdesc *) current; 423 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf)); 424 vty_out (vty, " Attached Router: %s%s", buf, VNL); 425 } 426 return 0; 427} 428 429int 430ospf6_network_lsa_originate (struct thread *thread) 431{ 432 struct ospf6_interface *oi; 433 434 char buffer [OSPF6_MAX_LSASIZE]; 435 struct ospf6_lsa_header *lsa_header; 436 437 int count; 438 struct ospf6_lsa *old, *lsa; 439 struct ospf6_network_lsa *network_lsa; 440 struct ospf6_network_lsdesc *lsdesc; 441 struct ospf6_neighbor *on; 442 struct ospf6_link_lsa *link_lsa; 443 struct listnode *i; 444 u_int16_t type; 445 446 oi = (struct ospf6_interface *) THREAD_ARG (thread); 447 oi->thread_network_lsa = NULL; 448 449 /* The interface must be enabled until here. A Network-LSA of a 450 disabled interface (but was once enabled) should be flushed 451 by ospf6_lsa_refresh (), and does not come here. */ 452 assert (oi->area); 453 454 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK), 455 htonl (oi->interface->ifindex), 456 oi->area->ospf6->router_id, oi->area->lsdb); 457 458 /* Do not originate Network-LSA if not DR */ 459 if (oi->state != OSPF6_INTERFACE_DR) 460 { 461 if (old) 462 ospf6_lsa_purge (old); 463 return 0; 464 } 465 466 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) 467 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name); 468 469 /* If none of neighbor is adjacent to us */ 470 count = 0; 471 472 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) 473 if (on->state == OSPF6_NEIGHBOR_FULL) 474 count++; 475 476 if (count == 0) 477 { 478 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) 479 zlog_debug ("Interface stub, ignore"); 480 if (old) 481 ospf6_lsa_purge (old); 482 return 0; 483 } 484 485 /* prepare buffer */ 486 memset (buffer, 0, sizeof (buffer)); 487 lsa_header = (struct ospf6_lsa_header *) buffer; 488 network_lsa = (struct ospf6_network_lsa *) 489 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 490 491 /* Collect the interface's Link-LSAs to describe 492 network's optional capabilities */ 493 type = htons (OSPF6_LSTYPE_LINK); 494 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; 495 lsa = ospf6_lsdb_type_next (type, lsa)) 496 { 497 link_lsa = (struct ospf6_link_lsa *) 498 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 499 network_lsa->options[0] |= link_lsa->options[0]; 500 network_lsa->options[1] |= link_lsa->options[1]; 501 network_lsa->options[2] |= link_lsa->options[2]; 502 } 503 504 lsdesc = (struct ospf6_network_lsdesc *) 505 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa)); 506 507 /* set Link Description to the router itself */ 508 lsdesc->router_id = oi->area->ospf6->router_id; 509 lsdesc++; 510 511 /* Walk through the neighbors */ 512 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) 513 { 514 if (on->state != OSPF6_NEIGHBOR_FULL) 515 continue; 516 517 /* set this neighbor's Router-ID to LSA */ 518 lsdesc->router_id = on->router_id; 519 lsdesc++; 520 } 521 522 /* Fill LSA Header */ 523 lsa_header->age = 0; 524 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK); 525 lsa_header->id = htonl (oi->interface->ifindex); 526 lsa_header->adv_router = oi->area->ospf6->router_id; 527 lsa_header->seqnum = 528 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 529 lsa_header->adv_router, oi->area->lsdb); 530 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); 531 532 /* LSA checksum */ 533 ospf6_lsa_checksum (lsa_header); 534 535 /* create LSA */ 536 lsa = ospf6_lsa_create (lsa_header); 537 538 /* Originate */ 539 ospf6_lsa_originate_area (lsa, oi->area); 540 541 return 0; 542} 543 544 545/****************************/ 546/* RFC2740 3.4.3.6 Link-LSA */ 547/****************************/ 548 549static char * 550ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen, 551 int pos) 552{ 553 char *start, *end, *current; 554 struct ospf6_link_lsa *link_lsa; 555 struct in6_addr in6; 556 struct ospf6_prefix *prefix; 557 int cnt = 0, prefixnum; 558 559 if (lsa) 560 { 561 link_lsa = (struct ospf6_link_lsa *) 562 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 563 564 if (pos == 0) { 565 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen); 566 return (buf); 567 } 568 569 prefixnum = ntohl (link_lsa->prefix_num); 570 if (pos > prefixnum) 571 return (NULL); 572 573 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); 574 end = (char *) lsa->header + ntohs (lsa->header->length); 575 current = start; 576 577 do 578 { 579 prefix = (struct ospf6_prefix *) current; 580 if (prefix->prefix_length == 0 || 581 current + OSPF6_PREFIX_SIZE (prefix) > end) 582 { 583 return (NULL); 584 } 585 586 if (cnt < pos) 587 { 588 current = start + pos*OSPF6_PREFIX_SIZE(prefix); 589 cnt++; 590 } 591 else 592 { 593 memset (&in6, 0, sizeof (in6)); 594 memcpy (&in6, OSPF6_PREFIX_BODY (prefix), 595 OSPF6_PREFIX_SPACE (prefix->prefix_length)); 596 inet_ntop (AF_INET6, &in6, buf, buflen); 597 return (buf); 598 } 599 } while (current <= end); 600 } 601 return (NULL); 602} 603 604static int 605ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) 606{ 607 char *start, *end, *current; 608 struct ospf6_link_lsa *link_lsa; 609 int prefixnum; 610 char buf[128], options[32]; 611 struct ospf6_prefix *prefix; 612 const char *p, *mc, *la, *nu; 613 struct in6_addr in6; 614 615 link_lsa = (struct ospf6_link_lsa *) 616 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 617 618 ospf6_options_printbuf (link_lsa->options, options, sizeof (options)); 619 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf)); 620 prefixnum = ntohl (link_lsa->prefix_num); 621 622 vty_out (vty, " Priority: %d Options: %s%s", 623 link_lsa->priority, options, VNL); 624 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL); 625 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL); 626 627 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); 628 end = (char *) lsa->header + ntohs (lsa->header->length); 629 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) 630 { 631 prefix = (struct ospf6_prefix *) current; 632 if (prefix->prefix_length == 0 || 633 current + OSPF6_PREFIX_SIZE (prefix) > end) 634 break; 635 636 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? 637 "P" : "--"); 638 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? 639 "MC" : "--"); 640 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? 641 "LA" : "--"); 642 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? 643 "NU" : "--"); 644 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s", 645 p, mc, la, nu, VNL); 646 647 memset (&in6, 0, sizeof (in6)); 648 memcpy (&in6, OSPF6_PREFIX_BODY (prefix), 649 OSPF6_PREFIX_SPACE (prefix->prefix_length)); 650 inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); 651 vty_out (vty, " Prefix: %s/%d%s", 652 buf, prefix->prefix_length, VNL); 653 } 654 655 return 0; 656} 657 658int 659ospf6_link_lsa_originate (struct thread *thread) 660{ 661 struct ospf6_interface *oi; 662 663 char buffer[OSPF6_MAX_LSASIZE]; 664 struct ospf6_lsa_header *lsa_header; 665 struct ospf6_lsa *old, *lsa; 666 667 struct ospf6_link_lsa *link_lsa; 668 struct ospf6_route *route; 669 struct ospf6_prefix *op; 670 671 oi = (struct ospf6_interface *) THREAD_ARG (thread); 672 oi->thread_link_lsa = NULL; 673 674 assert (oi->area); 675 676 /* find previous LSA */ 677 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK), 678 htonl (oi->interface->ifindex), 679 oi->area->ospf6->router_id, oi->lsdb); 680 681 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) 682 { 683 if (old) 684 ospf6_lsa_purge (old); 685 return 0; 686 } 687 688 if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) 689 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name); 690 691 /* can't make Link-LSA if linklocal address not set */ 692 if (oi->linklocal_addr == NULL) 693 { 694 if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) 695 zlog_debug ("No Linklocal address on %s, defer originating", 696 oi->interface->name); 697 if (old) 698 ospf6_lsa_purge (old); 699 return 0; 700 } 701 702 /* prepare buffer */ 703 memset (buffer, 0, sizeof (buffer)); 704 lsa_header = (struct ospf6_lsa_header *) buffer; 705 link_lsa = (struct ospf6_link_lsa *) 706 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 707 708 /* Fill Link-LSA */ 709 link_lsa->priority = oi->priority; 710 memcpy (link_lsa->options, oi->area->options, 3); 711 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr, 712 sizeof (struct in6_addr)); 713 link_lsa->prefix_num = htonl (oi->route_connected->count); 714 715 op = (struct ospf6_prefix *) 716 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa)); 717 718 /* connected prefix to advertise */ 719 for (route = ospf6_route_head (oi->route_connected); route; 720 route = ospf6_route_next (route)) 721 { 722 op->prefix_length = route->prefix.prefixlen; 723 op->prefix_options = route->path.prefix_options; 724 op->prefix_metric = htons (0); 725 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, 726 OSPF6_PREFIX_SPACE (op->prefix_length)); 727 op = OSPF6_PREFIX_NEXT (op); 728 } 729 730 /* Fill LSA Header */ 731 lsa_header->age = 0; 732 lsa_header->type = htons (OSPF6_LSTYPE_LINK); 733 lsa_header->id = htonl (oi->interface->ifindex); 734 lsa_header->adv_router = oi->area->ospf6->router_id; 735 lsa_header->seqnum = 736 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 737 lsa_header->adv_router, oi->lsdb); 738 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer); 739 740 /* LSA checksum */ 741 ospf6_lsa_checksum (lsa_header); 742 743 /* create LSA */ 744 lsa = ospf6_lsa_create (lsa_header); 745 746 /* Originate */ 747 ospf6_lsa_originate_interface (lsa, oi); 748 749 return 0; 750} 751 752 753/*****************************************/ 754/* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */ 755/*****************************************/ 756static char * 757ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, 758 int buflen, int pos) 759{ 760 char *start, *end, *current; 761 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 762 struct in6_addr in6; 763 int prefixnum, cnt = 0; 764 struct ospf6_prefix *prefix; 765 766 if (lsa) 767 { 768 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 769 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 770 771 prefixnum = ntohs (intra_prefix_lsa->prefix_num); 772 if (pos > prefixnum) 773 return (NULL); 774 775 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); 776 end = (char *) lsa->header + ntohs (lsa->header->length); 777 current = start; 778 779 do 780 { 781 prefix = (struct ospf6_prefix *) current; 782 if (prefix->prefix_length == 0 || 783 current + OSPF6_PREFIX_SIZE (prefix) > end) 784 { 785 return NULL; 786 } 787 788 if (cnt < pos) 789 { 790 current = start + pos*OSPF6_PREFIX_SIZE(prefix); 791 cnt++; 792 } 793 else 794 { 795 memset (&in6, 0, sizeof (in6)); 796 memcpy (&in6, OSPF6_PREFIX_BODY (prefix), 797 OSPF6_PREFIX_SPACE (prefix->prefix_length)); 798 inet_ntop (AF_INET6, &in6, buf, buflen); 799 sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length); 800 return (buf); 801 } 802 } while (current <= end); 803 } 804 return (buf); 805} 806 807static int 808ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa) 809{ 810 char *start, *end, *current; 811 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 812 int prefixnum; 813 char buf[128]; 814 struct ospf6_prefix *prefix; 815 char id[16], adv_router[16]; 816 const char *p, *mc, *la, *nu; 817 struct in6_addr in6; 818 819 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 820 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 821 822 prefixnum = ntohs (intra_prefix_lsa->prefix_num); 823 824 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL); 825 826 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id)); 827 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router, 828 adv_router, sizeof (adv_router)); 829 vty_out (vty, " Reference: %s Id: %s Adv: %s%s", 830 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router, 831 VNL); 832 833 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); 834 end = (char *) lsa->header + ntohs (lsa->header->length); 835 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) 836 { 837 prefix = (struct ospf6_prefix *) current; 838 if (prefix->prefix_length == 0 || 839 current + OSPF6_PREFIX_SIZE (prefix) > end) 840 break; 841 842 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? 843 "P" : "--"); 844 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? 845 "MC" : "--"); 846 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? 847 "LA" : "--"); 848 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? 849 "NU" : "--"); 850 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s", 851 p, mc, la, nu, VNL); 852 853 memset (&in6, 0, sizeof (in6)); 854 memcpy (&in6, OSPF6_PREFIX_BODY (prefix), 855 OSPF6_PREFIX_SPACE (prefix->prefix_length)); 856 inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); 857 vty_out (vty, " Prefix: %s/%d%s", 858 buf, prefix->prefix_length, VNL); 859 } 860 861 return 0; 862} 863 864int 865ospf6_intra_prefix_lsa_originate_stub (struct thread *thread) 866{ 867 struct ospf6_area *oa; 868 869 char buffer[OSPF6_MAX_LSASIZE]; 870 struct ospf6_lsa_header *lsa_header; 871 struct ospf6_lsa *old, *lsa; 872 873 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 874 struct ospf6_interface *oi; 875 struct ospf6_neighbor *on; 876 struct ospf6_route *route; 877 struct ospf6_prefix *op; 878 struct listnode *i, *j; 879 int full_count = 0; 880 unsigned short prefix_num = 0; 881 char buf[BUFSIZ]; 882 struct ospf6_route_table *route_advertise; 883 884 oa = (struct ospf6_area *) THREAD_ARG (thread); 885 oa->thread_intra_prefix_lsa = NULL; 886 887 /* find previous LSA */ 888 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX), 889 htonl (0), oa->ospf6->router_id, oa->lsdb); 890 891 if (! IS_AREA_ENABLED (oa)) 892 { 893 if (old) 894 ospf6_lsa_purge (old); 895 return 0; 896 } 897 898 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 899 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix", 900 oa->name); 901 902 /* prepare buffer */ 903 memset (buffer, 0, sizeof (buffer)); 904 lsa_header = (struct ospf6_lsa_header *) buffer; 905 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 906 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 907 908 /* Fill Intra-Area-Prefix-LSA */ 909 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER); 910 intra_prefix_lsa->ref_id = htonl (0); 911 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; 912 913 route_advertise = ospf6_route_table_create (0, 0); 914 915 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi)) 916 { 917 if (oi->state == OSPF6_INTERFACE_DOWN) 918 { 919 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 920 zlog_debug (" Interface %s is down, ignore", oi->interface->name); 921 continue; 922 } 923 924 full_count = 0; 925 926 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) 927 if (on->state == OSPF6_NEIGHBOR_FULL) 928 full_count++; 929 930 if (oi->state != OSPF6_INTERFACE_LOOPBACK && 931 oi->state != OSPF6_INTERFACE_POINTTOPOINT && 932 full_count != 0) 933 { 934 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 935 zlog_debug (" Interface %s is not stub, ignore", 936 oi->interface->name); 937 continue; 938 } 939 940 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 941 zlog_debug (" Interface %s:", oi->interface->name); 942 943 /* connected prefix to advertise */ 944 for (route = ospf6_route_head (oi->route_connected); route; 945 route = ospf6_route_best_next (route)) 946 { 947 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 948 { 949 prefix2str (&route->prefix, buf, sizeof (buf)); 950 zlog_debug (" include %s", buf); 951 } 952 ospf6_route_add (ospf6_route_copy (route), route_advertise); 953 } 954 } 955 956 if (route_advertise->count == 0) 957 { 958 if (old) 959 ospf6_lsa_purge (old); 960 ospf6_route_table_delete (route_advertise); 961 return 0; 962 } 963 964 /* put prefixes to advertise */ 965 prefix_num = 0; 966 op = (struct ospf6_prefix *) 967 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); 968 for (route = ospf6_route_head (route_advertise); route; 969 route = ospf6_route_best_next (route)) 970 { 971 op->prefix_length = route->prefix.prefixlen; 972 op->prefix_options = route->path.prefix_options; 973 op->prefix_metric = htons (route->path.cost); 974 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, 975 OSPF6_PREFIX_SPACE (op->prefix_length)); 976 op = OSPF6_PREFIX_NEXT (op); 977 prefix_num++; 978 } 979 980 ospf6_route_table_delete (route_advertise); 981 982 if (prefix_num == 0) 983 { 984 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 985 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise"); 986 return 0; 987 } 988 989 intra_prefix_lsa->prefix_num = htons (prefix_num); 990 991 /* Fill LSA Header */ 992 lsa_header->age = 0; 993 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); 994 lsa_header->id = htonl (0); 995 lsa_header->adv_router = oa->ospf6->router_id; 996 lsa_header->seqnum = 997 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 998 lsa_header->adv_router, oa->lsdb); 999 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); 1000 1001 /* LSA checksum */ 1002 ospf6_lsa_checksum (lsa_header); 1003 1004 /* create LSA */ 1005 lsa = ospf6_lsa_create (lsa_header); 1006 1007 /* Originate */ 1008 ospf6_lsa_originate_area (lsa, oa); 1009 1010 return 0; 1011} 1012 1013 1014int 1015ospf6_intra_prefix_lsa_originate_transit (struct thread *thread) 1016{ 1017 struct ospf6_interface *oi; 1018 1019 char buffer[OSPF6_MAX_LSASIZE]; 1020 struct ospf6_lsa_header *lsa_header; 1021 struct ospf6_lsa *old, *lsa; 1022 1023 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 1024 struct ospf6_neighbor *on; 1025 struct ospf6_route *route; 1026 struct ospf6_prefix *op; 1027 struct listnode *i; 1028 int full_count = 0; 1029 unsigned short prefix_num = 0; 1030 struct ospf6_route_table *route_advertise; 1031 struct ospf6_link_lsa *link_lsa; 1032 char *start, *end, *current; 1033 u_int16_t type; 1034 char buf[BUFSIZ]; 1035 1036 oi = (struct ospf6_interface *) THREAD_ARG (thread); 1037 oi->thread_intra_prefix_lsa = NULL; 1038 1039 assert (oi->area); 1040 1041 /* find previous LSA */ 1042 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX), 1043 htonl (oi->interface->ifindex), 1044 oi->area->ospf6->router_id, oi->area->lsdb); 1045 1046 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) 1047 { 1048 if (old) 1049 ospf6_lsa_purge (old); 1050 return 0; 1051 } 1052 1053 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1054 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix", 1055 oi->interface->name); 1056 1057 /* prepare buffer */ 1058 memset (buffer, 0, sizeof (buffer)); 1059 lsa_header = (struct ospf6_lsa_header *) buffer; 1060 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 1061 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 1062 1063 /* Fill Intra-Area-Prefix-LSA */ 1064 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK); 1065 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex); 1066 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id; 1067 1068 if (oi->state != OSPF6_INTERFACE_DR) 1069 { 1070 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1071 zlog_debug (" Interface is not DR"); 1072 if (old) 1073 ospf6_lsa_purge (old); 1074 return 0; 1075 } 1076 1077 full_count = 0; 1078 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on)) 1079 if (on->state == OSPF6_NEIGHBOR_FULL) 1080 full_count++; 1081 1082 if (full_count == 0) 1083 { 1084 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1085 zlog_debug (" Interface is stub"); 1086 if (old) 1087 ospf6_lsa_purge (old); 1088 return 0; 1089 } 1090 1091 /* connected prefix to advertise */ 1092 route_advertise = ospf6_route_table_create (0, 0); 1093 1094 type = ntohs (OSPF6_LSTYPE_LINK); 1095 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; 1096 lsa = ospf6_lsdb_type_next (type, lsa)) 1097 { 1098 if (OSPF6_LSA_IS_MAXAGE (lsa)) 1099 continue; 1100 1101 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1102 zlog_debug (" include prefix from %s", lsa->name); 1103 1104 if (lsa->header->adv_router != oi->area->ospf6->router_id) 1105 { 1106 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi); 1107 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL) 1108 { 1109 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1110 zlog_debug (" Neighbor not found or not Full, ignore"); 1111 continue; 1112 } 1113 } 1114 1115 link_lsa = (struct ospf6_link_lsa *) 1116 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); 1117 1118 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num); 1119 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); 1120 end = (char *) lsa->header + ntohs (lsa->header->length); 1121 for (current = start; current < end && prefix_num; 1122 current += OSPF6_PREFIX_SIZE (op)) 1123 { 1124 op = (struct ospf6_prefix *) current; 1125 if (op->prefix_length == 0 || 1126 current + OSPF6_PREFIX_SIZE (op) > end) 1127 break; 1128 1129 route = ospf6_route_create (); 1130 1131 route->type = OSPF6_DEST_TYPE_NETWORK; 1132 route->prefix.family = AF_INET6; 1133 route->prefix.prefixlen = op->prefix_length; 1134 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr)); 1135 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op), 1136 OSPF6_PREFIX_SPACE (op->prefix_length)); 1137 1138 route->path.origin.type = lsa->header->type; 1139 route->path.origin.id = lsa->header->id; 1140 route->path.origin.adv_router = lsa->header->adv_router; 1141 route->path.options[0] = link_lsa->options[0]; 1142 route->path.options[1] = link_lsa->options[1]; 1143 route->path.options[2] = link_lsa->options[2]; 1144 route->path.prefix_options = op->prefix_options; 1145 route->path.area_id = oi->area->area_id; 1146 route->path.type = OSPF6_PATH_TYPE_INTRA; 1147 1148 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1149 { 1150 prefix2str (&route->prefix, buf, sizeof (buf)); 1151 zlog_debug (" include %s", buf); 1152 } 1153 1154 ospf6_route_add (route, route_advertise); 1155 prefix_num--; 1156 } 1157 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1158 zlog_debug ("Trailing garbage in %s", lsa->name); 1159 } 1160 1161 op = (struct ospf6_prefix *) 1162 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); 1163 1164 prefix_num = 0; 1165 for (route = ospf6_route_head (route_advertise); route; 1166 route = ospf6_route_best_next (route)) 1167 { 1168 op->prefix_length = route->prefix.prefixlen; 1169 op->prefix_options = route->path.prefix_options; 1170 op->prefix_metric = htons (0); 1171 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, 1172 OSPF6_PREFIX_SPACE (op->prefix_length)); 1173 op = OSPF6_PREFIX_NEXT (op); 1174 prefix_num++; 1175 } 1176 1177 ospf6_route_table_delete (route_advertise); 1178 1179 if (prefix_num == 0) 1180 { 1181 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) 1182 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise"); 1183 return 0; 1184 } 1185 1186 intra_prefix_lsa->prefix_num = htons (prefix_num); 1187 1188 /* Fill LSA Header */ 1189 lsa_header->age = 0; 1190 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); 1191 lsa_header->id = htonl (oi->interface->ifindex); 1192 lsa_header->adv_router = oi->area->ospf6->router_id; 1193 lsa_header->seqnum = 1194 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, 1195 lsa_header->adv_router, oi->area->lsdb); 1196 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); 1197 1198 /* LSA checksum */ 1199 ospf6_lsa_checksum (lsa_header); 1200 1201 /* create LSA */ 1202 lsa = ospf6_lsa_create (lsa_header); 1203 1204 /* Originate */ 1205 ospf6_lsa_originate_area (lsa, oi->area); 1206 1207 return 0; 1208} 1209 1210void 1211ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa) 1212{ 1213 struct ospf6_area *oa; 1214 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 1215 struct prefix ls_prefix; 1216 struct ospf6_route *route, *ls_entry; 1217 int i, prefix_num; 1218 struct ospf6_prefix *op; 1219 char *start, *current, *end; 1220 char buf[64]; 1221 struct interface *ifp; 1222 int direct_connect = 0; 1223 1224 if (OSPF6_LSA_IS_MAXAGE (lsa)) 1225 return; 1226 1227 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1228 zlog_debug ("%s found", lsa->name); 1229 1230 oa = OSPF6_AREA (lsa->lsdb->data); 1231 1232 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 1233 OSPF6_LSA_HEADER_END (lsa->header); 1234 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER)) 1235 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, 1236 htonl (0), &ls_prefix); 1237 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK)) 1238 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router, 1239 intra_prefix_lsa->ref_id, &ls_prefix); 1240 else 1241 { 1242 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1243 zlog_debug ("Unknown reference LS-type: %#hx", 1244 ntohs (intra_prefix_lsa->ref_type)); 1245 return; 1246 } 1247 1248 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table); 1249 if (ls_entry == NULL) 1250 { 1251 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1252 { 1253 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf)); 1254 zlog_debug ("LS entry does not exist: %s", buf); 1255 } 1256 return; 1257 } 1258 1259 if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) 1260 { 1261 /* the intra-prefix are directly connected */ 1262 direct_connect = 1; 1263 } 1264 1265 prefix_num = ntohs (intra_prefix_lsa->prefix_num); 1266 start = (caddr_t) intra_prefix_lsa + 1267 sizeof (struct ospf6_intra_prefix_lsa); 1268 end = OSPF6_LSA_END (lsa->header); 1269 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) 1270 { 1271 op = (struct ospf6_prefix *) current; 1272 if (prefix_num == 0) 1273 break; 1274 if (end < current + OSPF6_PREFIX_SIZE (op)) 1275 break; 1276 1277 /* Appendix A.4.1.1 */ 1278 if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU) || 1279 CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_LA)) 1280 { 1281 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1282 { 1283 ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op), 1284 buf, sizeof (buf)); 1285 zlog_debug ("%s: Skipping Prefix %s has NU/LA option set", 1286 __func__, buf); 1287 } 1288 continue; 1289 } 1290 1291 route = ospf6_route_create (); 1292 1293 memset (&route->prefix, 0, sizeof (struct prefix)); 1294 route->prefix.family = AF_INET6; 1295 route->prefix.prefixlen = op->prefix_length; 1296 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op); 1297 1298 route->type = OSPF6_DEST_TYPE_NETWORK; 1299 route->path.origin.type = lsa->header->type; 1300 route->path.origin.id = lsa->header->id; 1301 route->path.origin.adv_router = lsa->header->adv_router; 1302 route->path.prefix_options = op->prefix_options; 1303 route->path.area_id = oa->area_id; 1304 route->path.type = OSPF6_PATH_TYPE_INTRA; 1305 route->path.metric_type = 1; 1306 route->path.cost = ls_entry->path.cost + 1307 ntohs (op->prefix_metric); 1308 1309 if (direct_connect) 1310 { 1311 ifp = if_lookup_prefix(&route->prefix); 1312 if (ifp) 1313 route->nexthop[0].ifindex = ifp->ifindex; 1314 } 1315 else 1316 { 1317 for (i = 0; ospf6_nexthop_is_set (&ls_entry->nexthop[i]) && 1318 i < OSPF6_MULTI_PATH_LIMIT; i++) 1319 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]); 1320 } 1321 1322 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1323 { 1324 prefix2str (&route->prefix, buf, sizeof (buf)); 1325 zlog_debug (" add %s", buf); 1326 } 1327 1328 ospf6_route_add (route, oa->route_table); 1329 prefix_num--; 1330 } 1331 1332 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1333 zlog_debug ("Trailing garbage ignored"); 1334} 1335 1336void 1337ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa) 1338{ 1339 struct ospf6_area *oa; 1340 struct ospf6_intra_prefix_lsa *intra_prefix_lsa; 1341 struct prefix prefix; 1342 struct ospf6_route *route; 1343 int prefix_num; 1344 struct ospf6_prefix *op; 1345 char *start, *current, *end; 1346 char buf[64]; 1347 1348 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1349 zlog_debug ("%s disappearing", lsa->name); 1350 1351 oa = OSPF6_AREA (lsa->lsdb->data); 1352 1353 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) 1354 OSPF6_LSA_HEADER_END (lsa->header); 1355 1356 prefix_num = ntohs (intra_prefix_lsa->prefix_num); 1357 start = (caddr_t) intra_prefix_lsa + 1358 sizeof (struct ospf6_intra_prefix_lsa); 1359 end = OSPF6_LSA_END (lsa->header); 1360 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op)) 1361 { 1362 op = (struct ospf6_prefix *) current; 1363 if (prefix_num == 0) 1364 break; 1365 if (end < current + OSPF6_PREFIX_SIZE (op)) 1366 break; 1367 prefix_num--; 1368 1369 memset (&prefix, 0, sizeof (struct prefix)); 1370 prefix.family = AF_INET6; 1371 prefix.prefixlen = op->prefix_length; 1372 ospf6_prefix_in6_addr (&prefix.u.prefix6, op); 1373 1374 route = ospf6_route_lookup (&prefix, oa->route_table); 1375 if (route == NULL) 1376 continue; 1377 1378 for (ospf6_route_lock (route); 1379 route && ospf6_route_is_prefix (&prefix, route); 1380 route = ospf6_route_next (route)) 1381 { 1382 if (route->type != OSPF6_DEST_TYPE_NETWORK) 1383 continue; 1384 if (route->path.area_id != oa->area_id) 1385 continue; 1386 if (route->path.type != OSPF6_PATH_TYPE_INTRA) 1387 continue; 1388 if (route->path.origin.type != lsa->header->type || 1389 route->path.origin.id != lsa->header->id || 1390 route->path.origin.adv_router != lsa->header->adv_router) 1391 continue; 1392 1393 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1394 { 1395 prefix2str (&route->prefix, buf, sizeof (buf)); 1396 zlog_debug ("remove %s", buf); 1397 } 1398 ospf6_route_remove (route, oa->route_table); 1399 } 1400 if (route) 1401 ospf6_route_unlock (route); 1402 } 1403 1404 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1405 zlog_debug ("Trailing garbage ignored"); 1406} 1407 1408void 1409ospf6_intra_route_calculation (struct ospf6_area *oa) 1410{ 1411 struct ospf6_route *route; 1412 u_int16_t type; 1413 struct ospf6_lsa *lsa; 1414 void (*hook_add) (struct ospf6_route *) = NULL; 1415 void (*hook_remove) (struct ospf6_route *) = NULL; 1416 1417 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1418 zlog_debug ("Re-examin intra-routes for area %s", oa->name); 1419 1420 hook_add = oa->route_table->hook_add; 1421 hook_remove = oa->route_table->hook_remove; 1422 oa->route_table->hook_add = NULL; 1423 oa->route_table->hook_remove = NULL; 1424 1425 for (route = ospf6_route_head (oa->route_table); route; 1426 route = ospf6_route_next (route)) 1427 route->flag = OSPF6_ROUTE_REMOVE; 1428 1429 type = htons (OSPF6_LSTYPE_INTRA_PREFIX); 1430 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa; 1431 lsa = ospf6_lsdb_type_next (type, lsa)) 1432 ospf6_intra_prefix_lsa_add (lsa); 1433 1434 oa->route_table->hook_add = hook_add; 1435 oa->route_table->hook_remove = hook_remove; 1436 1437 for (route = ospf6_route_head (oa->route_table); route; 1438 route = ospf6_route_next (route)) 1439 { 1440 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) && 1441 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD)) 1442 { 1443 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE); 1444 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD); 1445 } 1446 1447 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE)) 1448 ospf6_route_remove (route, oa->route_table); 1449 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) || 1450 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE)) 1451 { 1452 if (hook_add) 1453 (*hook_add) (route); 1454 } 1455 1456 route->flag = 0; 1457 } 1458 1459 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX)) 1460 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name); 1461} 1462 1463static void 1464ospf6_brouter_debug_print (struct ospf6_route *brouter) 1465{ 1466 u_int32_t brouter_id; 1467 char brouter_name[16]; 1468 char area_name[16]; 1469 char destination[64]; 1470 char installed[16], changed[16]; 1471 struct timeval now, res; 1472 char id[16], adv_router[16]; 1473 char capa[16], options[16]; 1474 1475 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); 1476 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); 1477 inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name)); 1478 ospf6_linkstate_prefix2str (&brouter->prefix, destination, 1479 sizeof (destination)); 1480 1481 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); 1482 timersub (&now, &brouter->installed, &res); 1483 timerstring (&res, installed, sizeof (installed)); 1484 1485 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now); 1486 timersub (&now, &brouter->changed, &res); 1487 timerstring (&res, changed, sizeof (changed)); 1488 1489 inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id)); 1490 inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router, 1491 sizeof (adv_router)); 1492 1493 ospf6_options_printbuf (brouter->path.options, options, sizeof (options)); 1494 ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa)); 1495 1496 zlog_info ("Brouter: %s via area %s", brouter_name, area_name); 1497 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p", 1498 brouter->prev, brouter, brouter->next, brouter->rnode); 1499 zlog_info (" type: %d prefix: %s installed: %s changed: %s", 1500 brouter->type, destination, installed, changed); 1501 zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock, 1502 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"), 1503 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"), 1504 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"), 1505 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-")); 1506 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s", 1507 OSPF6_PATH_TYPE_NAME (brouter->path.type), 1508 ospf6_lstype_name (brouter->path.origin.type), 1509 id, adv_router); 1510 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d", 1511 options, capa, brouter->path.metric_type, 1512 brouter->path.cost, brouter->path.cost_e2); 1513} 1514 1515void 1516ospf6_intra_brouter_calculation (struct ospf6_area *oa) 1517{ 1518 struct ospf6_route *brouter, *copy; 1519 void (*hook_add) (struct ospf6_route *) = NULL; 1520 void (*hook_remove) (struct ospf6_route *) = NULL; 1521 u_int32_t brouter_id; 1522 char brouter_name[16]; 1523 1524 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) 1525 zlog_info ("border-router calculation for area %s", oa->name); 1526 1527 hook_add = oa->ospf6->brouter_table->hook_add; 1528 hook_remove = oa->ospf6->brouter_table->hook_remove; 1529 oa->ospf6->brouter_table->hook_add = NULL; 1530 oa->ospf6->brouter_table->hook_remove = NULL; 1531 1532 /* withdraw the previous router entries for the area */ 1533 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter; 1534 brouter = ospf6_route_next (brouter)) 1535 { 1536 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); 1537 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); 1538 if (brouter->path.area_id != oa->area_id) 1539 continue; 1540 brouter->flag = OSPF6_ROUTE_REMOVE; 1541 1542 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || 1543 IS_OSPF6_DEBUG_ROUTE (MEMORY)) 1544 { 1545 zlog_info ("%p: mark as removing: area %s brouter %s", 1546 brouter, oa->name, brouter_name); 1547 ospf6_brouter_debug_print (brouter); 1548 } 1549 } 1550 1551 for (brouter = ospf6_route_head (oa->spf_table); brouter; 1552 brouter = ospf6_route_next (brouter)) 1553 { 1554 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); 1555 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); 1556 1557 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE) 1558 continue; 1559 if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0)) 1560 continue; 1561 if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) && 1562 ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B)) 1563 continue; 1564 1565 if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) || 1566 ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R)) 1567 continue; 1568 1569 copy = ospf6_route_copy (brouter); 1570 copy->type = OSPF6_DEST_TYPE_ROUTER; 1571 copy->path.area_id = oa->area_id; 1572 ospf6_route_add (copy, oa->ospf6->brouter_table); 1573 1574 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || 1575 IS_OSPF6_DEBUG_ROUTE (MEMORY)) 1576 { 1577 zlog_info ("%p: transfer: area %s brouter %s", 1578 brouter, oa->name, brouter_name); 1579 ospf6_brouter_debug_print (brouter); 1580 } 1581 } 1582 1583 oa->ospf6->brouter_table->hook_add = hook_add; 1584 oa->ospf6->brouter_table->hook_remove = hook_remove; 1585 1586 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter; 1587 brouter = ospf6_route_next (brouter)) 1588 { 1589 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix); 1590 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name)); 1591 1592 if (brouter->path.area_id != oa->area_id) 1593 continue; 1594 1595 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED)) 1596 continue; 1597 1598 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) && 1599 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD)) 1600 { 1601 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE); 1602 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD); 1603 } 1604 1605 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE)) 1606 { 1607 if (IS_OSPF6_DEBUG_BROUTER || 1608 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || 1609 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) 1610 zlog_info ("brouter %s disappears via area %s", 1611 brouter_name, oa->name); 1612 ospf6_route_remove (brouter, oa->ospf6->brouter_table); 1613 } 1614 else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) || 1615 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE)) 1616 { 1617 if (IS_OSPF6_DEBUG_BROUTER || 1618 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || 1619 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) 1620 zlog_info ("brouter %s appears via area %s", 1621 brouter_name, oa->name); 1622 1623 /* newly added */ 1624 if (hook_add) 1625 (*hook_add) (brouter); 1626 } 1627 else 1628 { 1629 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) || 1630 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) 1631 zlog_info ("brouter %s still exists via area %s", 1632 brouter_name, oa->name); 1633 } 1634 1635 brouter->flag = 0; 1636 } 1637 1638 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) 1639 zlog_info ("border-router calculation for area %s: done", oa->name); 1640} 1641 1642struct ospf6_lsa_handler router_handler = 1643{ 1644 OSPF6_LSTYPE_ROUTER, 1645 "Router", 1646 "Rtr", 1647 ospf6_router_lsa_show, 1648 ospf6_router_lsa_get_nbr_id 1649}; 1650 1651struct ospf6_lsa_handler network_handler = 1652{ 1653 OSPF6_LSTYPE_NETWORK, 1654 "Network", 1655 "Net", 1656 ospf6_network_lsa_show, 1657 ospf6_network_lsa_get_ar_id 1658}; 1659 1660struct ospf6_lsa_handler link_handler = 1661{ 1662 OSPF6_LSTYPE_LINK, 1663 "Link", 1664 "Lnk", 1665 ospf6_link_lsa_show, 1666 ospf6_link_lsa_get_prefix_str 1667}; 1668 1669struct ospf6_lsa_handler intra_prefix_handler = 1670{ 1671 OSPF6_LSTYPE_INTRA_PREFIX, 1672 "Intra-Prefix", 1673 "INP", 1674 ospf6_intra_prefix_lsa_show, 1675 ospf6_intra_prefix_lsa_get_prefix_str 1676}; 1677 1678void 1679ospf6_intra_init (void) 1680{ 1681 ospf6_install_lsa_handler (&router_handler); 1682 ospf6_install_lsa_handler (&network_handler); 1683 ospf6_install_lsa_handler (&link_handler); 1684 ospf6_install_lsa_handler (&intra_prefix_handler); 1685} 1686 1687DEFUN (debug_ospf6_brouter, 1688 debug_ospf6_brouter_cmd, 1689 "debug ospf6 border-routers", 1690 DEBUG_STR 1691 OSPF6_STR 1692 "Debug border router\n" 1693 ) 1694{ 1695 OSPF6_DEBUG_BROUTER_ON (); 1696 return CMD_SUCCESS; 1697} 1698 1699DEFUN (no_debug_ospf6_brouter, 1700 no_debug_ospf6_brouter_cmd, 1701 "no debug ospf6 border-routers", 1702 NO_STR 1703 DEBUG_STR 1704 OSPF6_STR 1705 "Debug border router\n" 1706 ) 1707{ 1708 OSPF6_DEBUG_BROUTER_OFF (); 1709 return CMD_SUCCESS; 1710} 1711 1712DEFUN (debug_ospf6_brouter_router, 1713 debug_ospf6_brouter_router_cmd, 1714 "debug ospf6 border-routers router-id A.B.C.D", 1715 DEBUG_STR 1716 OSPF6_STR 1717 "Debug border router\n" 1718 "Debug specific border router\n" 1719 "Specify border-router's router-id\n" 1720 ) 1721{ 1722 u_int32_t router_id; 1723 inet_pton (AF_INET, argv[0], &router_id); 1724 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id); 1725 return CMD_SUCCESS; 1726} 1727 1728DEFUN (no_debug_ospf6_brouter_router, 1729 no_debug_ospf6_brouter_router_cmd, 1730 "no debug ospf6 border-routers router-id", 1731 NO_STR 1732 DEBUG_STR 1733 OSPF6_STR 1734 "Debug border router\n" 1735 "Debug specific border router\n" 1736 ) 1737{ 1738 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF (); 1739 return CMD_SUCCESS; 1740} 1741 1742DEFUN (debug_ospf6_brouter_area, 1743 debug_ospf6_brouter_area_cmd, 1744 "debug ospf6 border-routers area-id A.B.C.D", 1745 DEBUG_STR 1746 OSPF6_STR 1747 "Debug border router\n" 1748 "Debug border routers in specific Area\n" 1749 "Specify Area-ID\n" 1750 ) 1751{ 1752 u_int32_t area_id; 1753 inet_pton (AF_INET, argv[0], &area_id); 1754 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id); 1755 return CMD_SUCCESS; 1756} 1757 1758DEFUN (no_debug_ospf6_brouter_area, 1759 no_debug_ospf6_brouter_area_cmd, 1760 "no debug ospf6 border-routers area-id", 1761 NO_STR 1762 DEBUG_STR 1763 OSPF6_STR 1764 "Debug border router\n" 1765 "Debug border routers in specific Area\n" 1766 ) 1767{ 1768 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF (); 1769 return CMD_SUCCESS; 1770} 1771 1772int 1773config_write_ospf6_debug_brouter (struct vty *vty) 1774{ 1775 char buf[16]; 1776 if (IS_OSPF6_DEBUG_BROUTER) 1777 vty_out (vty, "debug ospf6 border-routers%s", VNL); 1778 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) 1779 { 1780 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id, 1781 buf, sizeof (buf)); 1782 vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL); 1783 } 1784 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) 1785 { 1786 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id, 1787 buf, sizeof (buf)); 1788 vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL); 1789 } 1790 return 0; 1791} 1792 1793void 1794install_element_ospf6_debug_brouter (void) 1795{ 1796 install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd); 1797 install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd); 1798 install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd); 1799 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd); 1800 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd); 1801 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd); 1802 install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd); 1803 install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd); 1804 install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd); 1805 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd); 1806 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd); 1807 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd); 1808} 1809 1810 1811