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"
50 /******************************/
51 /* RFC2740 3.4.3.1 Router-LSA */
52 /******************************/
55 ospf6_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
57 char *start
, *end
, *current
;
58 char buf
[32], name
[32], bits
[16], options
[32];
59 struct ospf6_router_lsa
*router_lsa
;
60 struct ospf6_router_lsdesc
*lsdesc
;
62 router_lsa
= (struct ospf6_router_lsa
*)
63 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
65 ospf6_capability_printbuf (router_lsa
->bits
, bits
, sizeof (bits
));
66 ospf6_options_printbuf (router_lsa
->options
, options
, sizeof (options
));
67 vty_out (vty
, " Bits: %s Options: %s%s", bits
, options
, VNL
);
69 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
70 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
71 for (current
= start
; current
+ sizeof (struct ospf6_router_lsdesc
) <= end
;
72 current
+= sizeof (struct ospf6_router_lsdesc
))
74 lsdesc
= (struct ospf6_router_lsdesc
*) current
;
76 if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_POINTTOPOINT
)
77 snprintf (name
, sizeof (name
), "Point-To-Point");
78 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
)
79 snprintf (name
, sizeof (name
), "Transit-Network");
80 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_STUB_NETWORK
)
81 snprintf (name
, sizeof (name
), "Stub-Network");
82 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_VIRTUAL_LINK
)
83 snprintf (name
, sizeof (name
), "Virtual-Link");
85 snprintf (name
, sizeof (name
), "Unknown (%#x)", lsdesc
->type
);
87 vty_out (vty
, " Type: %s Metric: %d%s",
88 name
, ntohs (lsdesc
->metric
), VNL
);
89 vty_out (vty
, " Interface ID: %s%s",
90 inet_ntop (AF_INET
, &lsdesc
->interface_id
,
91 buf
, sizeof (buf
)), VNL
);
92 vty_out (vty
, " Neighbor Interface ID: %s%s",
93 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
94 buf
, sizeof (buf
)), VNL
);
95 vty_out (vty
, " Neighbor Router ID: %s%s",
96 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
97 buf
, sizeof (buf
)), VNL
);
103 ospf6_router_lsa_originate (struct thread
*thread
)
105 struct ospf6_area
*oa
;
107 char buffer
[OSPF6_MAX_LSASIZE
];
108 struct ospf6_lsa_header
*lsa_header
;
109 struct ospf6_lsa
*lsa
;
111 u_int32_t link_state_id
= 0;
113 struct ospf6_interface
*oi
;
114 struct ospf6_neighbor
*on
, *drouter
= NULL
;
115 struct ospf6_router_lsa
*router_lsa
;
116 struct ospf6_router_lsdesc
*lsdesc
;
121 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
122 oa
->thread_router_lsa
= NULL
;
124 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
125 zlog_info ("Originate Router-LSA for Area %s", oa
->name
);
127 memset (buffer
, 0, sizeof (buffer
));
128 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
129 router_lsa
= (struct ospf6_router_lsa
*)
130 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
132 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_V6
);
133 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_E
);
134 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_MC
);
135 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_N
);
136 OSPF6_OPT_SET (router_lsa
->options
, OSPF6_OPT_R
);
137 OSPF6_OPT_CLEAR (router_lsa
->options
, OSPF6_OPT_DC
);
139 if (ospf6_is_router_abr (ospf6
))
140 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
142 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
143 if (ospf6_asbr_is_asbr (ospf6
))
144 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
146 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
147 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_V
);
148 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_W
);
150 /* describe links for each interfaces */
151 lsdesc
= (struct ospf6_router_lsdesc
*)
152 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
154 for (i
= listhead (oa
->if_list
); i
; nextnode (i
))
156 oi
= (struct ospf6_interface
*) getdata (i
);
158 /* Interfaces in state Down or Loopback are not described */
159 if (oi
->state
== OSPF6_INTERFACE_DOWN
||
160 oi
->state
== OSPF6_INTERFACE_LOOPBACK
)
163 /* Nor are interfaces without any full adjacencies described */
165 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
167 on
= (struct ospf6_neighbor
*) getdata (j
);
168 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
174 /* Multiple Router-LSA instance according to size limit setting */
175 if (oa
->router_lsa_size_limit
!= 0 &&
176 (caddr_t
) lsdesc
+ sizeof (struct ospf6_router_lsdesc
) -
177 (caddr_t
) buffer
> oa
->router_lsa_size_limit
)
179 if ((caddr_t
) lsdesc
== (caddr_t
) router_lsa
+
180 sizeof (struct ospf6_router_lsa
))
182 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
183 zlog_info ("Size limit setting for Router-LSA too short");
187 /* Fill LSA Header */
189 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
190 lsa_header
->id
= htonl (link_state_id
);
191 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
193 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
194 lsa_header
->adv_router
, oa
->lsdb
);
195 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
198 ospf6_lsa_checksum (lsa_header
);
201 lsa
= ospf6_lsa_create (lsa_header
);
204 ospf6_lsa_originate_area (lsa
, oa
);
206 /* Reset setting for consecutive origination */
207 memset ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
),
208 0, (caddr_t
) lsdesc
- (caddr_t
) router_lsa
);
209 lsdesc
= (struct ospf6_router_lsdesc
*)
210 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
214 /* Point-to-Point interfaces */
215 if (if_is_pointopoint (oi
->interface
))
217 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
219 on
= (struct ospf6_neighbor
*) getdata (j
);
220 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
223 lsdesc
->type
= OSPF6_ROUTER_LSDESC_POINTTOPOINT
;
224 lsdesc
->metric
= htons (oi
->cost
);
225 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
226 lsdesc
->neighbor_interface_id
= htonl (on
->ifindex
);
227 lsdesc
->neighbor_router_id
= on
->router_id
;
233 /* Broadcast and NBMA interfaces */
234 if (if_is_broadcast (oi
->interface
))
236 /* If this router is not DR,
237 and If this router not fully adjacent with DR,
238 this interface is not transit yet: ignore. */
239 if (oi
->state
!= OSPF6_INTERFACE_DR
)
241 drouter
= ospf6_neighbor_lookup (oi
->drouter
, oi
);
242 if (drouter
== NULL
|| drouter
->state
!= OSPF6_NEIGHBOR_FULL
)
246 lsdesc
->type
= OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
;
247 lsdesc
->metric
= htons (oi
->cost
);
248 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
249 if (oi
->state
!= OSPF6_INTERFACE_DR
)
251 lsdesc
->neighbor_interface_id
= htonl (drouter
->ifindex
);
252 lsdesc
->neighbor_router_id
= drouter
->router_id
;
256 lsdesc
->neighbor_interface_id
= htonl (oi
->interface
->ifindex
);
257 lsdesc
->neighbor_router_id
= oi
->area
->ospf6
->router_id
;
265 /* Point-to-Multipoint interfaces */
269 if ((caddr_t
) lsdesc
!= (caddr_t
) router_lsa
+
270 sizeof (struct ospf6_router_lsa
))
272 /* Fill LSA Header */
274 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
275 lsa_header
->id
= htonl (link_state_id
);
276 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
278 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
279 lsa_header
->adv_router
, oa
->lsdb
);
280 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
283 ospf6_lsa_checksum (lsa_header
);
286 lsa
= ospf6_lsa_create (lsa_header
);
289 ospf6_lsa_originate_area (lsa
, oa
);
295 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
296 zlog_info ("Nothing to describe in Router-LSA, suppress");
299 /* Do premature-aging of rest, undesired Router-LSAs */
300 type
= ntohs (OSPF6_LSTYPE_ROUTER
);
301 router
= oa
->ospf6
->router_id
;
302 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, oa
->lsdb
); lsa
;
303 lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
305 if (ntohl (lsa
->header
->id
) < link_state_id
)
307 ospf6_lsa_purge (lsa
);
313 /*******************************/
314 /* RFC2740 3.4.3.2 Network-LSA */
315 /*******************************/
318 ospf6_network_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
320 char *start
, *end
, *current
;
321 struct ospf6_network_lsa
*network_lsa
;
322 struct ospf6_network_lsdesc
*lsdesc
;
323 char buf
[128], options
[32];
325 network_lsa
= (struct ospf6_network_lsa
*)
326 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
328 ospf6_options_printbuf (network_lsa
->options
, options
, sizeof (options
));
329 vty_out (vty
, " Options: %s%s", options
, VNL
);
331 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
332 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
333 for (current
= start
; current
+ sizeof (struct ospf6_network_lsdesc
) <= end
;
334 current
+= sizeof (struct ospf6_network_lsdesc
))
336 lsdesc
= (struct ospf6_network_lsdesc
*) current
;
337 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, sizeof (buf
));
338 vty_out (vty
, " Attached Router: %s%s", buf
, VNL
);
344 ospf6_network_lsa_originate (struct thread
*thread
)
346 struct ospf6_interface
*oi
;
348 char buffer
[OSPF6_MAX_LSASIZE
];
349 struct ospf6_lsa_header
*lsa_header
;
352 struct ospf6_lsa
*old
, *lsa
;
353 struct ospf6_network_lsa
*network_lsa
;
354 struct ospf6_network_lsdesc
*lsdesc
;
355 struct ospf6_neighbor
*on
;
356 struct ospf6_link_lsa
*link_lsa
;
360 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
361 oi
->thread_network_lsa
= NULL
;
363 /* The interface must be enabled until here. A Network-LSA of a
364 disabled interface (but was once enabled) should be flushed
365 by ospf6_lsa_refresh (), and does not come here. */
368 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK
),
369 htonl (oi
->interface
->ifindex
),
370 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
372 /* Do not originate Network-LSA if not DR */
373 if (oi
->state
!= OSPF6_INTERFACE_DR
)
376 ospf6_lsa_purge (old
);
380 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
381 zlog_info ("Originate Network-LSA for Interface %s", oi
->interface
->name
);
383 /* If none of neighbor is adjacent to us */
385 for (i
= listhead (oi
->neighbor_list
); i
; nextnode (i
))
387 on
= (struct ospf6_neighbor
*) getdata (i
);
388 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
393 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
394 zlog_info ("Interface stub, ignore");
396 ospf6_lsa_purge (old
);
401 memset (buffer
, 0, sizeof (buffer
));
402 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
403 network_lsa
= (struct ospf6_network_lsa
*)
404 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
406 /* Collect the interface's Link-LSAs to describe
407 network's optional capabilities */
408 type
= htons (OSPF6_LSTYPE_LINK
);
409 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
410 lsa
= ospf6_lsdb_type_next (type
, lsa
))
412 link_lsa
= (struct ospf6_link_lsa
*)
413 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
414 network_lsa
->options
[0] |= link_lsa
->options
[0];
415 network_lsa
->options
[1] |= link_lsa
->options
[1];
416 network_lsa
->options
[2] |= link_lsa
->options
[2];
419 lsdesc
= (struct ospf6_network_lsdesc
*)
420 ((caddr_t
) network_lsa
+ sizeof (struct ospf6_network_lsa
));
422 /* set Link Description to the router itself */
423 lsdesc
->router_id
= oi
->area
->ospf6
->router_id
;
426 /* Walk through the neighbors */
427 for (i
= listhead (oi
->neighbor_list
); i
; nextnode (i
))
429 on
= (struct ospf6_neighbor
*) getdata (i
);
431 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
434 /* set this neighbor's Router-ID to LSA */
435 lsdesc
->router_id
= on
->router_id
;
439 /* Fill LSA Header */
441 lsa_header
->type
= htons (OSPF6_LSTYPE_NETWORK
);
442 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
443 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
445 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
446 lsa_header
->adv_router
, oi
->area
->lsdb
);
447 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
450 ospf6_lsa_checksum (lsa_header
);
453 lsa
= ospf6_lsa_create (lsa_header
);
456 ospf6_lsa_originate_area (lsa
, oi
->area
);
462 /****************************/
463 /* RFC2740 3.4.3.6 Link-LSA */
464 /****************************/
467 ospf6_link_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
469 char *start
, *end
, *current
;
470 struct ospf6_link_lsa
*link_lsa
;
472 char buf
[128], options
[32];
473 struct ospf6_prefix
*prefix
;
474 char *p
, *mc
, *la
, *nu
;
477 link_lsa
= (struct ospf6_link_lsa
*)
478 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
480 ospf6_options_printbuf (link_lsa
->options
, options
, sizeof (options
));
481 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, sizeof (buf
));
482 prefixnum
= ntohl (link_lsa
->prefix_num
);
484 vty_out (vty
, " Priority: %d Options: %s%s",
485 link_lsa
->priority
, options
, VNL
);
486 vty_out (vty
, " LinkLocal Address: %s%s", buf
, VNL
);
487 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
489 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
490 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
491 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
493 prefix
= (struct ospf6_prefix
*) current
;
494 if (prefix
->prefix_length
== 0 ||
495 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
498 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
500 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
502 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
504 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
506 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
509 memset (&in6
, 0, sizeof (in6
));
510 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
511 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
512 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
513 vty_out (vty
, " Prefix: %s/%d%s",
514 buf
, prefix
->prefix_length
, VNL
);
521 ospf6_link_lsa_originate (struct thread
*thread
)
523 struct ospf6_interface
*oi
;
525 char buffer
[OSPF6_MAX_LSASIZE
];
526 struct ospf6_lsa_header
*lsa_header
;
527 struct ospf6_lsa
*old
, *lsa
;
529 struct ospf6_link_lsa
*link_lsa
;
530 struct ospf6_route
*route
;
531 struct ospf6_prefix
*op
;
533 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
534 oi
->thread_link_lsa
= NULL
;
538 /* find previous LSA */
539 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK
),
540 htonl (oi
->interface
->ifindex
),
541 oi
->area
->ospf6
->router_id
, oi
->lsdb
);
543 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
546 ospf6_lsa_purge (old
);
550 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
551 zlog_info ("Originate Link-LSA for Interface %s", oi
->interface
->name
);
553 /* can't make Link-LSA if linklocal address not set */
554 if (oi
->linklocal_addr
== NULL
)
556 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
557 zlog_info ("No Linklocal address on %s, defer originating",
558 oi
->interface
->name
);
560 ospf6_lsa_purge (old
);
565 memset (buffer
, 0, sizeof (buffer
));
566 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
567 link_lsa
= (struct ospf6_link_lsa
*)
568 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
571 link_lsa
->priority
= oi
->priority
;
572 memcpy (link_lsa
->options
, oi
->area
->options
, 3);
573 memcpy (&link_lsa
->linklocal_addr
, oi
->linklocal_addr
,
574 sizeof (struct in6_addr
));
575 link_lsa
->prefix_num
= htonl (oi
->route_connected
->count
);
577 op
= (struct ospf6_prefix
*)
578 ((caddr_t
) link_lsa
+ sizeof (struct ospf6_link_lsa
));
580 /* connected prefix to advertise */
581 for (route
= ospf6_route_head (oi
->route_connected
); route
;
582 route
= ospf6_route_next (route
))
584 op
->prefix_length
= route
->prefix
.prefixlen
;
585 op
->prefix_options
= route
->path
.prefix_options
;
586 op
->prefix_metric
= htons (0);
587 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
588 OSPF6_PREFIX_SPACE (op
->prefix_length
));
589 op
= OSPF6_PREFIX_NEXT (op
);
592 /* Fill LSA Header */
594 lsa_header
->type
= htons (OSPF6_LSTYPE_LINK
);
595 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
596 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
598 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
599 lsa_header
->adv_router
, oi
->lsdb
);
600 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) buffer
);
603 ospf6_lsa_checksum (lsa_header
);
606 lsa
= ospf6_lsa_create (lsa_header
);
609 ospf6_lsa_originate_interface (lsa
, oi
);
615 /*****************************************/
616 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
617 /*****************************************/
620 ospf6_intra_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
622 char *start
, *end
, *current
;
623 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
626 struct ospf6_prefix
*prefix
;
627 char id
[16], adv_router
[16];
628 char *p
, *mc
, *la
, *nu
;
631 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
632 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
634 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
636 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
638 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_id
, id
, sizeof (id
));
639 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_adv_router
,
640 adv_router
, sizeof (adv_router
));
641 vty_out (vty
, " Reference: %s Id: %s Adv: %s%s",
642 ospf6_lstype_name (intra_prefix_lsa
->ref_type
), id
, adv_router
,
645 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
646 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
647 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
649 prefix
= (struct ospf6_prefix
*) current
;
650 if (prefix
->prefix_length
== 0 ||
651 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
654 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
656 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
658 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
660 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
662 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
665 memset (&in6
, 0, sizeof (in6
));
666 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
667 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
668 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
669 vty_out (vty
, " Prefix: %s/%d%s",
670 buf
, prefix
->prefix_length
, VNL
);
677 ospf6_intra_prefix_lsa_originate_stub (struct thread
*thread
)
679 struct ospf6_area
*oa
;
681 char buffer
[OSPF6_MAX_LSASIZE
];
682 struct ospf6_lsa_header
*lsa_header
;
683 struct ospf6_lsa
*old
, *lsa
;
685 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
686 struct ospf6_interface
*oi
;
687 struct ospf6_neighbor
*on
;
688 struct ospf6_route
*route
;
689 struct ospf6_prefix
*op
;
692 unsigned short prefix_num
= 0;
694 struct ospf6_route_table
*route_advertise
;
696 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
697 oa
->thread_intra_prefix_lsa
= NULL
;
699 /* find previous LSA */
700 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
701 htonl (0), oa
->ospf6
->router_id
, oa
->lsdb
);
703 if (! IS_AREA_ENABLED (oa
))
706 ospf6_lsa_purge (old
);
710 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
711 zlog_info ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
715 memset (buffer
, 0, sizeof (buffer
));
716 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
717 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
718 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
720 /* Fill Intra-Area-Prefix-LSA */
721 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_ROUTER
);
722 intra_prefix_lsa
->ref_id
= htonl (0);
723 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
725 route_advertise
= ospf6_route_table_create ();
727 for (i
= listhead (oa
->if_list
); i
; nextnode (i
))
729 oi
= (struct ospf6_interface
*) getdata (i
);
731 if (oi
->state
== OSPF6_INTERFACE_DOWN
)
733 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
734 zlog_info (" Interface %s is down, ignore", oi
->interface
->name
);
739 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
741 on
= (struct ospf6_neighbor
*) getdata (j
);
742 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
745 if (oi
->state
!= OSPF6_INTERFACE_LOOPBACK
&&
746 oi
->state
!= OSPF6_INTERFACE_POINTTOPOINT
&&
749 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
750 zlog_info (" Interface %s is not stub, ignore",
751 oi
->interface
->name
);
755 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
756 zlog_info (" Interface %s:", oi
->interface
->name
);
758 /* connected prefix to advertise */
759 for (route
= ospf6_route_head (oi
->route_connected
); route
;
760 route
= ospf6_route_best_next (route
))
762 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
764 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
765 zlog_info (" include %s", buf
);
767 ospf6_route_add (ospf6_route_copy (route
), route_advertise
);
771 if (route_advertise
->count
== 0)
774 ospf6_lsa_purge (old
);
775 ospf6_route_table_delete (route_advertise
);
779 /* put prefixes to advertise */
781 op
= (struct ospf6_prefix
*)
782 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
783 for (route
= ospf6_route_head (route_advertise
); route
;
784 route
= ospf6_route_best_next (route
))
786 op
->prefix_length
= route
->prefix
.prefixlen
;
787 op
->prefix_options
= route
->path
.prefix_options
;
788 op
->prefix_metric
= htons (route
->path
.cost
);
789 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
790 OSPF6_PREFIX_SPACE (op
->prefix_length
));
791 op
= OSPF6_PREFIX_NEXT (op
);
795 ospf6_route_table_delete (route_advertise
);
799 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
800 zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise");
804 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
806 /* Fill LSA Header */
808 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
809 lsa_header
->id
= htonl (0);
810 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
812 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
813 lsa_header
->adv_router
, oa
->lsdb
);
814 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
817 ospf6_lsa_checksum (lsa_header
);
820 lsa
= ospf6_lsa_create (lsa_header
);
823 ospf6_lsa_originate_area (lsa
, oa
);
830 ospf6_intra_prefix_lsa_originate_transit (struct thread
*thread
)
832 struct ospf6_interface
*oi
;
834 char buffer
[OSPF6_MAX_LSASIZE
];
835 struct ospf6_lsa_header
*lsa_header
;
836 struct ospf6_lsa
*old
, *lsa
;
838 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
839 struct ospf6_neighbor
*on
;
840 struct ospf6_route
*route
;
841 struct ospf6_prefix
*op
;
844 unsigned short prefix_num
= 0;
845 struct ospf6_route_table
*route_advertise
;
846 struct ospf6_link_lsa
*link_lsa
;
847 char *start
, *end
, *current
;
851 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
852 oi
->thread_intra_prefix_lsa
= NULL
;
856 /* find previous LSA */
857 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
858 htonl (oi
->interface
->ifindex
),
859 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
861 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
864 ospf6_lsa_purge (old
);
868 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
869 zlog_info ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
870 oi
->interface
->name
);
873 memset (buffer
, 0, sizeof (buffer
));
874 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
875 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
876 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
878 /* Fill Intra-Area-Prefix-LSA */
879 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_NETWORK
);
880 intra_prefix_lsa
->ref_id
= htonl (oi
->interface
->ifindex
);
881 intra_prefix_lsa
->ref_adv_router
= oi
->area
->ospf6
->router_id
;
883 if (oi
->state
!= OSPF6_INTERFACE_DR
)
885 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
886 zlog_info (" Interface is not DR");
888 ospf6_lsa_purge (old
);
893 for (i
= listhead (oi
->neighbor_list
); i
; nextnode (i
))
895 on
= (struct ospf6_neighbor
*) getdata (i
);
896 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
901 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
902 zlog_info (" Interface is stub");
904 ospf6_lsa_purge (old
);
908 /* connected prefix to advertise */
909 route_advertise
= ospf6_route_table_create ();
911 type
= ntohs (OSPF6_LSTYPE_LINK
);
912 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
913 lsa
= ospf6_lsdb_type_next (type
, lsa
))
915 if (OSPF6_LSA_IS_MAXAGE (lsa
))
918 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
919 zlog_info (" include prefix from %s", lsa
->name
);
921 if (lsa
->header
->adv_router
!= oi
->area
->ospf6
->router_id
)
923 on
= ospf6_neighbor_lookup (lsa
->header
->adv_router
, oi
);
924 if (on
== NULL
|| on
->state
!= OSPF6_NEIGHBOR_FULL
)
926 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
927 zlog_info (" Neighbor not found or not Full, ignore");
932 link_lsa
= (struct ospf6_link_lsa
*)
933 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
935 prefix_num
= (unsigned short) ntohl (link_lsa
->prefix_num
);
936 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
937 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
938 for (current
= start
; current
< end
&& prefix_num
;
939 current
+= OSPF6_PREFIX_SIZE (op
))
941 op
= (struct ospf6_prefix
*) current
;
942 if (op
->prefix_length
== 0 ||
943 current
+ OSPF6_PREFIX_SIZE (op
) > end
)
946 route
= ospf6_route_create ();
948 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
949 route
->prefix
.family
= AF_INET6
;
950 route
->prefix
.prefixlen
= op
->prefix_length
;
951 memset (&route
->prefix
.u
.prefix6
, 0, sizeof (struct in6_addr
));
952 memcpy (&route
->prefix
.u
.prefix6
, OSPF6_PREFIX_BODY (op
),
953 OSPF6_PREFIX_SPACE (op
->prefix_length
));
955 route
->path
.origin
.type
= lsa
->header
->type
;
956 route
->path
.origin
.id
= lsa
->header
->id
;
957 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
958 route
->path
.options
[0] = link_lsa
->options
[0];
959 route
->path
.options
[1] = link_lsa
->options
[1];
960 route
->path
.options
[2] = link_lsa
->options
[2];
961 route
->path
.prefix_options
= op
->prefix_options
;
962 route
->path
.area_id
= oi
->area
->area_id
;
963 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
965 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
967 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
968 zlog_info (" include %s", buf
);
971 ospf6_route_add (route
, route_advertise
);
974 if (current
!= end
&& IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
975 zlog_info ("Trailing garbage in %s", lsa
->name
);
978 op
= (struct ospf6_prefix
*)
979 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
982 for (route
= ospf6_route_head (route_advertise
); route
;
983 route
= ospf6_route_best_next (route
))
985 op
->prefix_length
= route
->prefix
.prefixlen
;
986 op
->prefix_options
= route
->path
.prefix_options
;
987 op
->prefix_metric
= htons (0);
988 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
989 OSPF6_PREFIX_SPACE (op
->prefix_length
));
990 op
= OSPF6_PREFIX_NEXT (op
);
994 ospf6_route_table_delete (route_advertise
);
998 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
999 zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise");
1003 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
1005 /* Fill LSA Header */
1006 lsa_header
->age
= 0;
1007 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1008 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
1009 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
1010 lsa_header
->seqnum
=
1011 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1012 lsa_header
->adv_router
, oi
->area
->lsdb
);
1013 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1016 ospf6_lsa_checksum (lsa_header
);
1019 lsa
= ospf6_lsa_create (lsa_header
);
1022 ospf6_lsa_originate_area (lsa
, oi
->area
);
1028 ospf6_intra_prefix_lsa_add (struct ospf6_lsa
*lsa
)
1030 struct ospf6_area
*oa
;
1031 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1032 struct prefix ls_prefix
;
1033 struct ospf6_route
*route
, *ls_entry
;
1035 struct ospf6_prefix
*op
;
1036 char *start
, *current
, *end
;
1039 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1042 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1043 zlog_info ("%s found", lsa
->name
);
1045 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1047 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1048 OSPF6_LSA_HEADER_END (lsa
->header
);
1049 if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_ROUTER
))
1050 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1051 htonl (0), &ls_prefix
);
1052 else if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_NETWORK
))
1053 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1054 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1057 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1058 zlog_info ("Unknown reference LS-type: %#hx",
1059 ntohs (intra_prefix_lsa
->ref_type
));
1063 ls_entry
= ospf6_route_lookup (&ls_prefix
, oa
->spf_table
);
1064 if (ls_entry
== NULL
)
1066 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1068 ospf6_linkstate_prefix2str (&ls_prefix
, buf
, sizeof (buf
));
1069 zlog_info ("LS entry does not exist: %s", buf
);
1074 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1075 start
= (caddr_t
) intra_prefix_lsa
+
1076 sizeof (struct ospf6_intra_prefix_lsa
);
1077 end
= OSPF6_LSA_END (lsa
->header
);
1078 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1080 op
= (struct ospf6_prefix
*) current
;
1081 if (prefix_num
== 0)
1083 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1086 route
= ospf6_route_create ();
1088 memset (&route
->prefix
, 0, sizeof (struct prefix
));
1089 route
->prefix
.family
= AF_INET6
;
1090 route
->prefix
.prefixlen
= op
->prefix_length
;
1091 ospf6_prefix_in6_addr (&route
->prefix
.u
.prefix6
, op
);
1093 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1094 route
->path
.origin
.type
= lsa
->header
->type
;
1095 route
->path
.origin
.id
= lsa
->header
->id
;
1096 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1097 route
->path
.prefix_options
= op
->prefix_options
;
1098 route
->path
.area_id
= oa
->area_id
;
1099 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1100 route
->path
.metric_type
= 1;
1101 route
->path
.cost
= ls_entry
->path
.cost
+
1102 ntohs (op
->prefix_metric
);
1104 for (i
= 0; ospf6_nexthop_is_set (&ls_entry
->nexthop
[i
]) &&
1105 i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
1106 ospf6_nexthop_copy (&route
->nexthop
[i
], &ls_entry
->nexthop
[i
]);
1108 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1110 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1111 zlog_info (" add %s", buf
);
1114 ospf6_route_add (route
, oa
->route_table
);
1118 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1119 zlog_info ("Trailing garbage ignored");
1123 ospf6_intra_prefix_lsa_remove (struct ospf6_lsa
*lsa
)
1125 struct ospf6_area
*oa
;
1126 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1127 struct prefix prefix
;
1128 struct ospf6_route
*route
;
1130 struct ospf6_prefix
*op
;
1131 char *start
, *current
, *end
;
1134 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1135 zlog_info ("%s disappearing", lsa
->name
);
1137 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1139 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1140 OSPF6_LSA_HEADER_END (lsa
->header
);
1142 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1143 start
= (caddr_t
) intra_prefix_lsa
+
1144 sizeof (struct ospf6_intra_prefix_lsa
);
1145 end
= OSPF6_LSA_END (lsa
->header
);
1146 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1148 op
= (struct ospf6_prefix
*) current
;
1149 if (prefix_num
== 0)
1151 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1155 memset (&prefix
, 0, sizeof (struct prefix
));
1156 prefix
.family
= AF_INET6
;
1157 prefix
.prefixlen
= op
->prefix_length
;
1158 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, op
);
1160 route
= ospf6_route_lookup (&prefix
, oa
->route_table
);
1164 for (ospf6_route_lock (route
);
1165 route
&& ospf6_route_is_prefix (&prefix
, route
);
1166 route
= ospf6_route_next (route
))
1168 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
1170 if (route
->path
.area_id
!= oa
->area_id
)
1172 if (route
->path
.type
!= OSPF6_PATH_TYPE_INTRA
)
1174 if (route
->path
.origin
.type
!= lsa
->header
->type
||
1175 route
->path
.origin
.id
!= lsa
->header
->id
||
1176 route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
1179 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1181 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1182 zlog_info ("remove %s", buf
);
1184 ospf6_route_remove (route
, oa
->route_table
);
1188 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1189 zlog_info ("Trailing garbage ignored");
1193 ospf6_intra_route_calculation (struct ospf6_area
*oa
)
1195 struct ospf6_route
*route
;
1197 struct ospf6_lsa
*lsa
;
1198 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1199 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1201 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1202 zlog_info ("Re-examin intra-routes for area %s", oa
->name
);
1204 hook_add
= oa
->route_table
->hook_add
;
1205 hook_remove
= oa
->route_table
->hook_remove
;
1206 oa
->route_table
->hook_add
= NULL
;
1207 oa
->route_table
->hook_remove
= NULL
;
1209 for (route
= ospf6_route_head (oa
->route_table
); route
;
1210 route
= ospf6_route_next (route
))
1211 route
->flag
= OSPF6_ROUTE_REMOVE
;
1213 type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1214 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
1215 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1216 ospf6_intra_prefix_lsa_add (lsa
);
1218 oa
->route_table
->hook_add
= hook_add
;
1219 oa
->route_table
->hook_remove
= hook_remove
;
1221 for (route
= ospf6_route_head (oa
->route_table
); route
;
1222 route
= ospf6_route_next (route
))
1224 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
) &&
1225 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
))
1227 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
);
1228 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_ADD
);
1231 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
1232 ospf6_route_remove (route
, oa
->route_table
);
1233 else if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
) ||
1234 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_CHANGE
))
1237 (*hook_add
) (route
);
1243 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1244 zlog_info ("Re-examin intra-routes for area %s: Done", oa
->name
);
1248 ospf6_intra_brouter_calculation (struct ospf6_area
*oa
)
1250 struct ospf6_route
*lsentry
, *copy
;
1251 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1252 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1255 if (IS_OSPF6_DEBUG_ROUTE (INTRA
))
1256 zlog_info ("Border-router calculation for area %s", oa
->name
);
1258 hook_add
= oa
->ospf6
->brouter_table
->hook_add
;
1259 hook_remove
= oa
->ospf6
->brouter_table
->hook_remove
;
1260 oa
->ospf6
->brouter_table
->hook_add
= NULL
;
1261 oa
->ospf6
->brouter_table
->hook_remove
= NULL
;
1263 /* withdraw the previous router entries for the area */
1264 for (lsentry
= ospf6_route_head (oa
->ospf6
->brouter_table
); lsentry
;
1265 lsentry
= ospf6_route_next (lsentry
))
1267 if (lsentry
->path
.area_id
!= oa
->area_id
)
1269 lsentry
->flag
= OSPF6_ROUTE_REMOVE
;
1272 for (lsentry
= ospf6_route_head (oa
->spf_table
); lsentry
;
1273 lsentry
= ospf6_route_next (lsentry
))
1275 if (lsentry
->type
!= OSPF6_DEST_TYPE_LINKSTATE
)
1277 if (ospf6_linkstate_prefix_id (&lsentry
->prefix
) != htonl (0))
1279 if (! CHECK_FLAG (lsentry
->path
.router_bits
, OSPF6_ROUTER_BIT_E
) &&
1280 ! CHECK_FLAG (lsentry
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
1283 copy
= ospf6_route_copy (lsentry
);
1284 copy
->type
= OSPF6_DEST_TYPE_ROUTER
;
1285 copy
->path
.area_id
= oa
->area_id
;
1286 ospf6_route_add (copy
, oa
->ospf6
->brouter_table
);
1288 if (IS_OSPF6_DEBUG_ROUTE (INTRA
))
1290 inet_ntop (AF_INET
, &ADV_ROUTER_IN_PREFIX (©
->prefix
),
1292 zlog_info ("Re-install router entry %s", buf
);
1296 oa
->ospf6
->brouter_table
->hook_add
= hook_add
;
1297 oa
->ospf6
->brouter_table
->hook_remove
= hook_remove
;
1299 for (lsentry
= ospf6_route_head (oa
->ospf6
->brouter_table
); lsentry
;
1300 lsentry
= ospf6_route_next (lsentry
))
1302 if (lsentry
->path
.area_id
!= oa
->area_id
)
1305 if (CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
1308 if (CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_REMOVE
) &&
1309 CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_ADD
))
1311 UNSET_FLAG (lsentry
->flag
, OSPF6_ROUTE_REMOVE
);
1312 UNSET_FLAG (lsentry
->flag
, OSPF6_ROUTE_ADD
);
1315 if (CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_REMOVE
))
1316 ospf6_route_remove (lsentry
, oa
->ospf6
->brouter_table
);
1317 else if (CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_ADD
) ||
1318 CHECK_FLAG (lsentry
->flag
, OSPF6_ROUTE_CHANGE
))
1320 if (IS_OSPF6_DEBUG_ROUTE (INTRA
))
1322 inet_ntop (AF_INET
, &ADV_ROUTER_IN_PREFIX (&lsentry
->prefix
),
1324 zlog_info ("Call hook for router entry %s", buf
);
1327 (*hook_add
) (lsentry
);
1333 if (IS_OSPF6_DEBUG_ROUTE (INTRA
))
1334 zlog_info ("Border-router calculation for area %s: Done", oa
->name
);
1337 struct ospf6_lsa_handler router_handler
=
1339 OSPF6_LSTYPE_ROUTER
,
1341 ospf6_router_lsa_show
1344 struct ospf6_lsa_handler network_handler
=
1346 OSPF6_LSTYPE_NETWORK
,
1348 ospf6_network_lsa_show
1351 struct ospf6_lsa_handler link_handler
=
1358 struct ospf6_lsa_handler intra_prefix_handler
=
1360 OSPF6_LSTYPE_INTRA_PREFIX
,
1362 ospf6_intra_prefix_lsa_show
1368 ospf6_install_lsa_handler (&router_handler
);
1369 ospf6_install_lsa_handler (&network_handler
);
1370 ospf6_install_lsa_handler (&link_handler
);
1371 ospf6_install_lsa_handler (&intra_prefix_handler
);