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"
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_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
62 char *start
, *end
, *current
;
63 char buf
[32], name
[32], bits
[16], options
[32];
64 struct ospf6_router_lsa
*router_lsa
;
65 struct ospf6_router_lsdesc
*lsdesc
;
67 router_lsa
= (struct ospf6_router_lsa
*)
68 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
70 ospf6_capability_printbuf (router_lsa
->bits
, bits
, sizeof (bits
));
71 ospf6_options_printbuf (router_lsa
->options
, options
, sizeof (options
));
72 vty_out (vty
, " Bits: %s Options: %s%s", bits
, options
, VNL
);
74 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
75 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
76 for (current
= start
; current
+ sizeof (struct ospf6_router_lsdesc
) <= end
;
77 current
+= sizeof (struct ospf6_router_lsdesc
))
79 lsdesc
= (struct ospf6_router_lsdesc
*) current
;
81 if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_POINTTOPOINT
)
82 snprintf (name
, sizeof (name
), "Point-To-Point");
83 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
)
84 snprintf (name
, sizeof (name
), "Transit-Network");
85 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_STUB_NETWORK
)
86 snprintf (name
, sizeof (name
), "Stub-Network");
87 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_VIRTUAL_LINK
)
88 snprintf (name
, sizeof (name
), "Virtual-Link");
90 snprintf (name
, sizeof (name
), "Unknown (%#x)", lsdesc
->type
);
92 vty_out (vty
, " Type: %s Metric: %d%s",
93 name
, ntohs (lsdesc
->metric
), VNL
);
94 vty_out (vty
, " Interface ID: %s%s",
95 inet_ntop (AF_INET
, &lsdesc
->interface_id
,
96 buf
, sizeof (buf
)), VNL
);
97 vty_out (vty
, " Neighbor Interface ID: %s%s",
98 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
99 buf
, sizeof (buf
)), VNL
);
100 vty_out (vty
, " Neighbor Router ID: %s%s",
101 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
102 buf
, sizeof (buf
)), VNL
);
108 ospf6_router_lsa_originate (struct thread
*thread
)
110 struct ospf6_area
*oa
;
112 char buffer
[OSPF6_MAX_LSASIZE
];
113 struct ospf6_lsa_header
*lsa_header
;
114 struct ospf6_lsa
*lsa
;
116 u_int32_t link_state_id
= 0;
117 struct listnode
*node
, *nnode
;
119 struct ospf6_interface
*oi
;
120 struct ospf6_neighbor
*on
, *drouter
= NULL
;
121 struct ospf6_router_lsa
*router_lsa
;
122 struct ospf6_router_lsdesc
*lsdesc
;
127 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
128 oa
->thread_router_lsa
= NULL
;
130 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
131 zlog_debug ("Originate Router-LSA for Area %s", oa
->name
);
133 memset (buffer
, 0, sizeof (buffer
));
134 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
135 router_lsa
= (struct ospf6_router_lsa
*)
136 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
138 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_V6
);
139 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_E
);
140 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_MC
);
141 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_N
);
142 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_R
);
143 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_DC
);
145 if (ospf6_is_router_abr (ospf6
))
146 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
148 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
149 if (ospf6_asbr_is_asbr (ospf6
))
150 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
152 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
153 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_V
);
154 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_W
);
156 /* describe links for each interfaces */
157 lsdesc
= (struct ospf6_router_lsdesc
*)
158 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
160 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
162 /* Interfaces in state Down or Loopback are not described */
163 if (oi
->state
== OSPF6_INTERFACE_DOWN
||
164 oi
->state
== OSPF6_INTERFACE_LOOPBACK
)
167 /* Nor are interfaces without any full adjacencies described */
169 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
170 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
176 /* Multiple Router-LSA instance according to size limit setting */
177 if ( (oa
->router_lsa_size_limit
!= 0)
178 && ((caddr_t
) lsdesc
+ sizeof (struct ospf6_router_lsdesc
) -
179 /* XXX warning: comparison between signed and unsigned */
180 (caddr_t
) buffer
> oa
->router_lsa_size_limit
))
182 if ((caddr_t
) lsdesc
== (caddr_t
) router_lsa
+
183 sizeof (struct ospf6_router_lsa
))
185 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
186 zlog_debug ("Size limit setting for Router-LSA too short");
190 /* Fill LSA Header */
192 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
193 lsa_header
->id
= htonl (link_state_id
);
194 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
196 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
197 lsa_header
->adv_router
, oa
->lsdb
);
198 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
201 ospf6_lsa_checksum (lsa_header
);
204 lsa
= ospf6_lsa_create (lsa_header
);
207 ospf6_lsa_originate_area (lsa
, oa
);
209 /* Reset setting for consecutive origination */
210 memset ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
),
211 0, (caddr_t
) lsdesc
- (caddr_t
) router_lsa
);
212 lsdesc
= (struct ospf6_router_lsdesc
*)
213 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
217 /* Point-to-Point interfaces */
218 if (if_is_pointopoint (oi
->interface
))
220 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
222 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
225 lsdesc
->type
= OSPF6_ROUTER_LSDESC_POINTTOPOINT
;
226 lsdesc
->metric
= htons (oi
->cost
);
227 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
228 lsdesc
->neighbor_interface_id
= htonl (on
->ifindex
);
229 lsdesc
->neighbor_router_id
= on
->router_id
;
235 /* Broadcast and NBMA interfaces */
236 if (if_is_broadcast (oi
->interface
))
238 /* If this router is not DR,
239 and If this router not fully adjacent with DR,
240 this interface is not transit yet: ignore. */
241 if (oi
->state
!= OSPF6_INTERFACE_DR
)
243 drouter
= ospf6_neighbor_lookup (oi
->drouter
, oi
);
244 if (drouter
== NULL
|| drouter
->state
!= OSPF6_NEIGHBOR_FULL
)
248 lsdesc
->type
= OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
;
249 lsdesc
->metric
= htons (oi
->cost
);
250 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
251 if (oi
->state
!= OSPF6_INTERFACE_DR
)
253 lsdesc
->neighbor_interface_id
= htonl (drouter
->ifindex
);
254 lsdesc
->neighbor_router_id
= drouter
->router_id
;
258 lsdesc
->neighbor_interface_id
= htonl (oi
->interface
->ifindex
);
259 lsdesc
->neighbor_router_id
= oi
->area
->ospf6
->router_id
;
267 /* Point-to-Multipoint interfaces */
271 if ((caddr_t
) lsdesc
!= (caddr_t
) router_lsa
+
272 sizeof (struct ospf6_router_lsa
))
274 /* Fill LSA Header */
276 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
277 lsa_header
->id
= htonl (link_state_id
);
278 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
280 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
281 lsa_header
->adv_router
, oa
->lsdb
);
282 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
285 ospf6_lsa_checksum (lsa_header
);
288 lsa
= ospf6_lsa_create (lsa_header
);
291 ospf6_lsa_originate_area (lsa
, oa
);
297 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
298 zlog_debug ("Nothing to describe in Router-LSA, suppress");
301 /* Do premature-aging of rest, undesired Router-LSAs */
302 type
= ntohs (OSPF6_LSTYPE_ROUTER
);
303 router
= oa
->ospf6
->router_id
;
304 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, oa
->lsdb
); lsa
;
305 lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
307 if (ntohl (lsa
->header
->id
) < link_state_id
)
309 ospf6_lsa_purge (lsa
);
315 /*******************************/
316 /* RFC2740 3.4.3.2 Network-LSA */
317 /*******************************/
320 ospf6_network_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
322 char *start
, *end
, *current
;
323 struct ospf6_network_lsa
*network_lsa
;
324 struct ospf6_network_lsdesc
*lsdesc
;
325 char buf
[128], options
[32];
327 network_lsa
= (struct ospf6_network_lsa
*)
328 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
330 ospf6_options_printbuf (network_lsa
->options
, options
, sizeof (options
));
331 vty_out (vty
, " Options: %s%s", options
, VNL
);
333 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
334 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
335 for (current
= start
; current
+ sizeof (struct ospf6_network_lsdesc
) <= end
;
336 current
+= sizeof (struct ospf6_network_lsdesc
))
338 lsdesc
= (struct ospf6_network_lsdesc
*) current
;
339 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, sizeof (buf
));
340 vty_out (vty
, " Attached Router: %s%s", buf
, VNL
);
346 ospf6_network_lsa_originate (struct thread
*thread
)
348 struct ospf6_interface
*oi
;
350 char buffer
[OSPF6_MAX_LSASIZE
];
351 struct ospf6_lsa_header
*lsa_header
;
354 struct ospf6_lsa
*old
, *lsa
;
355 struct ospf6_network_lsa
*network_lsa
;
356 struct ospf6_network_lsdesc
*lsdesc
;
357 struct ospf6_neighbor
*on
;
358 struct ospf6_link_lsa
*link_lsa
;
362 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
363 oi
->thread_network_lsa
= NULL
;
365 /* The interface must be enabled until here. A Network-LSA of a
366 disabled interface (but was once enabled) should be flushed
367 by ospf6_lsa_refresh (), and does not come here. */
370 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK
),
371 htonl (oi
->interface
->ifindex
),
372 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
374 /* Do not originate Network-LSA if not DR */
375 if (oi
->state
!= OSPF6_INTERFACE_DR
)
378 ospf6_lsa_purge (old
);
382 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
383 zlog_debug ("Originate Network-LSA for Interface %s", oi
->interface
->name
);
385 /* If none of neighbor is adjacent to us */
388 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
389 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
394 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
395 zlog_debug ("Interface stub, ignore");
397 ospf6_lsa_purge (old
);
402 memset (buffer
, 0, sizeof (buffer
));
403 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
404 network_lsa
= (struct ospf6_network_lsa
*)
405 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
407 /* Collect the interface's Link-LSAs to describe
408 network's optional capabilities */
409 type
= htons (OSPF6_LSTYPE_LINK
);
410 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
411 lsa
= ospf6_lsdb_type_next (type
, lsa
))
413 link_lsa
= (struct ospf6_link_lsa
*)
414 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
415 network_lsa
->options
[0] |= link_lsa
->options
[0];
416 network_lsa
->options
[1] |= link_lsa
->options
[1];
417 network_lsa
->options
[2] |= link_lsa
->options
[2];
420 lsdesc
= (struct ospf6_network_lsdesc
*)
421 ((caddr_t
) network_lsa
+ sizeof (struct ospf6_network_lsa
));
423 /* set Link Description to the router itself */
424 lsdesc
->router_id
= oi
->area
->ospf6
->router_id
;
427 /* Walk through the neighbors */
428 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
430 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
433 /* set this neighbor's Router-ID to LSA */
434 lsdesc
->router_id
= on
->router_id
;
438 /* Fill LSA Header */
440 lsa_header
->type
= htons (OSPF6_LSTYPE_NETWORK
);
441 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
442 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
444 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
445 lsa_header
->adv_router
, oi
->area
->lsdb
);
446 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
449 ospf6_lsa_checksum (lsa_header
);
452 lsa
= ospf6_lsa_create (lsa_header
);
455 ospf6_lsa_originate_area (lsa
, oi
->area
);
461 /****************************/
462 /* RFC2740 3.4.3.6 Link-LSA */
463 /****************************/
466 ospf6_link_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
468 char *start
, *end
, *current
;
469 struct ospf6_link_lsa
*link_lsa
;
471 char buf
[128], options
[32];
472 struct ospf6_prefix
*prefix
;
473 const char *p
, *mc
, *la
, *nu
;
476 link_lsa
= (struct ospf6_link_lsa
*)
477 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
479 ospf6_options_printbuf (link_lsa
->options
, options
, sizeof (options
));
480 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, sizeof (buf
));
481 prefixnum
= ntohl (link_lsa
->prefix_num
);
483 vty_out (vty
, " Priority: %d Options: %s%s",
484 link_lsa
->priority
, options
, VNL
);
485 vty_out (vty
, " LinkLocal Address: %s%s", buf
, VNL
);
486 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
488 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
489 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
490 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
492 prefix
= (struct ospf6_prefix
*) current
;
493 if (prefix
->prefix_length
== 0 ||
494 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
497 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
499 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
501 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
503 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
505 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
508 memset (&in6
, 0, sizeof (in6
));
509 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
510 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
511 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
512 vty_out (vty
, " Prefix: %s/%d%s",
513 buf
, prefix
->prefix_length
, VNL
);
520 ospf6_link_lsa_originate (struct thread
*thread
)
522 struct ospf6_interface
*oi
;
524 char buffer
[OSPF6_MAX_LSASIZE
];
525 struct ospf6_lsa_header
*lsa_header
;
526 struct ospf6_lsa
*old
, *lsa
;
528 struct ospf6_link_lsa
*link_lsa
;
529 struct ospf6_route
*route
;
530 struct ospf6_prefix
*op
;
532 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
533 oi
->thread_link_lsa
= NULL
;
537 /* find previous LSA */
538 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK
),
539 htonl (oi
->interface
->ifindex
),
540 oi
->area
->ospf6
->router_id
, oi
->lsdb
);
542 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
545 ospf6_lsa_purge (old
);
549 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
550 zlog_debug ("Originate Link-LSA for Interface %s", oi
->interface
->name
);
552 /* can't make Link-LSA if linklocal address not set */
553 if (oi
->linklocal_addr
== NULL
)
555 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
556 zlog_debug ("No Linklocal address on %s, defer originating",
557 oi
->interface
->name
);
559 ospf6_lsa_purge (old
);
564 memset (buffer
, 0, sizeof (buffer
));
565 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
566 link_lsa
= (struct ospf6_link_lsa
*)
567 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
570 link_lsa
->priority
= oi
->priority
;
571 memcpy (link_lsa
->options
, oi
->area
->options
, 3);
572 memcpy (&link_lsa
->linklocal_addr
, oi
->linklocal_addr
,
573 sizeof (struct in6_addr
));
574 link_lsa
->prefix_num
= htonl (oi
->route_connected
->count
);
576 op
= (struct ospf6_prefix
*)
577 ((caddr_t
) link_lsa
+ sizeof (struct ospf6_link_lsa
));
579 /* connected prefix to advertise */
580 for (route
= ospf6_route_head (oi
->route_connected
); route
;
581 route
= ospf6_route_next (route
))
583 op
->prefix_length
= route
->prefix
.prefixlen
;
584 op
->prefix_options
= route
->path
.prefix_options
;
585 op
->prefix_metric
= htons (0);
586 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
587 OSPF6_PREFIX_SPACE (op
->prefix_length
));
588 op
= OSPF6_PREFIX_NEXT (op
);
591 /* Fill LSA Header */
593 lsa_header
->type
= htons (OSPF6_LSTYPE_LINK
);
594 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
595 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
597 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
598 lsa_header
->adv_router
, oi
->lsdb
);
599 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) buffer
);
602 ospf6_lsa_checksum (lsa_header
);
605 lsa
= ospf6_lsa_create (lsa_header
);
608 ospf6_lsa_originate_interface (lsa
, oi
);
614 /*****************************************/
615 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
616 /*****************************************/
619 ospf6_intra_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
621 char *start
, *end
, *current
;
622 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
625 struct ospf6_prefix
*prefix
;
626 char id
[16], adv_router
[16];
627 const char *p
, *mc
, *la
, *nu
;
630 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
631 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
633 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
635 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
637 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_id
, id
, sizeof (id
));
638 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_adv_router
,
639 adv_router
, sizeof (adv_router
));
640 vty_out (vty
, " Reference: %s Id: %s Adv: %s%s",
641 ospf6_lstype_name (intra_prefix_lsa
->ref_type
), id
, adv_router
,
644 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
645 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
646 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
648 prefix
= (struct ospf6_prefix
*) current
;
649 if (prefix
->prefix_length
== 0 ||
650 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
653 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
655 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
657 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
659 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
661 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
664 memset (&in6
, 0, sizeof (in6
));
665 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
666 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
667 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
668 vty_out (vty
, " Prefix: %s/%d%s",
669 buf
, prefix
->prefix_length
, VNL
);
676 ospf6_intra_prefix_lsa_originate_stub (struct thread
*thread
)
678 struct ospf6_area
*oa
;
680 char buffer
[OSPF6_MAX_LSASIZE
];
681 struct ospf6_lsa_header
*lsa_header
;
682 struct ospf6_lsa
*old
, *lsa
;
684 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
685 struct ospf6_interface
*oi
;
686 struct ospf6_neighbor
*on
;
687 struct ospf6_route
*route
;
688 struct ospf6_prefix
*op
;
689 struct listnode
*i
, *j
;
691 unsigned short prefix_num
= 0;
693 struct ospf6_route_table
*route_advertise
;
695 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
696 oa
->thread_intra_prefix_lsa
= NULL
;
698 /* find previous LSA */
699 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
700 htonl (0), oa
->ospf6
->router_id
, oa
->lsdb
);
702 if (! IS_AREA_ENABLED (oa
))
705 ospf6_lsa_purge (old
);
709 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
710 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
714 memset (buffer
, 0, sizeof (buffer
));
715 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
716 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
717 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
719 /* Fill Intra-Area-Prefix-LSA */
720 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_ROUTER
);
721 intra_prefix_lsa
->ref_id
= htonl (0);
722 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
724 route_advertise
= ospf6_route_table_create (0, 0);
726 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, i
, oi
))
728 if (oi
->state
== OSPF6_INTERFACE_DOWN
)
730 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
731 zlog_debug (" Interface %s is down, ignore", oi
->interface
->name
);
737 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
738 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
741 if (oi
->state
!= OSPF6_INTERFACE_LOOPBACK
&&
742 oi
->state
!= OSPF6_INTERFACE_POINTTOPOINT
&&
745 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
746 zlog_debug (" Interface %s is not stub, ignore",
747 oi
->interface
->name
);
751 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
752 zlog_debug (" Interface %s:", oi
->interface
->name
);
754 /* connected prefix to advertise */
755 for (route
= ospf6_route_head (oi
->route_connected
); route
;
756 route
= ospf6_route_best_next (route
))
758 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
760 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
761 zlog_debug (" include %s", buf
);
763 ospf6_route_add (ospf6_route_copy (route
), route_advertise
);
767 if (route_advertise
->count
== 0)
770 ospf6_lsa_purge (old
);
771 ospf6_route_table_delete (route_advertise
);
775 /* put prefixes to advertise */
777 op
= (struct ospf6_prefix
*)
778 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
779 for (route
= ospf6_route_head (route_advertise
); route
;
780 route
= ospf6_route_best_next (route
))
782 op
->prefix_length
= route
->prefix
.prefixlen
;
783 op
->prefix_options
= route
->path
.prefix_options
;
784 op
->prefix_metric
= htons (route
->path
.cost
);
785 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
786 OSPF6_PREFIX_SPACE (op
->prefix_length
));
787 op
= OSPF6_PREFIX_NEXT (op
);
791 ospf6_route_table_delete (route_advertise
);
795 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
796 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
800 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
802 /* Fill LSA Header */
804 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
805 lsa_header
->id
= htonl (0);
806 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
808 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
809 lsa_header
->adv_router
, oa
->lsdb
);
810 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
813 ospf6_lsa_checksum (lsa_header
);
816 lsa
= ospf6_lsa_create (lsa_header
);
819 ospf6_lsa_originate_area (lsa
, oa
);
826 ospf6_intra_prefix_lsa_originate_transit (struct thread
*thread
)
828 struct ospf6_interface
*oi
;
830 char buffer
[OSPF6_MAX_LSASIZE
];
831 struct ospf6_lsa_header
*lsa_header
;
832 struct ospf6_lsa
*old
, *lsa
;
834 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
835 struct ospf6_neighbor
*on
;
836 struct ospf6_route
*route
;
837 struct ospf6_prefix
*op
;
840 unsigned short prefix_num
= 0;
841 struct ospf6_route_table
*route_advertise
;
842 struct ospf6_link_lsa
*link_lsa
;
843 char *start
, *end
, *current
;
847 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
848 oi
->thread_intra_prefix_lsa
= NULL
;
852 /* find previous LSA */
853 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
854 htonl (oi
->interface
->ifindex
),
855 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
857 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
860 ospf6_lsa_purge (old
);
864 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
865 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
866 oi
->interface
->name
);
869 memset (buffer
, 0, sizeof (buffer
));
870 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
871 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
872 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
874 /* Fill Intra-Area-Prefix-LSA */
875 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_NETWORK
);
876 intra_prefix_lsa
->ref_id
= htonl (oi
->interface
->ifindex
);
877 intra_prefix_lsa
->ref_adv_router
= oi
->area
->ospf6
->router_id
;
879 if (oi
->state
!= OSPF6_INTERFACE_DR
)
881 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
882 zlog_debug (" Interface is not DR");
884 ospf6_lsa_purge (old
);
889 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
890 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
895 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
896 zlog_debug (" Interface is stub");
898 ospf6_lsa_purge (old
);
902 /* connected prefix to advertise */
903 route_advertise
= ospf6_route_table_create (0, 0);
905 type
= ntohs (OSPF6_LSTYPE_LINK
);
906 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
907 lsa
= ospf6_lsdb_type_next (type
, lsa
))
909 if (OSPF6_LSA_IS_MAXAGE (lsa
))
912 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
913 zlog_debug (" include prefix from %s", lsa
->name
);
915 if (lsa
->header
->adv_router
!= oi
->area
->ospf6
->router_id
)
917 on
= ospf6_neighbor_lookup (lsa
->header
->adv_router
, oi
);
918 if (on
== NULL
|| on
->state
!= OSPF6_NEIGHBOR_FULL
)
920 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
921 zlog_debug (" Neighbor not found or not Full, ignore");
926 link_lsa
= (struct ospf6_link_lsa
*)
927 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
929 prefix_num
= (unsigned short) ntohl (link_lsa
->prefix_num
);
930 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
931 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
932 for (current
= start
; current
< end
&& prefix_num
;
933 current
+= OSPF6_PREFIX_SIZE (op
))
935 op
= (struct ospf6_prefix
*) current
;
936 if (op
->prefix_length
== 0 ||
937 current
+ OSPF6_PREFIX_SIZE (op
) > end
)
940 route
= ospf6_route_create ();
942 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
943 route
->prefix
.family
= AF_INET6
;
944 route
->prefix
.prefixlen
= op
->prefix_length
;
945 memset (&route
->prefix
.u
.prefix6
, 0, sizeof (struct in6_addr
));
946 memcpy (&route
->prefix
.u
.prefix6
, OSPF6_PREFIX_BODY (op
),
947 OSPF6_PREFIX_SPACE (op
->prefix_length
));
949 route
->path
.origin
.type
= lsa
->header
->type
;
950 route
->path
.origin
.id
= lsa
->header
->id
;
951 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
952 route
->path
.options
[0] = link_lsa
->options
[0];
953 route
->path
.options
[1] = link_lsa
->options
[1];
954 route
->path
.options
[2] = link_lsa
->options
[2];
955 route
->path
.prefix_options
= op
->prefix_options
;
956 route
->path
.area_id
= oi
->area
->area_id
;
957 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
959 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
961 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
962 zlog_debug (" include %s", buf
);
965 ospf6_route_add (route
, route_advertise
);
968 if (current
!= end
&& IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
969 zlog_debug ("Trailing garbage in %s", lsa
->name
);
972 op
= (struct ospf6_prefix
*)
973 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
976 for (route
= ospf6_route_head (route_advertise
); route
;
977 route
= ospf6_route_best_next (route
))
979 op
->prefix_length
= route
->prefix
.prefixlen
;
980 op
->prefix_options
= route
->path
.prefix_options
;
981 op
->prefix_metric
= htons (0);
982 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
983 OSPF6_PREFIX_SPACE (op
->prefix_length
));
984 op
= OSPF6_PREFIX_NEXT (op
);
988 ospf6_route_table_delete (route_advertise
);
992 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
993 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
997 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
999 /* Fill LSA Header */
1000 lsa_header
->age
= 0;
1001 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1002 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
1003 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
1004 lsa_header
->seqnum
=
1005 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1006 lsa_header
->adv_router
, oi
->area
->lsdb
);
1007 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1010 ospf6_lsa_checksum (lsa_header
);
1013 lsa
= ospf6_lsa_create (lsa_header
);
1016 ospf6_lsa_originate_area (lsa
, oi
->area
);
1022 ospf6_intra_prefix_lsa_add (struct ospf6_lsa
*lsa
)
1024 struct ospf6_area
*oa
;
1025 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1026 struct prefix ls_prefix
;
1027 struct ospf6_route
*route
, *ls_entry
;
1029 struct ospf6_prefix
*op
;
1030 char *start
, *current
, *end
;
1033 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1036 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1037 zlog_debug ("%s found", lsa
->name
);
1039 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1041 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1042 OSPF6_LSA_HEADER_END (lsa
->header
);
1043 if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_ROUTER
))
1044 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1045 htonl (0), &ls_prefix
);
1046 else if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_NETWORK
))
1047 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1048 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1051 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1052 zlog_debug ("Unknown reference LS-type: %#hx",
1053 ntohs (intra_prefix_lsa
->ref_type
));
1057 ls_entry
= ospf6_route_lookup (&ls_prefix
, oa
->spf_table
);
1058 if (ls_entry
== NULL
)
1060 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1062 ospf6_linkstate_prefix2str (&ls_prefix
, buf
, sizeof (buf
));
1063 zlog_debug ("LS entry does not exist: %s", buf
);
1068 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1069 start
= (caddr_t
) intra_prefix_lsa
+
1070 sizeof (struct ospf6_intra_prefix_lsa
);
1071 end
= OSPF6_LSA_END (lsa
->header
);
1072 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1074 op
= (struct ospf6_prefix
*) current
;
1075 if (prefix_num
== 0)
1077 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1080 route
= ospf6_route_create ();
1082 memset (&route
->prefix
, 0, sizeof (struct prefix
));
1083 route
->prefix
.family
= AF_INET6
;
1084 route
->prefix
.prefixlen
= op
->prefix_length
;
1085 ospf6_prefix_in6_addr (&route
->prefix
.u
.prefix6
, op
);
1087 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1088 route
->path
.origin
.type
= lsa
->header
->type
;
1089 route
->path
.origin
.id
= lsa
->header
->id
;
1090 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1091 route
->path
.prefix_options
= op
->prefix_options
;
1092 route
->path
.area_id
= oa
->area_id
;
1093 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1094 route
->path
.metric_type
= 1;
1095 route
->path
.cost
= ls_entry
->path
.cost
+
1096 ntohs (op
->prefix_metric
);
1098 for (i
= 0; ospf6_nexthop_is_set (&ls_entry
->nexthop
[i
]) &&
1099 i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
1100 ospf6_nexthop_copy (&route
->nexthop
[i
], &ls_entry
->nexthop
[i
]);
1102 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1104 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1105 zlog_debug (" add %s", buf
);
1108 ospf6_route_add (route
, oa
->route_table
);
1112 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1113 zlog_debug ("Trailing garbage ignored");
1117 ospf6_intra_prefix_lsa_remove (struct ospf6_lsa
*lsa
)
1119 struct ospf6_area
*oa
;
1120 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1121 struct prefix prefix
;
1122 struct ospf6_route
*route
;
1124 struct ospf6_prefix
*op
;
1125 char *start
, *current
, *end
;
1128 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1129 zlog_debug ("%s disappearing", lsa
->name
);
1131 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1133 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1134 OSPF6_LSA_HEADER_END (lsa
->header
);
1136 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1137 start
= (caddr_t
) intra_prefix_lsa
+
1138 sizeof (struct ospf6_intra_prefix_lsa
);
1139 end
= OSPF6_LSA_END (lsa
->header
);
1140 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1142 op
= (struct ospf6_prefix
*) current
;
1143 if (prefix_num
== 0)
1145 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1149 memset (&prefix
, 0, sizeof (struct prefix
));
1150 prefix
.family
= AF_INET6
;
1151 prefix
.prefixlen
= op
->prefix_length
;
1152 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, op
);
1154 route
= ospf6_route_lookup (&prefix
, oa
->route_table
);
1158 for (ospf6_route_lock (route
);
1159 route
&& ospf6_route_is_prefix (&prefix
, route
);
1160 route
= ospf6_route_next (route
))
1162 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
1164 if (route
->path
.area_id
!= oa
->area_id
)
1166 if (route
->path
.type
!= OSPF6_PATH_TYPE_INTRA
)
1168 if (route
->path
.origin
.type
!= lsa
->header
->type
||
1169 route
->path
.origin
.id
!= lsa
->header
->id
||
1170 route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
1173 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1175 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1176 zlog_debug ("remove %s", buf
);
1178 ospf6_route_remove (route
, oa
->route_table
);
1182 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1183 zlog_debug ("Trailing garbage ignored");
1187 ospf6_intra_route_calculation (struct ospf6_area
*oa
)
1189 struct ospf6_route
*route
;
1191 struct ospf6_lsa
*lsa
;
1192 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1193 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1195 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1196 zlog_debug ("Re-examin intra-routes for area %s", oa
->name
);
1198 hook_add
= oa
->route_table
->hook_add
;
1199 hook_remove
= oa
->route_table
->hook_remove
;
1200 oa
->route_table
->hook_add
= NULL
;
1201 oa
->route_table
->hook_remove
= NULL
;
1203 for (route
= ospf6_route_head (oa
->route_table
); route
;
1204 route
= ospf6_route_next (route
))
1205 route
->flag
= OSPF6_ROUTE_REMOVE
;
1207 type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1208 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
1209 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1210 ospf6_intra_prefix_lsa_add (lsa
);
1212 oa
->route_table
->hook_add
= hook_add
;
1213 oa
->route_table
->hook_remove
= hook_remove
;
1215 for (route
= ospf6_route_head (oa
->route_table
); route
;
1216 route
= ospf6_route_next (route
))
1218 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
) &&
1219 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
))
1221 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
);
1222 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_ADD
);
1225 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
1226 ospf6_route_remove (route
, oa
->route_table
);
1227 else if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
) ||
1228 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_CHANGE
))
1231 (*hook_add
) (route
);
1237 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1238 zlog_debug ("Re-examin intra-routes for area %s: Done", oa
->name
);
1242 ospf6_brouter_debug_print (struct ospf6_route
*brouter
)
1244 u_int32_t brouter_id
;
1245 char brouter_name
[16];
1247 char destination
[64];
1248 char installed
[16], changed
[16];
1249 struct timeval now
, res
;
1250 char id
[16], adv_router
[16];
1251 char capa
[16], options
[16];
1253 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1254 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1255 inet_ntop (AF_INET
, &brouter
->path
.area_id
, area_name
, sizeof (area_name
));
1256 ospf6_linkstate_prefix2str (&brouter
->prefix
, destination
,
1257 sizeof (destination
));
1259 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &now
);
1260 timersub (&now
, &brouter
->installed
, &res
);
1261 timerstring (&res
, installed
, sizeof (installed
));
1263 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &now
);
1264 timersub (&now
, &brouter
->changed
, &res
);
1265 timerstring (&res
, changed
, sizeof (changed
));
1267 inet_ntop (AF_INET
, &brouter
->path
.origin
.id
, id
, sizeof (id
));
1268 inet_ntop (AF_INET
, &brouter
->path
.origin
.adv_router
, adv_router
,
1269 sizeof (adv_router
));
1271 ospf6_options_printbuf (brouter
->path
.options
, options
, sizeof (options
));
1272 ospf6_capability_printbuf (brouter
->path
.router_bits
, capa
, sizeof (capa
));
1274 zlog_info ("Brouter: %s via area %s", brouter_name
, area_name
);
1275 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1276 brouter
->prev
, brouter
, brouter
->next
, brouter
->rnode
);
1277 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1278 brouter
->type
, destination
, installed
, changed
);
1279 zlog_info (" lock: %d flags: %s%s%s%s", brouter
->lock
,
1280 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_BEST
) ? "B" : "-"),
1281 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ? "A" : "-"),
1282 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) ? "R" : "-"),
1283 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
) ? "C" : "-"));
1284 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1285 OSPF6_PATH_TYPE_NAME (brouter
->path
.type
),
1286 ospf6_lstype_name (brouter
->path
.origin
.type
),
1288 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1289 options
, capa
, brouter
->path
.metric_type
,
1290 brouter
->path
.cost
, brouter
->path
.cost_e2
);
1294 ospf6_intra_brouter_calculation (struct ospf6_area
*oa
)
1296 struct ospf6_route
*brouter
, *copy
;
1297 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1298 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1299 u_int32_t brouter_id
;
1300 char brouter_name
[16];
1302 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1303 zlog_info ("border-router calculation for area %s", oa
->name
);
1305 hook_add
= oa
->ospf6
->brouter_table
->hook_add
;
1306 hook_remove
= oa
->ospf6
->brouter_table
->hook_remove
;
1307 oa
->ospf6
->brouter_table
->hook_add
= NULL
;
1308 oa
->ospf6
->brouter_table
->hook_remove
= NULL
;
1310 /* withdraw the previous router entries for the area */
1311 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1312 brouter
= ospf6_route_next (brouter
))
1314 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1315 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1316 if (brouter
->path
.area_id
!= oa
->area_id
)
1318 brouter
->flag
= OSPF6_ROUTE_REMOVE
;
1320 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1321 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1323 zlog_info ("%p: mark as removing: area %s brouter %s",
1324 brouter
, oa
->name
, brouter_name
);
1325 ospf6_brouter_debug_print (brouter
);
1329 for (brouter
= ospf6_route_head (oa
->spf_table
); brouter
;
1330 brouter
= ospf6_route_next (brouter
))
1332 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1333 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1335 if (brouter
->type
!= OSPF6_DEST_TYPE_LINKSTATE
)
1337 if (ospf6_linkstate_prefix_id (&brouter
->prefix
) != htonl (0))
1339 if (! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_E
) &&
1340 ! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
1343 copy
= ospf6_route_copy (brouter
);
1344 copy
->type
= OSPF6_DEST_TYPE_ROUTER
;
1345 copy
->path
.area_id
= oa
->area_id
;
1346 ospf6_route_add (copy
, oa
->ospf6
->brouter_table
);
1348 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1349 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1351 zlog_info ("%p: transfer: area %s brouter %s",
1352 brouter
, oa
->name
, brouter_name
);
1353 ospf6_brouter_debug_print (brouter
);
1357 oa
->ospf6
->brouter_table
->hook_add
= hook_add
;
1358 oa
->ospf6
->brouter_table
->hook_remove
= hook_remove
;
1360 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1361 brouter
= ospf6_route_next (brouter
))
1363 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1364 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1366 if (brouter
->path
.area_id
!= oa
->area_id
)
1369 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
1372 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) &&
1373 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
))
1375 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1376 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
);
1379 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
))
1381 if (IS_OSPF6_DEBUG_BROUTER
||
1382 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1383 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1384 zlog_info ("brouter %s disappears via area %s",
1385 brouter_name
, oa
->name
);
1386 ospf6_route_remove (brouter
, oa
->ospf6
->brouter_table
);
1388 else if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ||
1389 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
))
1391 if (IS_OSPF6_DEBUG_BROUTER
||
1392 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1393 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1394 zlog_info ("brouter %s appears via area %s",
1395 brouter_name
, oa
->name
);
1399 (*hook_add
) (brouter
);
1403 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1404 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1405 zlog_info ("brouter %s still exists via area %s",
1406 brouter_name
, oa
->name
);
1412 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1413 zlog_info ("border-router calculation for area %s: done", oa
->name
);
1416 struct ospf6_lsa_handler router_handler
=
1418 OSPF6_LSTYPE_ROUTER
,
1420 ospf6_router_lsa_show
1423 struct ospf6_lsa_handler network_handler
=
1425 OSPF6_LSTYPE_NETWORK
,
1427 ospf6_network_lsa_show
1430 struct ospf6_lsa_handler link_handler
=
1437 struct ospf6_lsa_handler intra_prefix_handler
=
1439 OSPF6_LSTYPE_INTRA_PREFIX
,
1441 ospf6_intra_prefix_lsa_show
1445 ospf6_intra_init (void)
1447 ospf6_install_lsa_handler (&router_handler
);
1448 ospf6_install_lsa_handler (&network_handler
);
1449 ospf6_install_lsa_handler (&link_handler
);
1450 ospf6_install_lsa_handler (&intra_prefix_handler
);
1453 DEFUN (debug_ospf6_brouter
,
1454 debug_ospf6_brouter_cmd
,
1455 "debug ospf6 border-routers",
1458 "Debug border router\n"
1461 OSPF6_DEBUG_BROUTER_ON ();
1465 DEFUN (no_debug_ospf6_brouter
,
1466 no_debug_ospf6_brouter_cmd
,
1467 "no debug ospf6 border-routers",
1471 "Debug border router\n"
1474 OSPF6_DEBUG_BROUTER_OFF ();
1478 DEFUN (debug_ospf6_brouter_router
,
1479 debug_ospf6_brouter_router_cmd
,
1480 "debug ospf6 border-routers router-id A.B.C.D",
1483 "Debug border router\n"
1484 "Debug specific border router\n"
1485 "Specify border-router's router-id\n"
1488 u_int32_t router_id
;
1489 inet_pton (AF_INET
, argv
[0], &router_id
);
1490 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id
);
1494 DEFUN (no_debug_ospf6_brouter_router
,
1495 no_debug_ospf6_brouter_router_cmd
,
1496 "no debug ospf6 border-routers router-id",
1500 "Debug border router\n"
1501 "Debug specific border router\n"
1504 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1508 DEFUN (debug_ospf6_brouter_area
,
1509 debug_ospf6_brouter_area_cmd
,
1510 "debug ospf6 border-routers area-id A.B.C.D",
1513 "Debug border router\n"
1514 "Debug border routers in specific Area\n"
1519 inet_pton (AF_INET
, argv
[0], &area_id
);
1520 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id
);
1524 DEFUN (no_debug_ospf6_brouter_area
,
1525 no_debug_ospf6_brouter_area_cmd
,
1526 "no debug ospf6 border-routers area-id",
1530 "Debug border router\n"
1531 "Debug border routers in specific Area\n"
1534 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1539 config_write_ospf6_debug_brouter (struct vty
*vty
)
1542 if (IS_OSPF6_DEBUG_BROUTER
)
1543 vty_out (vty
, "debug ospf6 border-routers%s", VNL
);
1544 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER
)
1546 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_router_id
,
1548 vty_out (vty
, "debug ospf6 border-routers router-id %s%s", buf
, VNL
);
1550 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA
)
1552 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_area_id
,
1554 vty_out (vty
, "debug ospf6 border-routers area-id %s%s", buf
, VNL
);
1560 install_element_ospf6_debug_brouter (void)
1562 install_element (ENABLE_NODE
, &debug_ospf6_brouter_cmd
);
1563 install_element (ENABLE_NODE
, &debug_ospf6_brouter_router_cmd
);
1564 install_element (ENABLE_NODE
, &debug_ospf6_brouter_area_cmd
);
1565 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_cmd
);
1566 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1567 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_area_cmd
);
1568 install_element (CONFIG_NODE
, &debug_ospf6_brouter_cmd
);
1569 install_element (CONFIG_NODE
, &debug_ospf6_brouter_router_cmd
);
1570 install_element (CONFIG_NODE
, &debug_ospf6_brouter_area_cmd
);
1571 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_cmd
);
1572 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1573 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_area_cmd
);