2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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.
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"
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"
49 #include "ospf6_spf.h"
51 unsigned char conf_debug_ospf6_brouter = 0;
52 u_int32_t conf_debug_ospf6_brouter_specific_router_id;
53 u_int32_t conf_debug_ospf6_brouter_specific_area_id;
55 /******************************/
56 /* RFC2740 3.4.3.1 Router-LSA */
57 /******************************/
60 ospf6_router_lsa_get_nbr_id (struct ospf6_lsa *lsa, char *buf, int buflen,
63 struct ospf6_router_lsa *router_lsa;
64 struct ospf6_router_lsdesc *lsdesc;
66 char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
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);
75 lsdesc = (struct ospf6_router_lsdesc *)
76 (start + pos*(sizeof (struct ospf6_router_lsdesc)));
77 if ((char *)lsdesc < end)
79 if (buf && (buflen > INET_ADDRSTRLEN*2))
81 inet_ntop (AF_INET, &lsdesc->neighbor_interface_id,
83 inet_ntop (AF_INET, &lsdesc->neighbor_router_id,
85 sprintf (buf, "%s/%s", buf2, buf1);
96 ospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
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;
103 router_lsa = (struct ospf6_router_lsa *)
104 ((char *) lsa->header + sizeof (struct ospf6_lsa_header));
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);
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))
115 lsdesc = (struct ospf6_router_lsdesc *) current;
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");
126 snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type);
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);
144 ospf6_router_is_stub_router (struct ospf6_lsa *lsa)
146 struct ospf6_router_lsa *rtr_lsa;
148 if (lsa != NULL && OSPF6_LSA_IS_TYPE (ROUTER, lsa))
150 rtr_lsa = (struct ospf6_router_lsa *)
151 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
153 if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_R))
155 return (OSPF6_IS_STUB_ROUTER);
157 else if (!OSPF6_OPT_ISSET (rtr_lsa->options, OSPF6_OPT_V6))
159 return (OSPF6_IS_STUB_ROUTER_V6);
163 return (OSPF6_NOT_STUB_ROUTER);
167 ospf6_router_lsa_originate (struct thread *thread)
169 struct ospf6_area *oa;
171 char buffer [OSPF6_MAX_LSASIZE];
172 struct ospf6_lsa_header *lsa_header;
173 struct ospf6_lsa *lsa;
175 u_int32_t link_state_id = 0;
176 struct listnode *node, *nnode;
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;
186 oa = (struct ospf6_area *) THREAD_ARG (thread);
187 oa->thread_router_lsa = NULL;
189 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
190 zlog_debug ("Originate Router-LSA for Area %s", oa->name);
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));
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);
204 if (ospf6_is_router_abr (ospf6))
205 SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B);
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);
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);
215 /* describe links for each interfaces */
216 lsdesc = (struct ospf6_router_lsdesc *)
217 ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa));
219 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
221 /* Interfaces in state Down or Loopback are not described */
222 if (oi->state == OSPF6_INTERFACE_DOWN ||
223 oi->state == OSPF6_INTERFACE_LOOPBACK)
226 /* Nor are interfaces without any full adjacencies described */
228 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
229 if (on->state == OSPF6_NEIGHBOR_FULL)
235 /* Multiple Router-LSA instance according to size limit setting */
236 if ( (oa->router_lsa_size_limit != 0)
237 && ((size_t)((char *)lsdesc - buffer)
238 + sizeof (struct ospf6_router_lsdesc)
239 > oa->router_lsa_size_limit))
241 if ((caddr_t) lsdesc == (caddr_t) router_lsa +
242 sizeof (struct ospf6_router_lsa))
244 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
245 zlog_debug ("Size limit setting for Router-LSA too short");
252 /* Point-to-Point interfaces */
253 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
255 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
257 if (on->state != OSPF6_NEIGHBOR_FULL)
260 lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT;
261 lsdesc->metric = htons (oi->cost);
262 lsdesc->interface_id = htonl (oi->interface->ifindex);
263 lsdesc->neighbor_interface_id = htonl (on->ifindex);
264 lsdesc->neighbor_router_id = on->router_id;
270 /* Broadcast and NBMA interfaces */
271 else if (oi->type == OSPF_IFTYPE_BROADCAST)
273 /* If this router is not DR,
274 and If this router not fully adjacent with DR,
275 this interface is not transit yet: ignore. */
276 if (oi->state != OSPF6_INTERFACE_DR)
278 drouter = ospf6_neighbor_lookup (oi->drouter, oi);
279 if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL)
283 lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK;
284 lsdesc->metric = htons (oi->cost);
285 lsdesc->interface_id = htonl (oi->interface->ifindex);
286 if (oi->state != OSPF6_INTERFACE_DR)
288 lsdesc->neighbor_interface_id = htonl (drouter->ifindex);
289 lsdesc->neighbor_router_id = drouter->router_id;
293 lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex);
294 lsdesc->neighbor_router_id = oi->area->ospf6->router_id;
301 assert (0); /* Unknown interface type */
306 /* Point-to-Multipoint interfaces */
310 /* Fill LSA Header */
312 lsa_header->type = htons (OSPF6_LSTYPE_ROUTER);
313 lsa_header->id = htonl (link_state_id);
314 lsa_header->adv_router = oa->ospf6->router_id;
316 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
317 lsa_header->adv_router, oa->lsdb);
318 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
321 ospf6_lsa_checksum (lsa_header);
324 lsa = ospf6_lsa_create (lsa_header);
327 ospf6_lsa_originate_area (lsa, oa);
331 /* Do premature-aging of rest, undesired Router-LSAs */
332 type = ntohs (OSPF6_LSTYPE_ROUTER);
333 router = oa->ospf6->router_id;
334 for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa;
335 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
337 if (ntohl (lsa->header->id) < link_state_id)
339 ospf6_lsa_purge (lsa);
345 /*******************************/
346 /* RFC2740 3.4.3.2 Network-LSA */
347 /*******************************/
350 ospf6_network_lsa_get_ar_id (struct ospf6_lsa *lsa, char *buf, int buflen,
353 char *start, *end, *current;
354 struct ospf6_network_lsa *network_lsa;
355 struct ospf6_network_lsdesc *lsdesc;
359 network_lsa = (struct ospf6_network_lsa *)
360 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
362 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
363 end = (char *) lsa->header + ntohs (lsa->header->length);
364 current = start + pos*(sizeof (struct ospf6_network_lsdesc));
366 if ((current + sizeof(struct ospf6_network_lsdesc)) <= end)
368 lsdesc = (struct ospf6_network_lsdesc *)current;
370 inet_ntop (AF_INET, &lsdesc->router_id, buf, buflen);
380 ospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
382 char *start, *end, *current;
383 struct ospf6_network_lsa *network_lsa;
384 struct ospf6_network_lsdesc *lsdesc;
385 char buf[128], options[32];
387 network_lsa = (struct ospf6_network_lsa *)
388 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
390 ospf6_options_printbuf (network_lsa->options, options, sizeof (options));
391 vty_out (vty, " Options: %s%s", options, VNL);
393 start = (char *) network_lsa + sizeof (struct ospf6_network_lsa);
394 end = (char *) lsa->header + ntohs (lsa->header->length);
395 for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end;
396 current += sizeof (struct ospf6_network_lsdesc))
398 lsdesc = (struct ospf6_network_lsdesc *) current;
399 inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf));
400 vty_out (vty, " Attached Router: %s%s", buf, VNL);
406 ospf6_network_lsa_originate (struct thread *thread)
408 struct ospf6_interface *oi;
410 char buffer [OSPF6_MAX_LSASIZE];
411 struct ospf6_lsa_header *lsa_header;
414 struct ospf6_lsa *old, *lsa;
415 struct ospf6_network_lsa *network_lsa;
416 struct ospf6_network_lsdesc *lsdesc;
417 struct ospf6_neighbor *on;
418 struct ospf6_link_lsa *link_lsa;
422 oi = (struct ospf6_interface *) THREAD_ARG (thread);
423 oi->thread_network_lsa = NULL;
425 /* The interface must be enabled until here. A Network-LSA of a
426 disabled interface (but was once enabled) should be flushed
427 by ospf6_lsa_refresh (), and does not come here. */
430 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK),
431 htonl (oi->interface->ifindex),
432 oi->area->ospf6->router_id, oi->area->lsdb);
434 /* Do not originate Network-LSA if not DR */
435 if (oi->state != OSPF6_INTERFACE_DR)
438 ospf6_lsa_purge (old);
442 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
443 zlog_debug ("Originate Network-LSA for Interface %s", oi->interface->name);
445 /* If none of neighbor is adjacent to us */
448 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
449 if (on->state == OSPF6_NEIGHBOR_FULL)
454 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK))
455 zlog_debug ("Interface stub, ignore");
457 ospf6_lsa_purge (old);
462 memset (buffer, 0, sizeof (buffer));
463 lsa_header = (struct ospf6_lsa_header *) buffer;
464 network_lsa = (struct ospf6_network_lsa *)
465 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
467 /* Collect the interface's Link-LSAs to describe
468 network's optional capabilities */
469 type = htons (OSPF6_LSTYPE_LINK);
470 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
471 lsa = ospf6_lsdb_type_next (type, lsa))
473 link_lsa = (struct ospf6_link_lsa *)
474 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
475 network_lsa->options[0] |= link_lsa->options[0];
476 network_lsa->options[1] |= link_lsa->options[1];
477 network_lsa->options[2] |= link_lsa->options[2];
480 lsdesc = (struct ospf6_network_lsdesc *)
481 ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa));
483 /* set Link Description to the router itself */
484 lsdesc->router_id = oi->area->ospf6->router_id;
487 /* Walk through the neighbors */
488 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
490 if (on->state != OSPF6_NEIGHBOR_FULL)
493 /* set this neighbor's Router-ID to LSA */
494 lsdesc->router_id = on->router_id;
498 /* Fill LSA Header */
500 lsa_header->type = htons (OSPF6_LSTYPE_NETWORK);
501 lsa_header->id = htonl (oi->interface->ifindex);
502 lsa_header->adv_router = oi->area->ospf6->router_id;
504 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
505 lsa_header->adv_router, oi->area->lsdb);
506 lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer);
509 ospf6_lsa_checksum (lsa_header);
512 lsa = ospf6_lsa_create (lsa_header);
515 ospf6_lsa_originate_area (lsa, oi->area);
521 /****************************/
522 /* RFC2740 3.4.3.6 Link-LSA */
523 /****************************/
526 ospf6_link_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf, int buflen,
529 char *start, *end, *current;
530 struct ospf6_link_lsa *link_lsa;
532 struct ospf6_prefix *prefix;
533 int cnt = 0, prefixnum;
537 link_lsa = (struct ospf6_link_lsa *)
538 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
541 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
545 prefixnum = ntohl (link_lsa->prefix_num);
549 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
550 end = (char *) lsa->header + ntohs (lsa->header->length);
555 prefix = (struct ospf6_prefix *) current;
556 if (prefix->prefix_length == 0 ||
557 current + OSPF6_PREFIX_SIZE (prefix) > end)
564 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
569 memset (&in6, 0, sizeof (in6));
570 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
571 OSPF6_PREFIX_SPACE (prefix->prefix_length));
572 inet_ntop (AF_INET6, &in6, buf, buflen);
575 } while (current <= end);
581 ospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
583 char *start, *end, *current;
584 struct ospf6_link_lsa *link_lsa;
586 char buf[128], options[32];
587 struct ospf6_prefix *prefix;
588 const char *p, *mc, *la, *nu;
591 link_lsa = (struct ospf6_link_lsa *)
592 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
594 ospf6_options_printbuf (link_lsa->options, options, sizeof (options));
595 inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf));
596 prefixnum = ntohl (link_lsa->prefix_num);
598 vty_out (vty, " Priority: %d Options: %s%s",
599 link_lsa->priority, options, VNL);
600 vty_out (vty, " LinkLocal Address: %s%s", buf, VNL);
601 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
603 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
604 end = (char *) lsa->header + ntohs (lsa->header->length);
605 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
607 prefix = (struct ospf6_prefix *) current;
608 if (prefix->prefix_length == 0 ||
609 current + OSPF6_PREFIX_SIZE (prefix) > end)
612 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
614 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
616 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
618 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
620 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
623 memset (&in6, 0, sizeof (in6));
624 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
625 OSPF6_PREFIX_SPACE (prefix->prefix_length));
626 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
627 vty_out (vty, " Prefix: %s/%d%s",
628 buf, prefix->prefix_length, VNL);
635 ospf6_link_lsa_originate (struct thread *thread)
637 struct ospf6_interface *oi;
639 char buffer[OSPF6_MAX_LSASIZE];
640 struct ospf6_lsa_header *lsa_header;
641 struct ospf6_lsa *old, *lsa;
643 struct ospf6_link_lsa *link_lsa;
644 struct ospf6_route *route;
645 struct ospf6_prefix *op;
647 oi = (struct ospf6_interface *) THREAD_ARG (thread);
648 oi->thread_link_lsa = NULL;
652 /* find previous LSA */
653 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK),
654 htonl (oi->interface->ifindex),
655 oi->area->ospf6->router_id, oi->lsdb);
657 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
660 ospf6_lsa_purge (old);
664 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
665 zlog_debug ("Originate Link-LSA for Interface %s", oi->interface->name);
667 /* can't make Link-LSA if linklocal address not set */
668 if (oi->linklocal_addr == NULL)
670 if (IS_OSPF6_DEBUG_ORIGINATE (LINK))
671 zlog_debug ("No Linklocal address on %s, defer originating",
672 oi->interface->name);
674 ospf6_lsa_purge (old);
679 memset (buffer, 0, sizeof (buffer));
680 lsa_header = (struct ospf6_lsa_header *) buffer;
681 link_lsa = (struct ospf6_link_lsa *)
682 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
685 link_lsa->priority = oi->priority;
686 memcpy (link_lsa->options, oi->area->options, 3);
687 memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr,
688 sizeof (struct in6_addr));
689 link_lsa->prefix_num = htonl (oi->route_connected->count);
691 op = (struct ospf6_prefix *)
692 ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa));
694 /* connected prefix to advertise */
695 for (route = ospf6_route_head (oi->route_connected); route;
696 route = ospf6_route_next (route))
698 op->prefix_length = route->prefix.prefixlen;
699 op->prefix_options = route->path.prefix_options;
700 op->prefix_metric = htons (0);
701 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
702 OSPF6_PREFIX_SPACE (op->prefix_length));
703 op = OSPF6_PREFIX_NEXT (op);
706 /* Fill LSA Header */
708 lsa_header->type = htons (OSPF6_LSTYPE_LINK);
709 lsa_header->id = htonl (oi->interface->ifindex);
710 lsa_header->adv_router = oi->area->ospf6->router_id;
712 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
713 lsa_header->adv_router, oi->lsdb);
714 lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer);
717 ospf6_lsa_checksum (lsa_header);
720 lsa = ospf6_lsa_create (lsa_header);
723 ospf6_lsa_originate_interface (lsa, oi);
729 /*****************************************/
730 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
731 /*****************************************/
733 ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
736 char *start, *end, *current;
737 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
739 int prefixnum, cnt = 0;
740 struct ospf6_prefix *prefix;
744 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
745 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
747 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
751 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
752 end = (char *) lsa->header + ntohs (lsa->header->length);
757 prefix = (struct ospf6_prefix *) current;
758 if (prefix->prefix_length == 0 ||
759 current + OSPF6_PREFIX_SIZE (prefix) > end)
766 current = start + pos*OSPF6_PREFIX_SIZE(prefix);
771 memset (&in6, 0, sizeof (in6));
772 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
773 OSPF6_PREFIX_SPACE (prefix->prefix_length));
774 inet_ntop (AF_INET6, &in6, buf, buflen);
775 sprintf(&buf[strlen(buf)], "/%d", prefix->prefix_length);
778 } while (current <= end);
784 ospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
786 char *start, *end, *current;
787 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
790 struct ospf6_prefix *prefix;
791 char id[16], adv_router[16];
792 const char *p, *mc, *la, *nu;
795 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
796 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
798 prefixnum = ntohs (intra_prefix_lsa->prefix_num);
800 vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL);
802 inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id));
803 inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router,
804 adv_router, sizeof (adv_router));
805 vty_out (vty, " Reference: %s Id: %s Adv: %s%s",
806 ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router,
809 start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa);
810 end = (char *) lsa->header + ntohs (lsa->header->length);
811 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix))
813 prefix = (struct ospf6_prefix *) current;
814 if (prefix->prefix_length == 0 ||
815 current + OSPF6_PREFIX_SIZE (prefix) > end)
818 p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ?
820 mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ?
822 la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ?
824 nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ?
826 vty_out (vty, " Prefix Options: %s|%s|%s|%s%s",
829 memset (&in6, 0, sizeof (in6));
830 memcpy (&in6, OSPF6_PREFIX_BODY (prefix),
831 OSPF6_PREFIX_SPACE (prefix->prefix_length));
832 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
833 vty_out (vty, " Prefix: %s/%d%s",
834 buf, prefix->prefix_length, VNL);
841 ospf6_intra_prefix_lsa_originate_stub (struct thread *thread)
843 struct ospf6_area *oa;
845 char buffer[OSPF6_MAX_LSASIZE];
846 struct ospf6_lsa_header *lsa_header;
847 struct ospf6_lsa *old, *lsa;
849 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
850 struct ospf6_interface *oi;
851 struct ospf6_neighbor *on;
852 struct ospf6_route *route;
853 struct ospf6_prefix *op;
854 struct listnode *i, *j;
856 unsigned short prefix_num = 0;
858 struct ospf6_route_table *route_advertise;
860 oa = (struct ospf6_area *) THREAD_ARG (thread);
861 oa->thread_intra_prefix_lsa = NULL;
863 /* find previous LSA */
864 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
865 htonl (0), oa->ospf6->router_id, oa->lsdb);
867 if (! IS_AREA_ENABLED (oa))
870 ospf6_lsa_purge (old);
874 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
875 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
879 memset (buffer, 0, sizeof (buffer));
880 lsa_header = (struct ospf6_lsa_header *) buffer;
881 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
882 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
884 /* Fill Intra-Area-Prefix-LSA */
885 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER);
886 intra_prefix_lsa->ref_id = htonl (0);
887 intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
889 route_advertise = ospf6_route_table_create (0, 0);
891 for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
893 if (oi->state == OSPF6_INTERFACE_DOWN)
895 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
896 zlog_debug (" Interface %s is down, ignore", oi->interface->name);
902 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
903 if (on->state == OSPF6_NEIGHBOR_FULL)
906 if (oi->state != OSPF6_INTERFACE_LOOPBACK &&
907 oi->state != OSPF6_INTERFACE_POINTTOPOINT &&
910 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
911 zlog_debug (" Interface %s is not stub, ignore",
912 oi->interface->name);
916 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
917 zlog_debug (" Interface %s:", oi->interface->name);
919 /* connected prefix to advertise */
920 for (route = ospf6_route_head (oi->route_connected); route;
921 route = ospf6_route_best_next (route))
923 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
925 prefix2str (&route->prefix, buf, sizeof (buf));
926 zlog_debug (" include %s", buf);
928 ospf6_route_add (ospf6_route_copy (route), route_advertise);
932 if (route_advertise->count == 0)
935 ospf6_lsa_purge (old);
936 ospf6_route_table_delete (route_advertise);
940 /* put prefixes to advertise */
942 op = (struct ospf6_prefix *)
943 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
944 for (route = ospf6_route_head (route_advertise); route;
945 route = ospf6_route_best_next (route))
947 op->prefix_length = route->prefix.prefixlen;
948 op->prefix_options = route->path.prefix_options;
949 op->prefix_metric = htons (route->path.cost);
950 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
951 OSPF6_PREFIX_SPACE (op->prefix_length));
952 op = OSPF6_PREFIX_NEXT (op);
956 ospf6_route_table_delete (route_advertise);
960 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
961 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
965 intra_prefix_lsa->prefix_num = htons (prefix_num);
967 /* Fill LSA Header */
969 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
970 lsa_header->id = htonl (0);
971 lsa_header->adv_router = oa->ospf6->router_id;
973 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
974 lsa_header->adv_router, oa->lsdb);
975 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
978 ospf6_lsa_checksum (lsa_header);
981 lsa = ospf6_lsa_create (lsa_header);
984 ospf6_lsa_originate_area (lsa, oa);
991 ospf6_intra_prefix_lsa_originate_transit (struct thread *thread)
993 struct ospf6_interface *oi;
995 char buffer[OSPF6_MAX_LSASIZE];
996 struct ospf6_lsa_header *lsa_header;
997 struct ospf6_lsa *old, *lsa;
999 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1000 struct ospf6_neighbor *on;
1001 struct ospf6_route *route;
1002 struct ospf6_prefix *op;
1005 unsigned short prefix_num = 0;
1006 struct ospf6_route_table *route_advertise;
1007 struct ospf6_link_lsa *link_lsa;
1008 char *start, *end, *current;
1012 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1013 oi->thread_intra_prefix_lsa = NULL;
1017 /* find previous LSA */
1018 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX),
1019 htonl (oi->interface->ifindex),
1020 oi->area->ospf6->router_id, oi->area->lsdb);
1022 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE))
1025 ospf6_lsa_purge (old);
1029 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1030 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1031 oi->interface->name);
1033 /* prepare buffer */
1034 memset (buffer, 0, sizeof (buffer));
1035 lsa_header = (struct ospf6_lsa_header *) buffer;
1036 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1037 ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
1039 /* Fill Intra-Area-Prefix-LSA */
1040 intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK);
1041 intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex);
1042 intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id;
1044 if (oi->state != OSPF6_INTERFACE_DR)
1046 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1047 zlog_debug (" Interface is not DR");
1049 ospf6_lsa_purge (old);
1054 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, i, on))
1055 if (on->state == OSPF6_NEIGHBOR_FULL)
1058 if (full_count == 0)
1060 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1061 zlog_debug (" Interface is stub");
1063 ospf6_lsa_purge (old);
1067 /* connected prefix to advertise */
1068 route_advertise = ospf6_route_table_create (0, 0);
1070 type = ntohs (OSPF6_LSTYPE_LINK);
1071 for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa;
1072 lsa = ospf6_lsdb_type_next (type, lsa))
1074 if (OSPF6_LSA_IS_MAXAGE (lsa))
1077 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1078 zlog_debug (" include prefix from %s", lsa->name);
1080 if (lsa->header->adv_router != oi->area->ospf6->router_id)
1082 on = ospf6_neighbor_lookup (lsa->header->adv_router, oi);
1083 if (on == NULL || on->state != OSPF6_NEIGHBOR_FULL)
1085 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1086 zlog_debug (" Neighbor not found or not Full, ignore");
1091 link_lsa = (struct ospf6_link_lsa *)
1092 ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header));
1094 prefix_num = (unsigned short) ntohl (link_lsa->prefix_num);
1095 start = (char *) link_lsa + sizeof (struct ospf6_link_lsa);
1096 end = (char *) lsa->header + ntohs (lsa->header->length);
1097 for (current = start; current < end && prefix_num;
1098 current += OSPF6_PREFIX_SIZE (op))
1100 op = (struct ospf6_prefix *) current;
1101 if (op->prefix_length == 0 ||
1102 current + OSPF6_PREFIX_SIZE (op) > end)
1105 route = ospf6_route_create ();
1107 route->type = OSPF6_DEST_TYPE_NETWORK;
1108 route->prefix.family = AF_INET6;
1109 route->prefix.prefixlen = op->prefix_length;
1110 memset (&route->prefix.u.prefix6, 0, sizeof (struct in6_addr));
1111 memcpy (&route->prefix.u.prefix6, OSPF6_PREFIX_BODY (op),
1112 OSPF6_PREFIX_SPACE (op->prefix_length));
1114 route->path.origin.type = lsa->header->type;
1115 route->path.origin.id = lsa->header->id;
1116 route->path.origin.adv_router = lsa->header->adv_router;
1117 route->path.options[0] = link_lsa->options[0];
1118 route->path.options[1] = link_lsa->options[1];
1119 route->path.options[2] = link_lsa->options[2];
1120 route->path.prefix_options = op->prefix_options;
1121 route->path.area_id = oi->area->area_id;
1122 route->path.type = OSPF6_PATH_TYPE_INTRA;
1124 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1126 prefix2str (&route->prefix, buf, sizeof (buf));
1127 zlog_debug (" include %s", buf);
1130 ospf6_route_add (route, route_advertise);
1133 if (current != end && IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1134 zlog_debug ("Trailing garbage in %s", lsa->name);
1137 op = (struct ospf6_prefix *)
1138 ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa));
1141 for (route = ospf6_route_head (route_advertise); route;
1142 route = ospf6_route_best_next (route))
1144 op->prefix_length = route->prefix.prefixlen;
1145 op->prefix_options = route->path.prefix_options;
1146 op->prefix_metric = htons (0);
1147 memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6,
1148 OSPF6_PREFIX_SPACE (op->prefix_length));
1149 op = OSPF6_PREFIX_NEXT (op);
1153 ospf6_route_table_delete (route_advertise);
1155 if (prefix_num == 0)
1157 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
1158 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
1162 intra_prefix_lsa->prefix_num = htons (prefix_num);
1164 /* Fill LSA Header */
1165 lsa_header->age = 0;
1166 lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1167 lsa_header->id = htonl (oi->interface->ifindex);
1168 lsa_header->adv_router = oi->area->ospf6->router_id;
1169 lsa_header->seqnum =
1170 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
1171 lsa_header->adv_router, oi->area->lsdb);
1172 lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header);
1175 ospf6_lsa_checksum (lsa_header);
1178 lsa = ospf6_lsa_create (lsa_header);
1181 ospf6_lsa_originate_area (lsa, oi->area);
1187 ospf6_intra_prefix_lsa_add (struct ospf6_lsa *lsa)
1189 struct ospf6_area *oa;
1190 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1191 struct prefix ls_prefix;
1192 struct ospf6_route *route, *ls_entry;
1194 struct ospf6_prefix *op;
1195 char *start, *current, *end;
1197 struct interface *ifp;
1198 int direct_connect = 0;
1200 if (OSPF6_LSA_IS_MAXAGE (lsa))
1203 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1204 zlog_debug ("%s found", lsa->name);
1206 oa = OSPF6_AREA (lsa->lsdb->data);
1208 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1209 OSPF6_LSA_HEADER_END (lsa->header);
1210 if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_ROUTER))
1211 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1212 htonl (0), &ls_prefix);
1213 else if (intra_prefix_lsa->ref_type == htons (OSPF6_LSTYPE_NETWORK))
1214 ospf6_linkstate_prefix (intra_prefix_lsa->ref_adv_router,
1215 intra_prefix_lsa->ref_id, &ls_prefix);
1218 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1219 zlog_debug ("Unknown reference LS-type: %#hx",
1220 ntohs (intra_prefix_lsa->ref_type));
1224 ls_entry = ospf6_route_lookup (&ls_prefix, oa->spf_table);
1225 if (ls_entry == NULL)
1227 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1229 ospf6_linkstate_prefix2str (&ls_prefix, buf, sizeof (buf));
1230 zlog_debug ("LS entry does not exist: %s", buf);
1235 if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id)
1237 /* the intra-prefix are directly connected */
1241 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1242 start = (caddr_t) intra_prefix_lsa +
1243 sizeof (struct ospf6_intra_prefix_lsa);
1244 end = OSPF6_LSA_END (lsa->header);
1245 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1247 op = (struct ospf6_prefix *) current;
1248 if (prefix_num == 0)
1250 if (end < current + OSPF6_PREFIX_SIZE (op))
1253 /* Appendix A.4.1.1 */
1254 if (CHECK_FLAG(op->prefix_options, OSPF6_PREFIX_OPTION_NU))
1256 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1258 ospf6_linkstate_prefix2str ((struct prefix *)OSPF6_PREFIX_BODY(op),
1260 zlog_debug ("%s: Skipping Prefix %s has NU option set",
1266 route = ospf6_route_create ();
1268 memset (&route->prefix, 0, sizeof (struct prefix));
1269 route->prefix.family = AF_INET6;
1270 route->prefix.prefixlen = op->prefix_length;
1271 ospf6_prefix_in6_addr (&route->prefix.u.prefix6, op);
1273 route->type = OSPF6_DEST_TYPE_NETWORK;
1274 route->path.origin.type = lsa->header->type;
1275 route->path.origin.id = lsa->header->id;
1276 route->path.origin.adv_router = lsa->header->adv_router;
1277 route->path.prefix_options = op->prefix_options;
1278 route->path.area_id = oa->area_id;
1279 route->path.type = OSPF6_PATH_TYPE_INTRA;
1280 route->path.metric_type = 1;
1281 route->path.cost = ls_entry->path.cost +
1282 ntohs (op->prefix_metric);
1286 ifp = if_lookup_prefix(&route->prefix);
1288 route->nexthop[0].ifindex = ifp->ifindex;
1292 for (i = 0; i < OSPF6_MULTI_PATH_LIMIT &&
1293 ospf6_nexthop_is_set (&ls_entry->nexthop[i]); i++)
1294 ospf6_nexthop_copy (&route->nexthop[i], &ls_entry->nexthop[i]);
1297 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1299 prefix2str (&route->prefix, buf, sizeof (buf));
1300 zlog_debug (" add %s", buf);
1303 ospf6_route_add (route, oa->route_table);
1307 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1308 zlog_debug ("Trailing garbage ignored");
1312 ospf6_intra_prefix_lsa_remove (struct ospf6_lsa *lsa)
1314 struct ospf6_area *oa;
1315 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
1316 struct prefix prefix;
1317 struct ospf6_route *route, *nroute;
1319 struct ospf6_prefix *op;
1320 char *start, *current, *end;
1323 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1324 zlog_debug ("%s disappearing", lsa->name);
1326 oa = OSPF6_AREA (lsa->lsdb->data);
1328 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
1329 OSPF6_LSA_HEADER_END (lsa->header);
1331 prefix_num = ntohs (intra_prefix_lsa->prefix_num);
1332 start = (caddr_t) intra_prefix_lsa +
1333 sizeof (struct ospf6_intra_prefix_lsa);
1334 end = OSPF6_LSA_END (lsa->header);
1335 for (current = start; current < end; current += OSPF6_PREFIX_SIZE (op))
1337 op = (struct ospf6_prefix *) current;
1338 if (prefix_num == 0)
1340 if (end < current + OSPF6_PREFIX_SIZE (op))
1344 memset (&prefix, 0, sizeof (struct prefix));
1345 prefix.family = AF_INET6;
1346 prefix.prefixlen = op->prefix_length;
1347 ospf6_prefix_in6_addr (&prefix.u.prefix6, op);
1349 route = ospf6_route_lookup (&prefix, oa->route_table);
1353 for (ospf6_route_lock (route);
1354 route && ospf6_route_is_prefix (&prefix, route);
1357 nroute = ospf6_route_next (route);
1358 if (route->type != OSPF6_DEST_TYPE_NETWORK)
1360 if (route->path.area_id != oa->area_id)
1362 if (route->path.type != OSPF6_PATH_TYPE_INTRA)
1364 if (route->path.origin.type != lsa->header->type ||
1365 route->path.origin.id != lsa->header->id ||
1366 route->path.origin.adv_router != lsa->header->adv_router)
1369 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1371 prefix2str (&route->prefix, buf, sizeof (buf));
1372 zlog_debug ("remove %s", buf);
1374 ospf6_route_remove (route, oa->route_table);
1377 ospf6_route_unlock (route);
1380 if (current != end && IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1381 zlog_debug ("Trailing garbage ignored");
1385 ospf6_intra_route_calculation (struct ospf6_area *oa)
1387 struct ospf6_route *route, *nroute;
1389 struct ospf6_lsa *lsa;
1390 void (*hook_add) (struct ospf6_route *) = NULL;
1391 void (*hook_remove) (struct ospf6_route *) = NULL;
1393 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1394 zlog_debug ("Re-examin intra-routes for area %s", oa->name);
1396 hook_add = oa->route_table->hook_add;
1397 hook_remove = oa->route_table->hook_remove;
1398 oa->route_table->hook_add = NULL;
1399 oa->route_table->hook_remove = NULL;
1401 for (route = ospf6_route_head (oa->route_table); route;
1402 route = ospf6_route_next (route))
1403 route->flag = OSPF6_ROUTE_REMOVE;
1405 type = htons (OSPF6_LSTYPE_INTRA_PREFIX);
1406 for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
1407 lsa = ospf6_lsdb_type_next (type, lsa))
1408 ospf6_intra_prefix_lsa_add (lsa);
1410 oa->route_table->hook_add = hook_add;
1411 oa->route_table->hook_remove = hook_remove;
1413 for (route = ospf6_route_head (oa->route_table); route;
1416 nroute = ospf6_route_next (route);
1417 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE) &&
1418 CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD))
1420 UNSET_FLAG (route->flag, OSPF6_ROUTE_REMOVE);
1421 UNSET_FLAG (route->flag, OSPF6_ROUTE_ADD);
1424 if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))
1425 ospf6_route_remove (route, oa->route_table);
1426 else if (CHECK_FLAG (route->flag, OSPF6_ROUTE_ADD) ||
1427 CHECK_FLAG (route->flag, OSPF6_ROUTE_CHANGE))
1430 (*hook_add) (route);
1436 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX))
1437 zlog_debug ("Re-examin intra-routes for area %s: Done", oa->name);
1441 ospf6_brouter_debug_print (struct ospf6_route *brouter)
1443 u_int32_t brouter_id;
1444 char brouter_name[16];
1446 char destination[64];
1447 char installed[16], changed[16];
1448 struct timeval now, res;
1449 char id[16], adv_router[16];
1450 char capa[16], options[16];
1452 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1453 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1454 inet_ntop (AF_INET, &brouter->path.area_id, area_name, sizeof (area_name));
1455 ospf6_linkstate_prefix2str (&brouter->prefix, destination,
1456 sizeof (destination));
1458 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1459 timersub (&now, &brouter->installed, &res);
1460 timerstring (&res, installed, sizeof (installed));
1462 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1463 timersub (&now, &brouter->changed, &res);
1464 timerstring (&res, changed, sizeof (changed));
1466 inet_ntop (AF_INET, &brouter->path.origin.id, id, sizeof (id));
1467 inet_ntop (AF_INET, &brouter->path.origin.adv_router, adv_router,
1468 sizeof (adv_router));
1470 ospf6_options_printbuf (brouter->path.options, options, sizeof (options));
1471 ospf6_capability_printbuf (brouter->path.router_bits, capa, sizeof (capa));
1473 zlog_info ("Brouter: %s via area %s", brouter_name, area_name);
1474 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1475 (void *)brouter->prev, (void *)brouter, (void *)brouter->next,
1476 (void *)brouter->rnode);
1477 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1478 brouter->type, destination, installed, changed);
1479 zlog_info (" lock: %d flags: %s%s%s%s", brouter->lock,
1480 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_BEST) ? "B" : "-"),
1481 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ? "A" : "-"),
1482 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) ? "R" : "-"),
1483 (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE) ? "C" : "-"));
1484 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1485 OSPF6_PATH_TYPE_NAME (brouter->path.type),
1486 ospf6_lstype_name (brouter->path.origin.type),
1488 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1489 options, capa, brouter->path.metric_type,
1490 brouter->path.cost, brouter->path.cost_e2);
1494 ospf6_intra_brouter_calculation (struct ospf6_area *oa)
1496 struct ospf6_route *brouter, *nbrouter, *copy;
1497 void (*hook_add) (struct ospf6_route *) = NULL;
1498 void (*hook_remove) (struct ospf6_route *) = NULL;
1499 u_int32_t brouter_id;
1500 char brouter_name[16];
1502 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1503 zlog_info ("border-router calculation for area %s", oa->name);
1505 hook_add = oa->ospf6->brouter_table->hook_add;
1506 hook_remove = oa->ospf6->brouter_table->hook_remove;
1507 oa->ospf6->brouter_table->hook_add = NULL;
1508 oa->ospf6->brouter_table->hook_remove = NULL;
1510 /* withdraw the previous router entries for the area */
1511 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1512 brouter = ospf6_route_next (brouter))
1514 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1515 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1516 if (brouter->path.area_id != oa->area_id)
1518 brouter->flag = OSPF6_ROUTE_REMOVE;
1520 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1521 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1523 zlog_info ("%p: mark as removing: area %s brouter %s",
1524 (void *)brouter, oa->name, brouter_name);
1525 ospf6_brouter_debug_print (brouter);
1529 for (brouter = ospf6_route_head (oa->spf_table); brouter;
1530 brouter = ospf6_route_next (brouter))
1532 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1533 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1535 if (brouter->type != OSPF6_DEST_TYPE_LINKSTATE)
1537 if (ospf6_linkstate_prefix_id (&brouter->prefix) != htonl (0))
1539 if (! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_E) &&
1540 ! CHECK_FLAG (brouter->path.router_bits, OSPF6_ROUTER_BIT_B))
1543 if (! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_V6) ||
1544 ! OSPF6_OPT_ISSET (brouter->path.options, OSPF6_OPT_R))
1547 copy = ospf6_route_copy (brouter);
1548 copy->type = OSPF6_DEST_TYPE_ROUTER;
1549 copy->path.area_id = oa->area_id;
1550 ospf6_route_add (copy, oa->ospf6->brouter_table);
1552 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1553 IS_OSPF6_DEBUG_ROUTE (MEMORY))
1555 zlog_info ("%p: transfer: area %s brouter %s",
1556 (void *)brouter, oa->name, brouter_name);
1557 ospf6_brouter_debug_print (brouter);
1561 oa->ospf6->brouter_table->hook_add = hook_add;
1562 oa->ospf6->brouter_table->hook_remove = hook_remove;
1564 for (brouter = ospf6_route_head (oa->ospf6->brouter_table); brouter;
1567 nbrouter = ospf6_route_next (brouter);
1568 brouter_id = ADV_ROUTER_IN_PREFIX (&brouter->prefix);
1569 inet_ntop (AF_INET, &brouter_id, brouter_name, sizeof (brouter_name));
1571 if (brouter->path.area_id != oa->area_id)
1574 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_WAS_REMOVED))
1577 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE) &&
1578 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD))
1580 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE);
1581 UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD);
1584 if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_REMOVE))
1586 if (IS_OSPF6_DEBUG_BROUTER ||
1587 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1588 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1589 zlog_info ("brouter %s disappears via area %s",
1590 brouter_name, oa->name);
1591 ospf6_route_remove (brouter, oa->ospf6->brouter_table);
1593 else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) ||
1594 CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE))
1596 if (IS_OSPF6_DEBUG_BROUTER ||
1597 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id) ||
1598 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1599 zlog_info ("brouter %s appears via area %s",
1600 brouter_name, oa->name);
1604 (*hook_add) (brouter);
1608 if (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 still exists via area %s",
1611 brouter_name, oa->name);
1617 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id))
1618 zlog_info ("border-router calculation for area %s: done", oa->name);
1621 struct ospf6_lsa_handler router_handler =
1623 OSPF6_LSTYPE_ROUTER,
1626 ospf6_router_lsa_show,
1627 ospf6_router_lsa_get_nbr_id
1630 struct ospf6_lsa_handler network_handler =
1632 OSPF6_LSTYPE_NETWORK,
1635 ospf6_network_lsa_show,
1636 ospf6_network_lsa_get_ar_id
1639 struct ospf6_lsa_handler link_handler =
1644 ospf6_link_lsa_show,
1645 ospf6_link_lsa_get_prefix_str
1648 struct ospf6_lsa_handler intra_prefix_handler =
1650 OSPF6_LSTYPE_INTRA_PREFIX,
1653 ospf6_intra_prefix_lsa_show,
1654 ospf6_intra_prefix_lsa_get_prefix_str
1658 ospf6_intra_init (void)
1660 ospf6_install_lsa_handler (&router_handler);
1661 ospf6_install_lsa_handler (&network_handler);
1662 ospf6_install_lsa_handler (&link_handler);
1663 ospf6_install_lsa_handler (&intra_prefix_handler);
1666 DEFUN (debug_ospf6_brouter,
1667 debug_ospf6_brouter_cmd,
1668 "debug ospf6 border-routers",
1671 "Debug border router\n"
1674 OSPF6_DEBUG_BROUTER_ON ();
1678 DEFUN (no_debug_ospf6_brouter,
1679 no_debug_ospf6_brouter_cmd,
1680 "no debug ospf6 border-routers",
1684 "Debug border router\n"
1687 OSPF6_DEBUG_BROUTER_OFF ();
1691 DEFUN (debug_ospf6_brouter_router,
1692 debug_ospf6_brouter_router_cmd,
1693 "debug ospf6 border-routers router-id A.B.C.D",
1696 "Debug border router\n"
1697 "Debug specific border router\n"
1698 "Specify border-router's router-id\n"
1701 u_int32_t router_id;
1702 inet_pton (AF_INET, argv[0], &router_id);
1703 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id);
1707 DEFUN (no_debug_ospf6_brouter_router,
1708 no_debug_ospf6_brouter_router_cmd,
1709 "no debug ospf6 border-routers router-id",
1713 "Debug border router\n"
1714 "Debug specific border router\n"
1717 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1721 DEFUN (debug_ospf6_brouter_area,
1722 debug_ospf6_brouter_area_cmd,
1723 "debug ospf6 border-routers area-id A.B.C.D",
1726 "Debug border router\n"
1727 "Debug border routers in specific Area\n"
1732 inet_pton (AF_INET, argv[0], &area_id);
1733 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id);
1737 DEFUN (no_debug_ospf6_brouter_area,
1738 no_debug_ospf6_brouter_area_cmd,
1739 "no debug ospf6 border-routers area-id",
1743 "Debug border router\n"
1744 "Debug border routers in specific Area\n"
1747 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1752 config_write_ospf6_debug_brouter (struct vty *vty)
1755 if (IS_OSPF6_DEBUG_BROUTER)
1756 vty_out (vty, "debug ospf6 border-routers%s", VNL);
1757 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER)
1759 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_router_id,
1761 vty_out (vty, "debug ospf6 border-routers router-id %s%s", buf, VNL);
1763 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA)
1765 inet_ntop (AF_INET, &conf_debug_ospf6_brouter_specific_area_id,
1767 vty_out (vty, "debug ospf6 border-routers area-id %s%s", buf, VNL);
1773 install_element_ospf6_debug_brouter (void)
1775 install_element (ENABLE_NODE, &debug_ospf6_brouter_cmd);
1776 install_element (ENABLE_NODE, &debug_ospf6_brouter_router_cmd);
1777 install_element (ENABLE_NODE, &debug_ospf6_brouter_area_cmd);
1778 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_cmd);
1779 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_router_cmd);
1780 install_element (ENABLE_NODE, &no_debug_ospf6_brouter_area_cmd);
1781 install_element (CONFIG_NODE, &debug_ospf6_brouter_cmd);
1782 install_element (CONFIG_NODE, &debug_ospf6_brouter_router_cmd);
1783 install_element (CONFIG_NODE, &debug_ospf6_brouter_area_cmd);
1784 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_cmd);
1785 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_router_cmd);
1786 install_element (CONFIG_NODE, &no_debug_ospf6_brouter_area_cmd);