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.
35 #include "ospf6_proto.h"
36 #include "ospf6_message.h"
37 #include "ospf6_route.h"
38 #include "ospf6_lsa.h"
39 #include "ospf6_lsdb.h"
41 #include "ospf6_top.h"
42 #include "ospf6_area.h"
43 #include "ospf6_interface.h"
44 #include "ospf6_neighbor.h"
45 #include "ospf6_intra.h"
46 #include "ospf6_asbr.h"
47 #include "ospf6_abr.h"
48 #include "ospf6_flood.h"
50 #include "ospf6_spf.h"
52 unsigned char conf_debug_ospf6_brouter
= 0;
53 u_int32_t conf_debug_ospf6_brouter_specific_router_id
;
54 u_int32_t conf_debug_ospf6_brouter_specific_area_id
;
56 /******************************/
57 /* RFC2740 3.4.3.1 Router-LSA */
58 /******************************/
61 ospf6_router_lsa_get_nbr_id (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
64 struct ospf6_router_lsa
*router_lsa
;
65 struct ospf6_router_lsdesc
*lsdesc
;
67 char buf1
[INET_ADDRSTRLEN
], buf2
[INET_ADDRSTRLEN
];
71 router_lsa
= (struct ospf6_router_lsa
*)
72 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
73 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
74 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
76 lsdesc
= (struct ospf6_router_lsdesc
*)
77 (start
+ pos
*(sizeof (struct ospf6_router_lsdesc
)));
78 if ((char *)lsdesc
< end
)
80 if (buf
&& (buflen
> INET_ADDRSTRLEN
*2))
82 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
84 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
86 sprintf (buf
, "%s/%s", buf2
, buf1
);
97 ospf6_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
99 char *start
, *end
, *current
;
100 char buf
[32], name
[32], bits
[16], options
[32];
101 struct ospf6_router_lsa
*router_lsa
;
102 struct ospf6_router_lsdesc
*lsdesc
;
104 router_lsa
= (struct ospf6_router_lsa
*)
105 ((char *) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
107 ospf6_capability_printbuf (router_lsa
->bits
, bits
, sizeof (bits
));
108 ospf6_options_printbuf (router_lsa
->options
, options
, sizeof (options
));
109 vty_out (vty
, " Bits: %s Options: %s%s", bits
, options
, VNL
);
111 start
= (char *) router_lsa
+ sizeof (struct ospf6_router_lsa
);
112 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
113 for (current
= start
; current
+ sizeof (struct ospf6_router_lsdesc
) <= end
;
114 current
+= sizeof (struct ospf6_router_lsdesc
))
116 lsdesc
= (struct ospf6_router_lsdesc
*) current
;
118 if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_POINTTOPOINT
)
119 snprintf (name
, sizeof (name
), "Point-To-Point");
120 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
)
121 snprintf (name
, sizeof (name
), "Transit-Network");
122 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_STUB_NETWORK
)
123 snprintf (name
, sizeof (name
), "Stub-Network");
124 else if (lsdesc
->type
== OSPF6_ROUTER_LSDESC_VIRTUAL_LINK
)
125 snprintf (name
, sizeof (name
), "Virtual-Link");
127 snprintf (name
, sizeof (name
), "Unknown (%#x)", lsdesc
->type
);
129 vty_out (vty
, " Type: %s Metric: %d%s",
130 name
, ntohs (lsdesc
->metric
), VNL
);
131 vty_out (vty
, " Interface ID: %s%s",
132 inet_ntop (AF_INET
, &lsdesc
->interface_id
,
133 buf
, sizeof (buf
)), VNL
);
134 vty_out (vty
, " Neighbor Interface ID: %s%s",
135 inet_ntop (AF_INET
, &lsdesc
->neighbor_interface_id
,
136 buf
, sizeof (buf
)), VNL
);
137 vty_out (vty
, " Neighbor Router ID: %s%s",
138 inet_ntop (AF_INET
, &lsdesc
->neighbor_router_id
,
139 buf
, sizeof (buf
)), VNL
);
145 ospf6_router_lsa_options_set (struct ospf6_area
*oa
,
146 struct ospf6_router_lsa
*router_lsa
)
148 OSPF6_OPT_CLEAR_ALL (router_lsa
->options
);
149 memcpy (router_lsa
->options
, oa
->options
, 3);
151 if (ospf6_is_router_abr (ospf6
))
152 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
154 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_B
);
156 if (!IS_AREA_STUB (oa
) && ospf6_asbr_is_asbr (oa
->ospf6
))
158 SET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
162 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_E
);
165 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_V
);
166 UNSET_FLAG (router_lsa
->bits
, OSPF6_ROUTER_BIT_W
);
170 ospf6_router_is_stub_router (struct ospf6_lsa
*lsa
)
172 struct ospf6_router_lsa
*rtr_lsa
;
174 if (lsa
!= NULL
&& OSPF6_LSA_IS_TYPE (ROUTER
, lsa
))
176 rtr_lsa
= (struct ospf6_router_lsa
*)
177 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
179 if (!OSPF6_OPT_ISSET (rtr_lsa
->options
, OSPF6_OPT_R
))
181 return (OSPF6_IS_STUB_ROUTER
);
183 else if (!OSPF6_OPT_ISSET (rtr_lsa
->options
, OSPF6_OPT_V6
))
185 return (OSPF6_IS_STUB_ROUTER_V6
);
189 return (OSPF6_NOT_STUB_ROUTER
);
193 ospf6_router_lsa_originate (struct thread
*thread
)
195 struct ospf6_area
*oa
;
197 char buffer
[OSPF6_MAX_LSASIZE
];
198 struct ospf6_lsa_header
*lsa_header
;
199 struct ospf6_lsa
*lsa
;
201 u_int32_t link_state_id
= 0;
202 struct listnode
*node
, *nnode
;
204 struct ospf6_interface
*oi
;
205 struct ospf6_neighbor
*on
, *drouter
= NULL
;
206 struct ospf6_router_lsa
*router_lsa
;
207 struct ospf6_router_lsdesc
*lsdesc
;
212 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
213 oa
->thread_router_lsa
= NULL
;
215 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
216 zlog_debug ("Originate Router-LSA for Area %s", oa
->name
);
218 memset (buffer
, 0, sizeof (buffer
));
219 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
220 router_lsa
= (struct ospf6_router_lsa
*)
221 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
223 ospf6_router_lsa_options_set (oa
, router_lsa
);
225 /* describe links for each interfaces */
226 lsdesc
= (struct ospf6_router_lsdesc
*)
227 ((caddr_t
) router_lsa
+ sizeof (struct ospf6_router_lsa
));
229 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
231 /* Interfaces in state Down or Loopback are not described */
232 if (oi
->state
== OSPF6_INTERFACE_DOWN
||
233 oi
->state
== OSPF6_INTERFACE_LOOPBACK
)
236 /* Nor are interfaces without any full adjacencies described */
238 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
239 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
245 /* Multiple Router-LSA instance according to size limit setting */
246 if ( (oa
->router_lsa_size_limit
!= 0)
247 && ((size_t)((char *)lsdesc
- buffer
)
248 + sizeof (struct ospf6_router_lsdesc
)
249 > oa
->router_lsa_size_limit
))
251 if ((caddr_t
) lsdesc
== (caddr_t
) router_lsa
+
252 sizeof (struct ospf6_router_lsa
))
254 if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER
))
255 zlog_debug ("Size limit setting for Router-LSA too short");
262 /* Point-to-Point interfaces */
263 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
265 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
267 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
270 lsdesc
->type
= OSPF6_ROUTER_LSDESC_POINTTOPOINT
;
271 lsdesc
->metric
= htons (oi
->cost
);
272 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
273 lsdesc
->neighbor_interface_id
= htonl (on
->ifindex
);
274 lsdesc
->neighbor_router_id
= on
->router_id
;
280 /* Broadcast and NBMA interfaces */
281 else if (oi
->type
== OSPF_IFTYPE_BROADCAST
)
283 /* If this router is not DR,
284 and If this router not fully adjacent with DR,
285 this interface is not transit yet: ignore. */
286 if (oi
->state
!= OSPF6_INTERFACE_DR
)
288 drouter
= ospf6_neighbor_lookup (oi
->drouter
, oi
);
289 if (drouter
== NULL
|| drouter
->state
!= OSPF6_NEIGHBOR_FULL
)
293 lsdesc
->type
= OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK
;
294 lsdesc
->metric
= htons (oi
->cost
);
295 lsdesc
->interface_id
= htonl (oi
->interface
->ifindex
);
296 if (oi
->state
!= OSPF6_INTERFACE_DR
)
298 lsdesc
->neighbor_interface_id
= htonl (drouter
->ifindex
);
299 lsdesc
->neighbor_router_id
= drouter
->router_id
;
303 lsdesc
->neighbor_interface_id
= htonl (oi
->interface
->ifindex
);
304 lsdesc
->neighbor_router_id
= oi
->area
->ospf6
->router_id
;
311 assert (0); /* Unknown interface type */
316 /* Point-to-Multipoint interfaces */
320 /* Fill LSA Header */
322 lsa_header
->type
= htons (OSPF6_LSTYPE_ROUTER
);
323 lsa_header
->id
= htonl (link_state_id
);
324 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
326 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
327 lsa_header
->adv_router
, oa
->lsdb
);
328 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
331 ospf6_lsa_checksum (lsa_header
);
334 lsa
= ospf6_lsa_create (lsa_header
);
337 ospf6_lsa_originate_area (lsa
, oa
);
341 /* Do premature-aging of rest, undesired Router-LSAs */
342 type
= ntohs (OSPF6_LSTYPE_ROUTER
);
343 router
= oa
->ospf6
->router_id
;
345 for (lsa
= ospf6_lsdb_type_router_head (type
, router
, oa
->lsdb
); lsa
;
346 lsa
= ospf6_lsdb_type_router_next (type
, router
, lsa
))
348 if (ntohl (lsa
->header
->id
) < link_state_id
)
350 ospf6_lsa_purge (lsa
);
355 * Waiting till the LSA is actually removed from the database to trigger
356 * SPF delays network convergence. Unlike IPv4, for an ABR, when all
357 * interfaces associated with an area are gone, triggering an SPF right away
358 * helps convergence with inter-area routes.
360 if (count
&& !link_state_id
)
361 ospf6_spf_schedule (oa
->ospf6
, OSPF6_SPF_FLAGS_ROUTER_LSA_ORIGINATED
);
366 /*******************************/
367 /* RFC2740 3.4.3.2 Network-LSA */
368 /*******************************/
371 ospf6_network_lsa_get_ar_id (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
374 char *start
, *end
, *current
;
375 struct ospf6_network_lsa
*network_lsa
;
376 struct ospf6_network_lsdesc
*lsdesc
;
380 network_lsa
= (struct ospf6_network_lsa
*)
381 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
383 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
384 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
385 current
= start
+ pos
*(sizeof (struct ospf6_network_lsdesc
));
387 if ((current
+ sizeof(struct ospf6_network_lsdesc
)) <= end
)
389 lsdesc
= (struct ospf6_network_lsdesc
*)current
;
391 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, buflen
);
401 ospf6_network_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
403 char *start
, *end
, *current
;
404 struct ospf6_network_lsa
*network_lsa
;
405 struct ospf6_network_lsdesc
*lsdesc
;
406 char buf
[128], options
[32];
408 network_lsa
= (struct ospf6_network_lsa
*)
409 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
411 ospf6_options_printbuf (network_lsa
->options
, options
, sizeof (options
));
412 vty_out (vty
, " Options: %s%s", options
, VNL
);
414 start
= (char *) network_lsa
+ sizeof (struct ospf6_network_lsa
);
415 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
416 for (current
= start
; current
+ sizeof (struct ospf6_network_lsdesc
) <= end
;
417 current
+= sizeof (struct ospf6_network_lsdesc
))
419 lsdesc
= (struct ospf6_network_lsdesc
*) current
;
420 inet_ntop (AF_INET
, &lsdesc
->router_id
, buf
, sizeof (buf
));
421 vty_out (vty
, " Attached Router: %s%s", buf
, VNL
);
427 ospf6_network_lsa_originate (struct thread
*thread
)
429 struct ospf6_interface
*oi
;
431 char buffer
[OSPF6_MAX_LSASIZE
];
432 struct ospf6_lsa_header
*lsa_header
;
435 struct ospf6_lsa
*old
, *lsa
;
436 struct ospf6_network_lsa
*network_lsa
;
437 struct ospf6_network_lsdesc
*lsdesc
;
438 struct ospf6_neighbor
*on
;
439 struct ospf6_link_lsa
*link_lsa
;
443 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
444 oi
->thread_network_lsa
= NULL
;
446 /* The interface must be enabled until here. A Network-LSA of a
447 disabled interface (but was once enabled) should be flushed
448 by ospf6_lsa_refresh (), and does not come here. */
451 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK
),
452 htonl (oi
->interface
->ifindex
),
453 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
455 /* Do not originate Network-LSA if not DR */
456 if (oi
->state
!= OSPF6_INTERFACE_DR
)
460 ospf6_lsa_purge (old
);
462 * Waiting till the LSA is actually removed from the database to
463 * trigger SPF delays network convergence.
465 ospf6_spf_schedule (oi
->area
->ospf6
,
466 OSPF6_SPF_FLAGS_NETWORK_LSA_ORIGINATED
);
471 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
472 zlog_debug ("Originate Network-LSA for Interface %s", oi
->interface
->name
);
474 /* If none of neighbor is adjacent to us */
477 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
478 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
483 if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK
))
484 zlog_debug ("Interface stub, ignore");
486 ospf6_lsa_purge (old
);
491 memset (buffer
, 0, sizeof (buffer
));
492 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
493 network_lsa
= (struct ospf6_network_lsa
*)
494 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
496 /* Collect the interface's Link-LSAs to describe
497 network's optional capabilities */
498 type
= htons (OSPF6_LSTYPE_LINK
);
499 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
500 lsa
= ospf6_lsdb_type_next (type
, lsa
))
502 link_lsa
= (struct ospf6_link_lsa
*)
503 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
504 network_lsa
->options
[0] |= link_lsa
->options
[0];
505 network_lsa
->options
[1] |= link_lsa
->options
[1];
506 network_lsa
->options
[2] |= link_lsa
->options
[2];
509 lsdesc
= (struct ospf6_network_lsdesc
*)
510 ((caddr_t
) network_lsa
+ sizeof (struct ospf6_network_lsa
));
512 /* set Link Description to the router itself */
513 lsdesc
->router_id
= oi
->area
->ospf6
->router_id
;
516 /* Walk through the neighbors */
517 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
519 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
522 /* set this neighbor's Router-ID to LSA */
523 lsdesc
->router_id
= on
->router_id
;
527 /* Fill LSA Header */
529 lsa_header
->type
= htons (OSPF6_LSTYPE_NETWORK
);
530 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
531 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
533 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
534 lsa_header
->adv_router
, oi
->area
->lsdb
);
535 lsa_header
->length
= htons ((caddr_t
) lsdesc
- (caddr_t
) buffer
);
538 ospf6_lsa_checksum (lsa_header
);
541 lsa
= ospf6_lsa_create (lsa_header
);
544 ospf6_lsa_originate_area (lsa
, oi
->area
);
550 /****************************/
551 /* RFC2740 3.4.3.6 Link-LSA */
552 /****************************/
555 ospf6_link_lsa_get_prefix_str (struct ospf6_lsa
*lsa
, char *buf
, int buflen
,
558 char *start
, *end
, *current
;
559 struct ospf6_link_lsa
*link_lsa
;
561 struct ospf6_prefix
*prefix
;
562 int cnt
= 0, prefixnum
;
566 link_lsa
= (struct ospf6_link_lsa
*)
567 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
570 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, buflen
);
574 prefixnum
= ntohl (link_lsa
->prefix_num
);
578 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
579 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
584 prefix
= (struct ospf6_prefix
*) current
;
585 if (prefix
->prefix_length
== 0 ||
586 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
593 current
= start
+ pos
*OSPF6_PREFIX_SIZE(prefix
);
598 memset (&in6
, 0, sizeof (in6
));
599 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
600 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
601 inet_ntop (AF_INET6
, &in6
, buf
, buflen
);
604 } while (current
<= end
);
610 ospf6_link_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
612 char *start
, *end
, *current
;
613 struct ospf6_link_lsa
*link_lsa
;
615 char buf
[128], options
[32];
616 struct ospf6_prefix
*prefix
;
617 const char *p
, *mc
, *la
, *nu
;
620 link_lsa
= (struct ospf6_link_lsa
*)
621 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
623 ospf6_options_printbuf (link_lsa
->options
, options
, sizeof (options
));
624 inet_ntop (AF_INET6
, &link_lsa
->linklocal_addr
, buf
, sizeof (buf
));
625 prefixnum
= ntohl (link_lsa
->prefix_num
);
627 vty_out (vty
, " Priority: %d Options: %s%s",
628 link_lsa
->priority
, options
, VNL
);
629 vty_out (vty
, " LinkLocal Address: %s%s", buf
, VNL
);
630 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
632 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
633 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
634 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
636 prefix
= (struct ospf6_prefix
*) current
;
637 if (prefix
->prefix_length
== 0 ||
638 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
641 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
643 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
645 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
647 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
649 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
652 memset (&in6
, 0, sizeof (in6
));
653 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
654 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
655 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
656 vty_out (vty
, " Prefix: %s/%d%s",
657 buf
, prefix
->prefix_length
, VNL
);
664 ospf6_link_lsa_originate (struct thread
*thread
)
666 struct ospf6_interface
*oi
;
668 char buffer
[OSPF6_MAX_LSASIZE
];
669 struct ospf6_lsa_header
*lsa_header
;
670 struct ospf6_lsa
*old
, *lsa
;
672 struct ospf6_link_lsa
*link_lsa
;
673 struct ospf6_route
*route
;
674 struct ospf6_prefix
*op
;
676 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
677 oi
->thread_link_lsa
= NULL
;
681 /* find previous LSA */
682 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK
),
683 htonl (oi
->interface
->ifindex
),
684 oi
->area
->ospf6
->router_id
, oi
->lsdb
);
686 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
689 ospf6_lsa_purge (old
);
693 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
694 zlog_debug ("Originate Link-LSA for Interface %s", oi
->interface
->name
);
696 /* can't make Link-LSA if linklocal address not set */
697 if (oi
->linklocal_addr
== NULL
)
699 if (IS_OSPF6_DEBUG_ORIGINATE (LINK
))
700 zlog_debug ("No Linklocal address on %s, defer originating",
701 oi
->interface
->name
);
703 ospf6_lsa_purge (old
);
708 memset (buffer
, 0, sizeof (buffer
));
709 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
710 link_lsa
= (struct ospf6_link_lsa
*)
711 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
714 link_lsa
->priority
= oi
->priority
;
715 memcpy (link_lsa
->options
, oi
->area
->options
, 3);
716 memcpy (&link_lsa
->linklocal_addr
, oi
->linklocal_addr
,
717 sizeof (struct in6_addr
));
718 link_lsa
->prefix_num
= htonl (oi
->route_connected
->count
);
720 op
= (struct ospf6_prefix
*)
721 ((caddr_t
) link_lsa
+ sizeof (struct ospf6_link_lsa
));
723 /* connected prefix to advertise */
724 for (route
= ospf6_route_head (oi
->route_connected
); route
;
725 route
= ospf6_route_next (route
))
727 op
->prefix_length
= route
->prefix
.prefixlen
;
728 op
->prefix_options
= route
->path
.prefix_options
;
729 op
->prefix_metric
= htons (0);
730 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
731 OSPF6_PREFIX_SPACE (op
->prefix_length
));
732 op
= OSPF6_PREFIX_NEXT (op
);
735 /* Fill LSA Header */
737 lsa_header
->type
= htons (OSPF6_LSTYPE_LINK
);
738 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
739 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
741 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
742 lsa_header
->adv_router
, oi
->lsdb
);
743 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) buffer
);
746 ospf6_lsa_checksum (lsa_header
);
749 lsa
= ospf6_lsa_create (lsa_header
);
752 ospf6_lsa_originate_interface (lsa
, oi
);
758 /*****************************************/
759 /* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA */
760 /*****************************************/
762 ospf6_intra_prefix_lsa_get_prefix_str (struct ospf6_lsa
*lsa
, char *buf
,
765 char *start
, *end
, *current
;
766 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
768 int prefixnum
, cnt
= 0;
769 struct ospf6_prefix
*prefix
;
773 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
774 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
776 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
780 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
781 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
786 prefix
= (struct ospf6_prefix
*) current
;
787 if (prefix
->prefix_length
== 0 ||
788 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
795 current
= start
+ pos
*OSPF6_PREFIX_SIZE(prefix
);
800 memset (&in6
, 0, sizeof (in6
));
801 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
802 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
803 inet_ntop (AF_INET6
, &in6
, buf
, buflen
);
804 sprintf(&buf
[strlen(buf
)], "/%d", prefix
->prefix_length
);
807 } while (current
<= end
);
813 ospf6_intra_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
815 char *start
, *end
, *current
;
816 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
819 struct ospf6_prefix
*prefix
;
820 char id
[16], adv_router
[16];
821 const char *p
, *mc
, *la
, *nu
;
824 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
825 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
827 prefixnum
= ntohs (intra_prefix_lsa
->prefix_num
);
829 vty_out (vty
, " Number of Prefix: %d%s", prefixnum
, VNL
);
831 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_id
, id
, sizeof (id
));
832 inet_ntop (AF_INET
, &intra_prefix_lsa
->ref_adv_router
,
833 adv_router
, sizeof (adv_router
));
834 vty_out (vty
, " Reference: %s Id: %s Adv: %s%s",
835 ospf6_lstype_name (intra_prefix_lsa
->ref_type
), id
, adv_router
,
838 start
= (char *) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
);
839 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
840 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (prefix
))
842 prefix
= (struct ospf6_prefix
*) current
;
843 if (prefix
->prefix_length
== 0 ||
844 current
+ OSPF6_PREFIX_SIZE (prefix
) > end
)
847 p
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_P
) ?
849 mc
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_MC
) ?
851 la
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_LA
) ?
853 nu
= (CHECK_FLAG (prefix
->prefix_options
, OSPF6_PREFIX_OPTION_NU
) ?
855 vty_out (vty
, " Prefix Options: %s|%s|%s|%s%s",
858 memset (&in6
, 0, sizeof (in6
));
859 memcpy (&in6
, OSPF6_PREFIX_BODY (prefix
),
860 OSPF6_PREFIX_SPACE (prefix
->prefix_length
));
861 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
862 vty_out (vty
, " Prefix: %s/%d%s",
863 buf
, prefix
->prefix_length
, VNL
);
870 ospf6_intra_prefix_lsa_originate_stub (struct thread
*thread
)
872 struct ospf6_area
*oa
;
874 char buffer
[OSPF6_MAX_LSASIZE
];
875 struct ospf6_lsa_header
*lsa_header
;
876 struct ospf6_lsa
*old
, *lsa
;
878 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
879 struct ospf6_interface
*oi
;
880 struct ospf6_neighbor
*on
;
881 struct ospf6_route
*route
;
882 struct ospf6_prefix
*op
;
883 struct listnode
*i
, *j
;
885 unsigned short prefix_num
= 0;
886 char buf
[PREFIX2STR_BUFFER
];
887 struct ospf6_route_table
*route_advertise
;
889 oa
= (struct ospf6_area
*) THREAD_ARG (thread
);
890 oa
->thread_intra_prefix_lsa
= NULL
;
892 /* find previous LSA */
893 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
894 htonl (0), oa
->ospf6
->router_id
, oa
->lsdb
);
896 if (! IS_AREA_ENABLED (oa
))
899 ospf6_lsa_purge (old
);
903 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
904 zlog_debug ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix",
908 memset (buffer
, 0, sizeof (buffer
));
909 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
910 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
911 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
913 /* Fill Intra-Area-Prefix-LSA */
914 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_ROUTER
);
915 intra_prefix_lsa
->ref_id
= htonl (0);
916 intra_prefix_lsa
->ref_adv_router
= oa
->ospf6
->router_id
;
918 route_advertise
= ospf6_route_table_create (0, 0);
920 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, i
, oi
))
922 if (oi
->state
== OSPF6_INTERFACE_DOWN
)
924 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
925 zlog_debug (" Interface %s is down, ignore", oi
->interface
->name
);
931 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, j
, on
))
932 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
935 if (oi
->state
!= OSPF6_INTERFACE_LOOPBACK
&&
936 oi
->state
!= OSPF6_INTERFACE_POINTTOPOINT
&&
939 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
940 zlog_debug (" Interface %s is not stub, ignore",
941 oi
->interface
->name
);
945 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
946 zlog_debug (" Interface %s:", oi
->interface
->name
);
948 /* connected prefix to advertise */
949 for (route
= ospf6_route_head (oi
->route_connected
); route
;
950 route
= ospf6_route_best_next (route
))
952 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
954 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
955 zlog_debug (" include %s", buf
);
957 ospf6_route_add (ospf6_route_copy (route
), route_advertise
);
961 if (route_advertise
->count
== 0)
964 ospf6_lsa_purge (old
);
965 ospf6_route_table_delete (route_advertise
);
969 /* put prefixes to advertise */
971 op
= (struct ospf6_prefix
*)
972 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
973 for (route
= ospf6_route_head (route_advertise
); route
;
974 route
= ospf6_route_best_next (route
))
976 op
->prefix_length
= route
->prefix
.prefixlen
;
977 op
->prefix_options
= route
->path
.prefix_options
;
978 op
->prefix_metric
= htons (route
->path
.cost
);
979 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
980 OSPF6_PREFIX_SPACE (op
->prefix_length
));
981 op
= OSPF6_PREFIX_NEXT (op
);
985 ospf6_route_table_delete (route_advertise
);
989 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
990 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
994 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
996 /* Fill LSA Header */
998 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
999 lsa_header
->id
= htonl (0);
1000 lsa_header
->adv_router
= oa
->ospf6
->router_id
;
1001 lsa_header
->seqnum
=
1002 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1003 lsa_header
->adv_router
, oa
->lsdb
);
1004 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1007 ospf6_lsa_checksum (lsa_header
);
1010 lsa
= ospf6_lsa_create (lsa_header
);
1013 ospf6_lsa_originate_area (lsa
, oa
);
1020 ospf6_intra_prefix_lsa_originate_transit (struct thread
*thread
)
1022 struct ospf6_interface
*oi
;
1024 char buffer
[OSPF6_MAX_LSASIZE
];
1025 struct ospf6_lsa_header
*lsa_header
;
1026 struct ospf6_lsa
*old
, *lsa
;
1028 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1029 struct ospf6_neighbor
*on
;
1030 struct ospf6_route
*route
;
1031 struct ospf6_prefix
*op
;
1034 unsigned short prefix_num
= 0;
1035 struct ospf6_route_table
*route_advertise
;
1036 struct ospf6_link_lsa
*link_lsa
;
1037 char *start
, *end
, *current
;
1039 char buf
[PREFIX2STR_BUFFER
];
1041 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1042 oi
->thread_intra_prefix_lsa
= NULL
;
1046 /* find previous LSA */
1047 old
= ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX
),
1048 htonl (oi
->interface
->ifindex
),
1049 oi
->area
->ospf6
->router_id
, oi
->area
->lsdb
);
1051 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_DISABLE
))
1054 ospf6_lsa_purge (old
);
1058 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1059 zlog_debug ("Originate Intra-Area-Prefix-LSA for interface %s's prefix",
1060 oi
->interface
->name
);
1062 /* prepare buffer */
1063 memset (buffer
, 0, sizeof (buffer
));
1064 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
1065 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1066 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
1068 /* Fill Intra-Area-Prefix-LSA */
1069 intra_prefix_lsa
->ref_type
= htons (OSPF6_LSTYPE_NETWORK
);
1070 intra_prefix_lsa
->ref_id
= htonl (oi
->interface
->ifindex
);
1071 intra_prefix_lsa
->ref_adv_router
= oi
->area
->ospf6
->router_id
;
1073 if (oi
->state
!= OSPF6_INTERFACE_DR
)
1075 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1076 zlog_debug (" Interface is not DR");
1078 ospf6_lsa_purge (old
);
1083 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, i
, on
))
1084 if (on
->state
== OSPF6_NEIGHBOR_FULL
)
1087 if (full_count
== 0)
1089 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1090 zlog_debug (" Interface is stub");
1092 ospf6_lsa_purge (old
);
1096 /* connected prefix to advertise */
1097 route_advertise
= ospf6_route_table_create (0, 0);
1099 type
= ntohs (OSPF6_LSTYPE_LINK
);
1100 for (lsa
= ospf6_lsdb_type_head (type
, oi
->lsdb
); lsa
;
1101 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1103 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1106 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1107 zlog_debug (" include prefix from %s", lsa
->name
);
1109 if (lsa
->header
->adv_router
!= oi
->area
->ospf6
->router_id
)
1111 on
= ospf6_neighbor_lookup (lsa
->header
->adv_router
, oi
);
1112 if (on
== NULL
|| on
->state
!= OSPF6_NEIGHBOR_FULL
)
1114 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1115 zlog_debug (" Neighbor not found or not Full, ignore");
1120 link_lsa
= (struct ospf6_link_lsa
*)
1121 ((caddr_t
) lsa
->header
+ sizeof (struct ospf6_lsa_header
));
1123 prefix_num
= (unsigned short) ntohl (link_lsa
->prefix_num
);
1124 start
= (char *) link_lsa
+ sizeof (struct ospf6_link_lsa
);
1125 end
= (char *) lsa
->header
+ ntohs (lsa
->header
->length
);
1126 for (current
= start
; current
< end
&& prefix_num
;
1127 current
+= OSPF6_PREFIX_SIZE (op
))
1129 op
= (struct ospf6_prefix
*) current
;
1130 if (op
->prefix_length
== 0 ||
1131 current
+ OSPF6_PREFIX_SIZE (op
) > end
)
1134 route
= ospf6_route_create ();
1136 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1137 route
->prefix
.family
= AF_INET6
;
1138 route
->prefix
.prefixlen
= op
->prefix_length
;
1139 memset (&route
->prefix
.u
.prefix6
, 0, sizeof (struct in6_addr
));
1140 memcpy (&route
->prefix
.u
.prefix6
, OSPF6_PREFIX_BODY (op
),
1141 OSPF6_PREFIX_SPACE (op
->prefix_length
));
1143 route
->path
.origin
.type
= lsa
->header
->type
;
1144 route
->path
.origin
.id
= lsa
->header
->id
;
1145 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1146 route
->path
.options
[0] = link_lsa
->options
[0];
1147 route
->path
.options
[1] = link_lsa
->options
[1];
1148 route
->path
.options
[2] = link_lsa
->options
[2];
1149 route
->path
.prefix_options
= op
->prefix_options
;
1150 route
->path
.area_id
= oi
->area
->area_id
;
1151 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1153 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1155 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1156 zlog_debug (" include %s", buf
);
1159 ospf6_route_add (route
, route_advertise
);
1162 if (current
!= end
&& IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1163 zlog_debug ("Trailing garbage in %s", lsa
->name
);
1166 op
= (struct ospf6_prefix
*)
1167 ((caddr_t
) intra_prefix_lsa
+ sizeof (struct ospf6_intra_prefix_lsa
));
1170 for (route
= ospf6_route_head (route_advertise
); route
;
1171 route
= ospf6_route_best_next (route
))
1173 op
->prefix_length
= route
->prefix
.prefixlen
;
1174 op
->prefix_options
= route
->path
.prefix_options
;
1175 op
->prefix_metric
= htons (0);
1176 memcpy (OSPF6_PREFIX_BODY (op
), &route
->prefix
.u
.prefix6
,
1177 OSPF6_PREFIX_SPACE (op
->prefix_length
));
1178 op
= OSPF6_PREFIX_NEXT (op
);
1182 ospf6_route_table_delete (route_advertise
);
1184 if (prefix_num
== 0)
1186 if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX
))
1187 zlog_debug ("Quit to Advertise Intra-Prefix: no route to advertise");
1191 intra_prefix_lsa
->prefix_num
= htons (prefix_num
);
1193 /* Fill LSA Header */
1194 lsa_header
->age
= 0;
1195 lsa_header
->type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1196 lsa_header
->id
= htonl (oi
->interface
->ifindex
);
1197 lsa_header
->adv_router
= oi
->area
->ospf6
->router_id
;
1198 lsa_header
->seqnum
=
1199 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
1200 lsa_header
->adv_router
, oi
->area
->lsdb
);
1201 lsa_header
->length
= htons ((caddr_t
) op
- (caddr_t
) lsa_header
);
1204 ospf6_lsa_checksum (lsa_header
);
1207 lsa
= ospf6_lsa_create (lsa_header
);
1210 ospf6_lsa_originate_area (lsa
, oi
->area
);
1216 ospf6_intra_prefix_lsa_add (struct ospf6_lsa
*lsa
)
1218 struct ospf6_area
*oa
;
1219 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1220 struct prefix ls_prefix
;
1221 struct ospf6_route
*route
, *ls_entry
;
1223 struct ospf6_prefix
*op
;
1224 char *start
, *current
, *end
;
1225 char buf
[PREFIX2STR_BUFFER
];
1226 struct interface
*ifp
;
1227 int direct_connect
= 0;
1229 if (OSPF6_LSA_IS_MAXAGE (lsa
))
1232 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1233 zlog_debug ("%s found", lsa
->name
);
1235 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1237 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1238 OSPF6_LSA_HEADER_END (lsa
->header
);
1239 if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_ROUTER
))
1240 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1241 htonl (0), &ls_prefix
);
1242 else if (intra_prefix_lsa
->ref_type
== htons (OSPF6_LSTYPE_NETWORK
))
1243 ospf6_linkstate_prefix (intra_prefix_lsa
->ref_adv_router
,
1244 intra_prefix_lsa
->ref_id
, &ls_prefix
);
1247 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1248 zlog_debug ("Unknown reference LS-type: %#hx",
1249 ntohs (intra_prefix_lsa
->ref_type
));
1253 ls_entry
= ospf6_route_lookup (&ls_prefix
, oa
->spf_table
);
1254 if (ls_entry
== NULL
)
1256 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1258 ospf6_linkstate_prefix2str (&ls_prefix
, buf
, sizeof (buf
));
1259 zlog_debug ("LS entry does not exist: %s", buf
);
1264 if (intra_prefix_lsa
->ref_adv_router
== oa
->ospf6
->router_id
)
1266 /* the intra-prefix are directly connected */
1270 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1271 start
= (caddr_t
) intra_prefix_lsa
+
1272 sizeof (struct ospf6_intra_prefix_lsa
);
1273 end
= OSPF6_LSA_END (lsa
->header
);
1274 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1276 op
= (struct ospf6_prefix
*) current
;
1277 if (prefix_num
== 0)
1279 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1282 /* Appendix A.4.1.1 */
1283 if (CHECK_FLAG(op
->prefix_options
, OSPF6_PREFIX_OPTION_NU
))
1285 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1287 ospf6_linkstate_prefix2str ((struct prefix
*)OSPF6_PREFIX_BODY(op
),
1289 zlog_debug ("%s: Skipping Prefix %s has NU option set",
1295 route
= ospf6_route_create ();
1297 memset (&route
->prefix
, 0, sizeof (struct prefix
));
1298 route
->prefix
.family
= AF_INET6
;
1299 route
->prefix
.prefixlen
= op
->prefix_length
;
1300 ospf6_prefix_in6_addr (&route
->prefix
.u
.prefix6
, op
);
1302 route
->type
= OSPF6_DEST_TYPE_NETWORK
;
1303 route
->path
.origin
.type
= lsa
->header
->type
;
1304 route
->path
.origin
.id
= lsa
->header
->id
;
1305 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
1306 route
->path
.prefix_options
= op
->prefix_options
;
1307 route
->path
.area_id
= oa
->area_id
;
1308 route
->path
.type
= OSPF6_PATH_TYPE_INTRA
;
1309 route
->path
.metric_type
= 1;
1310 route
->path
.cost
= ls_entry
->path
.cost
+
1311 ntohs (op
->prefix_metric
);
1315 ifp
= if_lookup_prefix(&route
->prefix
, VRF_DEFAULT
);
1317 ospf6_route_add_nexthop (route
, ifp
->ifindex
, NULL
);
1321 ospf6_route_copy_nexthops (route
, ls_entry
);
1324 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1326 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1327 zlog_debug (" add %s", buf
);
1330 ospf6_route_add (route
, oa
->route_table
);
1334 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1335 zlog_debug ("Trailing garbage ignored");
1339 ospf6_intra_prefix_lsa_remove (struct ospf6_lsa
*lsa
)
1341 struct ospf6_area
*oa
;
1342 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1343 struct prefix prefix
;
1344 struct ospf6_route
*route
, *nroute
;
1346 struct ospf6_prefix
*op
;
1347 char *start
, *current
, *end
;
1348 char buf
[PREFIX2STR_BUFFER
];
1350 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1351 zlog_debug ("%s disappearing", lsa
->name
);
1353 oa
= OSPF6_AREA (lsa
->lsdb
->data
);
1355 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*)
1356 OSPF6_LSA_HEADER_END (lsa
->header
);
1358 prefix_num
= ntohs (intra_prefix_lsa
->prefix_num
);
1359 start
= (caddr_t
) intra_prefix_lsa
+
1360 sizeof (struct ospf6_intra_prefix_lsa
);
1361 end
= OSPF6_LSA_END (lsa
->header
);
1362 for (current
= start
; current
< end
; current
+= OSPF6_PREFIX_SIZE (op
))
1364 op
= (struct ospf6_prefix
*) current
;
1365 if (prefix_num
== 0)
1367 if (end
< current
+ OSPF6_PREFIX_SIZE (op
))
1371 memset (&prefix
, 0, sizeof (struct prefix
));
1372 prefix
.family
= AF_INET6
;
1373 prefix
.prefixlen
= op
->prefix_length
;
1374 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, op
);
1376 route
= ospf6_route_lookup (&prefix
, oa
->route_table
);
1380 for (ospf6_route_lock (route
);
1381 route
&& ospf6_route_is_prefix (&prefix
, route
);
1384 nroute
= ospf6_route_next (route
);
1385 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
)
1387 if (route
->path
.area_id
!= oa
->area_id
)
1389 if (route
->path
.type
!= OSPF6_PATH_TYPE_INTRA
)
1391 if (route
->path
.origin
.type
!= lsa
->header
->type
||
1392 route
->path
.origin
.id
!= lsa
->header
->id
||
1393 route
->path
.origin
.adv_router
!= lsa
->header
->adv_router
)
1396 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1398 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
1399 zlog_debug ("remove %s", buf
);
1401 ospf6_route_remove (route
, oa
->route_table
);
1404 ospf6_route_unlock (route
);
1407 if (current
!= end
&& IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1408 zlog_debug ("Trailing garbage ignored");
1412 ospf6_intra_route_calculation (struct ospf6_area
*oa
)
1414 struct ospf6_route
*route
, *nroute
;
1416 struct ospf6_lsa
*lsa
;
1417 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1418 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1420 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1421 zlog_debug ("Re-examin intra-routes for area %s", oa
->name
);
1423 hook_add
= oa
->route_table
->hook_add
;
1424 hook_remove
= oa
->route_table
->hook_remove
;
1425 oa
->route_table
->hook_add
= NULL
;
1426 oa
->route_table
->hook_remove
= NULL
;
1428 for (route
= ospf6_route_head (oa
->route_table
); route
;
1429 route
= ospf6_route_next (route
))
1430 route
->flag
= OSPF6_ROUTE_REMOVE
;
1432 type
= htons (OSPF6_LSTYPE_INTRA_PREFIX
);
1433 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
1434 lsa
= ospf6_lsdb_type_next (type
, lsa
))
1435 ospf6_intra_prefix_lsa_add (lsa
);
1437 oa
->route_table
->hook_add
= hook_add
;
1438 oa
->route_table
->hook_remove
= hook_remove
;
1440 for (route
= ospf6_route_head (oa
->route_table
); route
;
1443 nroute
= ospf6_route_next (route
);
1444 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
) &&
1445 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
))
1447 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
);
1448 UNSET_FLAG (route
->flag
, OSPF6_ROUTE_ADD
);
1451 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
1452 ospf6_route_remove (route
, oa
->route_table
);
1453 else if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ADD
) ||
1454 CHECK_FLAG (route
->flag
, OSPF6_ROUTE_CHANGE
))
1457 (*hook_add
) (route
);
1462 /* Redo the summaries as things might have changed */
1463 ospf6_abr_originate_summary (route
);
1468 if (IS_OSPF6_DEBUG_EXAMIN (INTRA_PREFIX
))
1469 zlog_debug ("Re-examin intra-routes for area %s: Done", oa
->name
);
1473 ospf6_brouter_debug_print (struct ospf6_route
*brouter
)
1475 u_int32_t brouter_id
;
1476 char brouter_name
[16];
1478 char destination
[64];
1479 char installed
[16], changed
[16];
1480 struct timeval now
, res
;
1481 char id
[16], adv_router
[16];
1482 char capa
[16], options
[16];
1484 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1485 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1486 inet_ntop (AF_INET
, &brouter
->path
.area_id
, area_name
, sizeof (area_name
));
1487 ospf6_linkstate_prefix2str (&brouter
->prefix
, destination
,
1488 sizeof (destination
));
1491 timersub (&now
, &brouter
->installed
, &res
);
1492 timerstring (&res
, installed
, sizeof (installed
));
1495 timersub (&now
, &brouter
->changed
, &res
);
1496 timerstring (&res
, changed
, sizeof (changed
));
1498 inet_ntop (AF_INET
, &brouter
->path
.origin
.id
, id
, sizeof (id
));
1499 inet_ntop (AF_INET
, &brouter
->path
.origin
.adv_router
, adv_router
,
1500 sizeof (adv_router
));
1502 ospf6_options_printbuf (brouter
->path
.options
, options
, sizeof (options
));
1503 ospf6_capability_printbuf (brouter
->path
.router_bits
, capa
, sizeof (capa
));
1505 zlog_info ("Brouter: %s via area %s", brouter_name
, area_name
);
1506 zlog_info (" memory: prev: %p this: %p next: %p parent rnode: %p",
1507 (void *)brouter
->prev
, (void *)brouter
, (void *)brouter
->next
,
1508 (void *)brouter
->rnode
);
1509 zlog_info (" type: %d prefix: %s installed: %s changed: %s",
1510 brouter
->type
, destination
, installed
, changed
);
1511 zlog_info (" lock: %d flags: %s%s%s%s", brouter
->lock
,
1512 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_BEST
) ? "B" : "-"),
1513 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ? "A" : "-"),
1514 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) ? "R" : "-"),
1515 (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
) ? "C" : "-"));
1516 zlog_info (" path type: %s ls-origin %s id: %s adv-router %s",
1517 OSPF6_PATH_TYPE_NAME (brouter
->path
.type
),
1518 ospf6_lstype_name (brouter
->path
.origin
.type
),
1520 zlog_info (" options: %s router-bits: %s metric-type: %d metric: %d/%d",
1521 options
, capa
, brouter
->path
.metric_type
,
1522 brouter
->path
.cost
, brouter
->path
.u
.cost_e2
);
1526 ospf6_intra_brouter_calculation (struct ospf6_area
*oa
)
1528 struct ospf6_route
*brouter
, *nbrouter
, *copy
;
1529 void (*hook_add
) (struct ospf6_route
*) = NULL
;
1530 void (*hook_remove
) (struct ospf6_route
*) = NULL
;
1531 u_int32_t brouter_id
;
1532 char brouter_name
[16];
1534 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1535 zlog_info ("border-router calculation for area %s", oa
->name
);
1537 hook_add
= oa
->ospf6
->brouter_table
->hook_add
;
1538 hook_remove
= oa
->ospf6
->brouter_table
->hook_remove
;
1539 oa
->ospf6
->brouter_table
->hook_add
= NULL
;
1540 oa
->ospf6
->brouter_table
->hook_remove
= NULL
;
1542 /* withdraw the previous router entries for the area */
1543 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1544 brouter
= ospf6_route_next (brouter
))
1546 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1547 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1548 if (brouter
->path
.area_id
!= oa
->area_id
)
1550 SET_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1552 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1553 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1555 zlog_info ("%p: mark as removing: area %s brouter %s",
1556 (void *)brouter
, oa
->name
, brouter_name
);
1557 ospf6_brouter_debug_print (brouter
);
1561 for (brouter
= ospf6_route_head (oa
->spf_table
); brouter
;
1562 brouter
= ospf6_route_next (brouter
))
1564 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1565 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1567 if (brouter
->type
!= OSPF6_DEST_TYPE_LINKSTATE
)
1569 if (ospf6_linkstate_prefix_id (&brouter
->prefix
) != htonl (0))
1571 if (! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_E
) &&
1572 ! CHECK_FLAG (brouter
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
1575 if (! OSPF6_OPT_ISSET (brouter
->path
.options
, OSPF6_OPT_V6
) ||
1576 ! OSPF6_OPT_ISSET (brouter
->path
.options
, OSPF6_OPT_R
))
1579 copy
= ospf6_route_copy (brouter
);
1580 copy
->type
= OSPF6_DEST_TYPE_ROUTER
;
1581 copy
->path
.area_id
= oa
->area_id
;
1582 ospf6_route_add (copy
, oa
->ospf6
->brouter_table
);
1584 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1585 IS_OSPF6_DEBUG_ROUTE (MEMORY
))
1587 zlog_info ("%p: transfer: area %s brouter %s",
1588 (void *)brouter
, oa
->name
, brouter_name
);
1589 ospf6_brouter_debug_print (brouter
);
1593 oa
->ospf6
->brouter_table
->hook_add
= hook_add
;
1594 oa
->ospf6
->brouter_table
->hook_remove
= hook_remove
;
1596 for (brouter
= ospf6_route_head (oa
->ospf6
->brouter_table
); brouter
;
1599 nbrouter
= ospf6_route_next (brouter
);
1600 brouter_id
= ADV_ROUTER_IN_PREFIX (&brouter
->prefix
);
1601 inet_ntop (AF_INET
, &brouter_id
, brouter_name
, sizeof (brouter_name
));
1603 if (brouter
->path
.area_id
!= oa
->area_id
)
1606 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
1609 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
) &&
1610 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
))
1612 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
);
1613 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
);
1616 if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_REMOVE
))
1618 if (IS_OSPF6_DEBUG_BROUTER
||
1619 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1620 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1621 zlog_info ("brouter %s disappears via area %s",
1622 brouter_name
, oa
->name
);
1623 ospf6_route_remove (brouter
, oa
->ospf6
->brouter_table
);
1625 else if (CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
) ||
1626 CHECK_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
))
1628 if (IS_OSPF6_DEBUG_BROUTER
||
1629 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1630 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1631 zlog_info ("brouter %s appears via area %s",
1632 brouter_name
, oa
->name
);
1636 (*hook_add
) (brouter
);
1640 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID (brouter_id
) ||
1641 IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1642 zlog_info ("brouter %s still exists via area %s",
1643 brouter_name
, oa
->name
);
1644 /* But re-originate summaries */
1645 ospf6_abr_originate_summary (brouter
);
1647 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_ADD
);
1648 UNSET_FLAG (brouter
->flag
, OSPF6_ROUTE_CHANGE
);
1651 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa
->area_id
))
1652 zlog_info ("border-router calculation for area %s: done", oa
->name
);
1655 struct ospf6_lsa_handler router_handler
=
1657 OSPF6_LSTYPE_ROUTER
,
1660 ospf6_router_lsa_show
,
1661 ospf6_router_lsa_get_nbr_id
1664 struct ospf6_lsa_handler network_handler
=
1666 OSPF6_LSTYPE_NETWORK
,
1669 ospf6_network_lsa_show
,
1670 ospf6_network_lsa_get_ar_id
1673 struct ospf6_lsa_handler link_handler
=
1678 ospf6_link_lsa_show
,
1679 ospf6_link_lsa_get_prefix_str
1682 struct ospf6_lsa_handler intra_prefix_handler
=
1684 OSPF6_LSTYPE_INTRA_PREFIX
,
1687 ospf6_intra_prefix_lsa_show
,
1688 ospf6_intra_prefix_lsa_get_prefix_str
1692 ospf6_intra_init (void)
1694 ospf6_install_lsa_handler (&router_handler
);
1695 ospf6_install_lsa_handler (&network_handler
);
1696 ospf6_install_lsa_handler (&link_handler
);
1697 ospf6_install_lsa_handler (&intra_prefix_handler
);
1700 DEFUN (debug_ospf6_brouter
,
1701 debug_ospf6_brouter_cmd
,
1702 "debug ospf6 border-routers",
1705 "Debug border router\n"
1708 OSPF6_DEBUG_BROUTER_ON ();
1712 DEFUN (no_debug_ospf6_brouter
,
1713 no_debug_ospf6_brouter_cmd
,
1714 "no debug ospf6 border-routers",
1718 "Debug border router\n"
1721 OSPF6_DEBUG_BROUTER_OFF ();
1725 DEFUN (debug_ospf6_brouter_router
,
1726 debug_ospf6_brouter_router_cmd
,
1727 "debug ospf6 border-routers router-id A.B.C.D",
1730 "Debug border router\n"
1731 "Debug specific border router\n"
1732 "Specify border-router's router-id\n"
1736 u_int32_t router_id
;
1737 inet_pton (AF_INET
, argv
[idx_ipv4
]->arg
, &router_id
);
1738 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ON (router_id
);
1742 DEFUN (no_debug_ospf6_brouter_router
,
1743 no_debug_ospf6_brouter_router_cmd
,
1744 "no debug ospf6 border-routers router-id",
1748 "Debug border router\n"
1749 "Debug specific border router\n"
1752 OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF ();
1756 DEFUN (debug_ospf6_brouter_area
,
1757 debug_ospf6_brouter_area_cmd
,
1758 "debug ospf6 border-routers area-id A.B.C.D",
1761 "Debug border router\n"
1762 "Debug border routers in specific Area\n"
1768 inet_pton (AF_INET
, argv
[idx_ipv4
]->arg
, &area_id
);
1769 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ON (area_id
);
1773 DEFUN (no_debug_ospf6_brouter_area
,
1774 no_debug_ospf6_brouter_area_cmd
,
1775 "no debug ospf6 border-routers area-id",
1779 "Debug border router\n"
1780 "Debug border routers in specific Area\n"
1783 OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF ();
1788 config_write_ospf6_debug_brouter (struct vty
*vty
)
1791 if (IS_OSPF6_DEBUG_BROUTER
)
1792 vty_out (vty
, "debug ospf6 border-routers%s", VNL
);
1793 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER
)
1795 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_router_id
,
1797 vty_out (vty
, "debug ospf6 border-routers router-id %s%s", buf
, VNL
);
1799 if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA
)
1801 inet_ntop (AF_INET
, &conf_debug_ospf6_brouter_specific_area_id
,
1803 vty_out (vty
, "debug ospf6 border-routers area-id %s%s", buf
, VNL
);
1809 install_element_ospf6_debug_brouter (void)
1811 install_element (ENABLE_NODE
, &debug_ospf6_brouter_cmd
);
1812 install_element (ENABLE_NODE
, &debug_ospf6_brouter_router_cmd
);
1813 install_element (ENABLE_NODE
, &debug_ospf6_brouter_area_cmd
);
1814 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_cmd
);
1815 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1816 install_element (ENABLE_NODE
, &no_debug_ospf6_brouter_area_cmd
);
1817 install_element (CONFIG_NODE
, &debug_ospf6_brouter_cmd
);
1818 install_element (CONFIG_NODE
, &debug_ospf6_brouter_router_cmd
);
1819 install_element (CONFIG_NODE
, &debug_ospf6_brouter_area_cmd
);
1820 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_cmd
);
1821 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_router_cmd
);
1822 install_element (CONFIG_NODE
, &no_debug_ospf6_brouter_area_cmd
);